DataService SendingRequest2添加Authorization头本地正常测试服更新失败
问题原因排查方向
- 第一是WCF Data Services 对应.NET Framework 4.5.2的版本存在已知兼容性问题:更新操作默认使用MERGE/PATCH谓词,当
SaveChanges使用默认的请求合并逻辑时,部分修改请求不会触发SendingRequest2事件。本地IIS Express和服务器完整IIS的HTTP管道处理逻辑存在差异,导致本地未暴露问题,服务器环境触发了该缺陷。 - 第二是上下文实例绑定逻辑疏漏:如果更新操作使用的DataServiceContext实例是重新初始化的,没有绑定
SendingRequest2事件,就会出现头缺失的情况。本地调试时可能因为作用域缓存、调试断点干扰等原因复用了绑定过事件的上下文,服务器运行时作用域释放更及时,就会触发问题。 - 第三是服务器IIS配置问题:如果服务器配置了HTTP谓词过滤,MERGE/PUT/PATCH类的更新请求被前置模块拦截修改,也会导致请求头被移除或者事件触发逻辑中断。
替代实现方案
方案1:替换为兼容性更好的BuildingRequest事件
BuildingRequest事件触发时机早于SendingRequest2,对所有请求类型的覆盖更完整,代码改动最小:
context.BuildingRequest += (s, e) => { if(!e.Headers.ContainsKey("Authorization")) { e.Headers.Add("Authorization", $"{applicationName} {applicationId}"); } };
如果要保险可以同时保留SendingRequest2的绑定逻辑,做双重保障。
方案2:统一上下文实例创建逻辑
封装上下文工厂,确保所有场景下拿到的上下文实例都已经绑定了请求头添加逻辑,避免漏绑:
public static class MyDataContextFactory { // 替换为你实际的上下文类型、服务地址 public static MyDataServiceContext GetContext() { var context = new MyDataServiceContext(new Uri("你的DataService地址")); // 统一绑定两个事件 context.BuildingRequest += (s, e) => { if(!e.Headers.ContainsKey("Authorization")) { e.Headers.Add("Authorization", $"{applicationName} {applicationId}"); } }; context.SendingRequest2 += (s, e) => { if(!e.RequestMessage.GetHeader("Authorization").Any()) { e.RequestMessage.SetHeader("Authorization", $"{applicationName} {applicationId}"); } }; return context; } }
所有业务逻辑调用都通过该工厂获取上下文,不要单独new上下文实例。
临时修复方案
如果暂时定位不到原因,可以在调用更新的SaveChanges时指定SaveChangesOptions.None参数,禁用请求合并逻辑,大部分场景下可以解决事件漏触发的问题:
context.SaveChanges(SaveChangesOptions.None);
内容的提问来源于stack exchange,提问作者user15622687
相关产品推荐
相关产品推荐

