Iis 7 ASP.NET MVC4不在IIS7集成模式下处理POST请求,而是在IIS7.5中处理

Iis 7 ASP.NET MVC4不在IIS7集成模式下处理POST请求,而是在IIS7.5中处理,iis-7,asp.net-mvc-4,iis-7.5,Iis 7,Asp.net Mvc 4,Iis 7.5,我有一个有趣的案例无法解释,我需要帮助找出我在IIS7上的问题: 鉴于: ASP.NET MVC 4 web应用程序 注册到{controller}/{action}的默认路由 请参阅以下控制器: public class ServiceController : Controller { public ActionResult Test() { return Content("Test"); } [HttpPost] public A

我有一个有趣的案例无法解释,我需要帮助找出我在IIS7上的问题:

鉴于:

  • ASP.NET MVC 4 web应用程序
  • 注册到{controller}/{action}的默认路由
请参阅以下控制器:

public class ServiceController : Controller
{
    public ActionResult Test()
    {
        return Content("Test");
    }

    [HttpPost]
    public ActionResult Test2()
    {
        return Content("Test2");
    }
}
此外,在Global.asax中还有以下代码:

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 404)
    {
        ExecuteIndexPage();
    }
}

protected void Application_Error(object sender, EventArgs e)
{
    var error = Server.GetLastError();
    ExceptionLogger.Log(error);

    ExecuteIndexPage();
}
因此,每当出现服务器错误时,都会记录此错误。在这种情况下以及在普通404的情况下,返回起始页。这(几乎)行得通。稍后再谈

此设置在IIS7(Windows Server 2008,生产环境)和IIS7.5(Win7 Pro,开发环境和Windows Server 2008 R2,以及生产环境)上提供了非常不同的行为

给定IIS中的以下配置(两个版本):

  • IIS中的Web是使用集成模式ASP.NET 4应用程序池配置的
  • 在system.webServer节中设置
在IIS 7.5中,行为是:

  • 获取请求到/:返回索引页
  • POST请求到/:返回索引页
  • 获取对/服务/测试的请求:返回测试
  • 向/服务/测试发送请求后:返回测试
  • 获取对/Service/Test2的请求:执行Global.asax应用程序\u错误:HttpException:在控制器“MyTestProject.Controllers.ServiceController”上找不到公共操作方法“Test2”
  • 向/Service/Test2发送请求:返回Test2
  • 获取没有路由的请求:执行Global.asax End_请求
IIS 7中,行为为:

  • 获取请求到/:返回索引页
  • 将请求发布到/:IIS 404页
  • 获取对/服务/测试的请求:返回测试
  • 向/Service/Test发送请求:IIS 404页
  • 获取对/Service/Test2的请求:执行Global.asax应用程序\u错误:HttpException:在控制器“MyTestProject.Controllers.ServiceController”上找不到公共操作方法“Test2”
  • 对/Service/Test2的POST请求:返回IIS 404页面
  • 获取对没有路由的内容的请求:IIS 404页
因此,IIS 7和IIS 7.5在使用GET请求时工作得非常好,除非没有路由。 当没有路由时,IIS 7.5将执行状态代码为404的Global.asax end请求并交付索引页。IIS 7不执行Global.asax结束请求。为什么? 我可以(现在也可以)通过注册一个{*catchall}路由来解决这个问题,这样就存在一个匹配的路由

当我尝试使用HTTPPOST时,IIS7的工作效率甚至低于我的预期

发布请求时,IIS 7不会在我的应用程序中执行任何代码,而是直接返回IIS 404页面


所以我的问题是:为什么IIS 7在我的MVC 4应用程序中拒绝如此艰难地处理POST请求,我能做些什么让它也处理POST请求?

这可能与IIS 7上未安装(或未正确安装)的某些功能有关,这些功能会阻止无扩展URL正常工作

请检查以下项目:

在Windows控制面板“程序和功能”应用程序的“打开或关闭Windows功能”对话框中:

  • 转到Internet信息服务>万维网服务>通用HTTP功能
  • 确保选择了“HTTP错误重定向”选项
  • 确保选择了“静态内容压缩”选项。选择任一选项后,单击“确定”保存更改
    参考:

    可能7和7.5路由在将POST传递给没有参数可以接受POST表单数据的操作方面有所不同

    如果您的代码从未被命中,则表示路由没有找到签名、参数和内部约束的匹配项,而在将其传递给代码之前,路由会检查这些匹配项


    也许下一步是尝试将参数添加到POST以接受模型,即使您没有传入该模型。结果,该模型显然是空的。

    我们终于找到了答案

    默认配置会在web.config中插入以下内容:

    <system.webServer>
      <validation validateIntegratedModeConfiguration="false" />
      <modules runAllManagedModulesForAllRequests="true" />
      <handlers>
        <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
        <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      </handlers>
    </system.webServer>
    
    
    
    问题是“*”路径,它将覆盖/test.aspx,而不仅仅是/test

    如果将其更改为“*”,则所有请求都将由ExtensionlessUrlHandler处理,包括那些对不再提供服务的静态文件的请求

    因此,解决方案是: 从处理程序条目中删除POST谓词,并为路径设置为“*”的ExtensionlessUrlHandler添加新条目,并且仅用于POST请求:

        <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit_post" path="*" verb="POST" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0_post" path="*" verb="POST" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    
    
    
    理想情况下,删除您不需要的(经典管道与集成管道中的x86和x64)