c# - C# .NET Core 3.1 OData:从 https 到 http 的意外更改 URI
问题描述
我正在使用带有 C# .NET Core 3.1 客户端的 SAP 的 OData 服务,并使用 GET 获取数据并尝试使用 PUT 发送更新。使用的 OData 版本相当旧(2.0),无法更新!
服务类(引用)是使用Microsoft.Data.OData
v5.8.4 作为“连接服务”从$metadata.xml
.
在服务首次使用 PATCH 而不是 PUT 后,我可以使用 调整行为SaveChangesOptions.ReplaceOnUpdate
,但现在BuildingRequest
事件中出现了一个奇怪的行为。
尽管该协议https
在 中使用(DataServiceContext)sender.BaseUri
,但在每个上BuildingRequestEventArgs.RequestUri
都说,并且失败并出现错误http
PUT
PUT
请求超时
因为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
有人见过这种行为吗?
我不喜欢这种解决方法,希望能解释一下这种行为以及如何解决这个问题。
提前致谢
解决方案
推荐阅读
- python - 如何防止标签编码器将 y 列添加到 X numpy.array
- python - 如何仅在调用 django python 时在后台运行函数?
- azure-devops - 如何使用在组织级别安装的扩展找到 Azure DevOps 项目
- c# - 如果存在 UseIdentityServer,是否需要 AddAuthentication 和 AddAuthorization?
- html - 使用“flex:shrink”无法正确调整图像大小
- magento - Magento 2系统产品导出重复一些记录
- algorithm - 对哈希表中搜索的预期时间限制的解释
- r - 如何使用 `cplexAPI` 求解具有二次约束的二次程序/线性程序?
- database - 在 Postgres 中合并 4 个表
- node.js - 如何在 docker 容器内的微服务架构中配置 API 网关