.NET Core 3.1 OData调用SAP服务PUT请求URI从HTTPS变为HTTP问题
问题原因
- 核心诱因是SAP OData服务返回的资源链接本身为HTTP协议:老版本SAP NetWeaver网关的ICM(Internet Communication Manager)如果没有配置对外暴露的HTTPS协议前缀,或是服务前端部署的反向代理未正确透传协议标识头,SAP服务会默认使用内部配置的HTTP协议生成所有返回的资源链接,包括实体编辑链接(edit link)、服务文档地址、元数据中的实体集路径。
- OData客户端的更新逻辑优先级:你使用的Microsoft.Data.OData v5.x生成的客户端,执行PUT/DELETE等更新操作时,默认优先使用查询实体时服务返回的edit link作为请求地址,而非初始化DataServiceContext时传入的BaseUri,因此哪怕BaseUri为HTTPS,更新请求还是会走服务返回的HTTP地址。
- 该问题确实和
$metadata.xml相关:你可以直接检查生成服务用的$metadata.xml,或是访问OData服务根地址获取服务文档,若其中的href属性均为HTTP开头,即可确认是服务端返回的链接本身协议错误。
修复方案
优先选择服务端修复,无权限修改服务端配置的话可使用客户端正规方案,不需要在BuildingRequest事件中临时硬编码替换Uri。
方案1:服务端修复(最优,无后续兼容问题)
联系SAP运维人员调整网关配置:
- 进入事务码SICF,找到对应的OData服务节点,将其对外暴露的协议前缀设置为HTTPS
- 若SAP前端部署了反向代理/负载均衡,确保代理层将
X-Forwarded-Proto: https头透传给SAP服务,SAP收到该头后会自动用HTTPS生成所有返回的资源链接。
方案2:客户端修复(无需修改服务端配置)
方式A:读取实体时修正编辑链接
在初始化SRV_Entities实例后添加ReadingEntity事件监听,在实体读取阶段就修正编辑链接的协议,后续更新时自动使用正确地址:
srv.ReadingEntity += (sender, e) => { var editLink = e.EntityDescriptor.EditLink; if (editLink != null && editLink.Scheme == "http") { var correctedUri = new UriBuilder(editLink) { Scheme = srv.BaseUri.Scheme, Port = srv.BaseUri.Port }.Uri; e.EntityDescriptor.EditLink = correctedUri; e.EntityDescriptor.SelfLink = correctedUri; } };
该方案符合OData客户端的设计逻辑,比请求构建阶段临时替换地址更稳定。
方式B:统一添加协议标识头
如果SAP服务支持识别X-Forwarded-Proto头,直接在BuildingRequest事件中添加该头即可,不需要修改任何Uri:
e.Headers.Add("X-Forwarded-Proto", "https");
添加后SAP服务返回的所有资源链接都会自动变为HTTPS,从根源解决协议错误问题。
内容的提问来源于stack exchange,提问作者Buckaroo Banzai
相关产品推荐
相关产品推荐

