安装KB4576947/KB4578974后WebForms中HttpContext.Current为空求助
.NET Framework更新KB4576947/KB4578974引发HttpContext.Current为空的问题解析
问题概述
你遇到的情况很典型:安装了2020年9月的.NET Framework预览更新KB4576947,以及10月13日的正式更新KB4578974后,Web Forms应用里的HttpContext.Current突然变成了空值,直接导致代码抛出异常。对比测试后发现,未打补丁的机器用System.Web.dll!System.Web.Hosting.PipelineRuntime初始化网站,而打了补丁的机器换成了System.Web.dll!System.Web.Hosting.ProcessHost——这个初始化流程的变化就是问题根源。
可复现的完整步骤
- 新建一个C# Web Forms项目(选ASP.NET/Web Forms模板即可)
- 在项目根目录添加
ProgrammaticConfigurationProvider.cs文件,代码如下:
using System.Configuration; using System.Linq; using System.Web; using System.Xml; namespace WebApplication1 { public class ProgrammaticConfigurationProvider : ProtectedConfigurationProvider { public override XmlNode Decrypt( XmlNode encryptedNode ) { var configElement = encryptedNode.ChildNodes.OfType<XmlElement>().First(); switch ( configElement.Name ) { case "sessionState": configElement.SetAttribute( "cookieName", "Test:" + ( HttpContext.Current.Session == null ? "Null" : "NotNull" ) ); break; } return configElement; } public override XmlNode Encrypt( XmlNode node ) => throw new System.NotImplementedException(); } }
- 编辑
web.config,在configuration节点下插入这段配置:
<configProtectedData defaultProvider="ProgrammaticConfigurationProvider"> <providers> <add name="ProgrammaticConfigurationProvider" type="WebApplication1.ProgrammaticConfigurationProvider, WebApplication1" /> </providers> </configProtectedData>
- 再在
system.web节点下添加:
<sessionState configProtectionProvider="ProgrammaticConfigurationProvider"> <EncryptedData> <sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;user id=sa;password=" cookieless="false" timeout="20" /> </EncryptedData> </sessionState>
运行项目后,Decrypt方法里的HttpContext.Current肯定是空的;卸载补丁后一切又恢复正常。
针对你疑问的解答
1. 为什么没主动请求,却自动安装了预览版补丁?
Windows Update的预览版推送逻辑有几种可能:
- 你的系统开启了“获取其他Microsoft产品的更新”选项,或者不小心开启了预览版更新通道(哪怕没加入Windows Insider计划,部分预览补丁也可能被推送)。
- 如果是企业环境,公司的WSUS服务器可能同步了预览补丁,管理员设置了自动推送。
- 微软有时候会给可能受特定问题影响的用户定向推送预览补丁,提前解决潜在问题,但这种情况不多见。
2. 正式补丁会影响我的百余个客户站点吗?这个调用栈变化是BUG吗?会被修复吗?
- 毫无疑问,正式补丁KB4578974会引发完全相同的故障,从你的测试结果就能看出来——初始化流程从
PipelineRuntime改成ProcessHost后,在ProtectedConfigurationProvider的Decrypt阶段,HttpContext还没被创建出来,自然拿不到HttpContext.Current。 - 这种情况属于微软更新引入的兼容性BUG,之前.NET Framework的更新也出过类似的初始化流程变更导致的问题,微软一般会在后续的累积更新里修复这类兼容性问题,毕竟影响面不小。
临时应对方案
在等微软出修复补丁的这段时间,你可以用这些方法减少对客户站点的影响:
- 先卸载KB4578974或KB4576947,回滚到之前的版本,保证业务正常运行。
- 修改你的自定义
ProtectedConfigurationProvider代码,别在Decrypt方法里依赖HttpContext.Current:- 比如把需要从上下文拿的配置信息提前到
Application_Start里缓存好,或者换一种不依赖上下文的配置方式。 - 如果一定要处理
sessionState,可以在Global.asax的Session_Start事件里动态修改相关属性,而不是在配置解密的时候操作。
- 比如把需要从上下文拿的配置信息提前到
内容的提问来源于stack exchange,提问作者Terry
相关产品推荐
相关产品推荐

