问题:
有时候我们配置IIS后可能运行提示以下错误:
HTTP 错误 500.23 - Internal Server Error
检测到在集成的托管管道模式下不适用的 ASP.NET 设置。
其中由于在IIS7的应用程序池有两种模式, “集成模式”和“经典模式”。
经典模式 则是我们以前习惯的IIS 6 的方式。
如果使用集成模式,那么对自定义的httpModules 和 httpHandlers 就要修改配置文件,需要将他们转移到<modules>和<hanlders>节里去。
两种解决方法:
第一种方法:配置应用程序池
在IIS7上配置应用程序池,并且将程序池的模式改为“经典”,之后一切正常。
但这样只是权宜之计,用了IIS7.x,但实际只发挥了6的功能
第二种方法:修改web.config配置文件:
例如原先设置(你的环境中可能没有httpModules,httpHandlers节点)
<system.web>
............
<httpModules>
<add name="WebbHttpModule" type="Webb.WAVE.Controls.Upload.WebbHttpModule, Webb.WAVE.Controls.Upload" />
<add name="rewriteUrl" type="RewritUrl.Rw,RewritUrl" />
</httpModules>
<httpHandlers>
<add path="*.myh" verb="GET" type="MyHandler" />
</httpHandlers>
</system.web>
在IIS7应用程序池为“集成模式”时,改为:
<system.web>
...........
</system.web>
<system.webServer>
<modules>
<add name="WebbHttpModule" type="Webb.WAVE.Controls.Upload.WebbHttpModule, Webb.WAVE.Controls.Upload" />
<add name="rewriteUrl" type="RewritUrl.Rw,RewritUrl" />
</modules>
<handlers>
<add name="MyHandler" path="*.myh" verb="GET" type="MyHandler" preCondition="integratedMode" />
</handlers>
</system.webServer>
(如果你的web.config没有httpModules,httpHandlers节点,则直接在节点system.webServer中添加:
<validation validateIntegratedModeConfiguration="false" />
这样可以禁止验证集成模式,避免错误提示。
经典模式(classic mode)和集成模式(Integrated mode)比较
在经典模式下,IIS会用ISAPI扩展(ISAPI extension aspnet_isapi.dll)和 ISAPI过滤器(ISAPI filter aspnet_filter.dll)来调用ASP.NET运行库来处理请求。如果使用经典模式的话,服务器会用两种管道来处理请求一个负责源代码,另外一个负责托管代码。在这种模式下,应用程序不能充分使用IIS7.X提供的服务。
微软官方一篇文章的图,介绍IIS7集成管道下的事件生命周期如下:
集成模式是一种统一的请求处理管道,由上图可以看到 ,集成模式下不管托管代码还是本机代码,都可以在身份验证和执行处理程序被插入到内核代码的托管代码拦截,它将ASP.NET请求管道与IIS核心管道组合在一起,ASP.NET从IIS插件(IIS extension)的角色进入了IIS的核心去监测每个请求和操作。并且可以有效的提高网站的性能。 有些在IIS6开发的代码需要运行于经典模式,因为在集成模式下会出现错误信息。
网上解释:在IIS6下,要想拦截本机代码,比如静态文件,需要编写WIN32的非托管代码,但它也保留扩展的ISAPI,我们可以写托管代码拦截托管文件的请求。虽然IIS6也可以通过IIS插入ISAPI为aspnet_isapi.dll的扩展,处理对静态文件的拦截,但它实际会走两个通道,首先是IIS内部的本机代码拦截,然后是托管代码ISAPI的拦截
IIS7集成模式还增加了MapRequestHandler、LogRequest 和 PostLogRequest 事件,如果在经典模式下加了这些处理事件,会抛出:此操作要求使用 IIS 集成管线模式。如果集成模式下不让IIS处理不兼容集成模式的配置以及处理方式,可以在web.config中配置:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>即可。
实际上IIS7集成模式,就是让用户可以通过编写托管代码的handlers、modules等模块,把托管代码插入到IIS内核代码中来解析,方便大家精确控制任意请求,带来更好的扩展性。