首页 > 解决方案 > C# .NET Core 3.1 OData:从 https 到 http 的意外更改 URI

问题描述

我正在使用带有 C# .NET Core 3.1 客户端的 SAP 的 OData 服务,并使用 GET 获取数据并尝试使用 PUT 发送更新。使用的 OData 版本相当旧(2.0),无法更新!

服务类(引用)是使用Microsoft.Data.ODatav5.8.4 作为“连接服务”从$metadata.xml.

在服务首次使用 PATCH 而不是 PUT 后,我可以使用 调整行为SaveChangesOptions.ReplaceOnUpdate,但现在BuildingRequest事件中出现了一个奇怪的行为。

尽管该协议https在 中使用(DataServiceContext)sender.BaseUri,但在每个上BuildingRequestEventArgs.RequestUri都说,并且失败并出现错误httpPUTPUT

请求超时

因为http没有在 SAP 服务器上激活。

 :
 private void SRV_Entities_BuildingRequest(object sender, System.Data.Services.Client.BuildingRequestEventArgs e)
    {
        var authHeaderValue = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", Username, Password)));
        //this is where you pass the creds.
        e.Headers.Add("Authorization", "Basic " + authHeaderValue);  
        // If I don't have the CSRFToken...          
        if( String.IsNullOrEmpty(CSRFToken) )
            e.Headers.Add("X-CSRF-TOKEN", "fetch");   // fetch the token
        else
            e.Headers.Add("X-CSRF-TOKEN", CSRFToken); // use the token
        if (!String.IsNullOrEmpty(CookieText))
            e.Headers.Add("Cookie", CookieText);      // and use the yummy cookie
        // token and cookie are set in the response of the fetch request in GetCSRFToken()

        // ############################################
        // This is a workaround!
        if (e.RequestUri.Scheme.Equals("http"))
        {
            logger.LogDebug($"Current wrong Request Uri: {e.RequestUri.ToString()}");
            e.RequestUri = new UriBuilder("https:",e.RequestUri.Host, 443, e.RequestUri.AbsolutePath).Uri;
        }
        // ############################################

        logger.LogDebug($"The Descriptor: {e.Descriptor}");
    }

在之前的 GET(始终为 https)和实体更改后的后续 PUT 之间,Uri 没有改变,DataServiceObject 也没有重新创建。

public void DoIt(string findIt, string newValue)
{
    :
    SRV_Entities srv = new SRV_Entities(new Uri(ServiceRoot));
    srv.Credentials = new NetworkCredential(Username, Password, Domain);
    srv.SaveChangesDefaultOptions = SaveChangesOptions.ReplaceOnUpdate;
    srv.BuildingRequest += SRV_Entities_BuildingRequest;
    :

    GetCSRFToken(); // <-- this is the part in "BuildingRequest"-event with the token stuff

    var dataQuery = (from x in srv.MyDatas where x.what == findIt select x);

    return dataQuery.BeginExecute(handler => {
        IEnumerable<MyData> datas = dataQuery.EndExecute(handler);
        foreach (MyData d in datas)
        {
            d.Value = newValue;
            srv.UpdateObject(d);
        }                            
        srv.BeginSaveChanges(handler => {
            result = handler;
            var state = handler.AsyncState as SRV_Entities;
            var end = state.EndSaveChanges(handler);
        }, srv);
    }, dataQuery);
:
}

使用“BuildingRequest”事件中的“解决方法”,调用按预期工作,至少没有错误,并且与“POSTMAN”作为测试一样。

有没有导致这种效果的设置?是不是
因为 $metadata.xml有人见过这种行为吗?

我不喜欢这种解决方法,希望能解释一下这种行为以及如何解决这个问题。

提前致谢

标签: c#odataput

解决方案


推荐阅读