我有一个我无法解释的有趣案例,我需要帮助找出我在 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 应用程序池进行配置
- <modules runAllManagedModulesForAllRequests="true" /> 在 system.webServer 部分设置
在IIS 7.5中,行为是:
- GET请求到/:返回索引页面
- 对 / 的 POST 请求:返回索引页
- 对 /Service/Test 的 GET 请求:返回Test
- 对 /Service/Test 的 POST 请求:返回Test
- 对 /Service/Test2 的 GET 请求:执行 Global.asax Application_Error:HttpException:在控制器“MyTestProject.Controllers.ServiceController”上找不到公共操作方法“Test2”。
- 对 /Service/Test2 的 POST 请求:返回Test2
- 对没有路由的事物的 GET 请求:执行 Global.asax End_Request。
在IIS 7中,行为改为:
- GET请求到/:返回索引页面
- POST 请求到 /:IIS 404 页面
- 对 /Service/Test 的 GET 请求:返回测试
- 对 /Service/Test 的 POST 请求:IIS 404 页面
- 对 /Service/Test2 的 GET 请求:执行 Global.asax Application_Error:HttpException:在控制器“MyTestProject.Controllers.ServiceController”上找不到公共操作方法“Test2”。
- 对 /Service/Test2 的 POST 请求:返回 IIS 404 页面
- GET请求没有路由的东西:IIS 404页面
因此,IIS 7 和 IIS 7.5 在使用 GET 请求时运行良好,除非没有路由。当没有路由时,IIS 7.5 执行带有状态码 404 的 Global.asax 结束请求并传递索引页。IIS 7 不执行Global.asax 结束请求。为什么?我可以(并且目前正在)通过注册 {*catchall} 路由来解决此问题,以便存在匹配的路由。
当我尝试使用 HTTP POST 时,IIS 7 的工作量甚至低于我的预期。
发布请求时,IIS 7 不会在我的应用程序中执行任何代码,而是直接返回 IIS 404 页面。
所以我的问题是:为什么 IIS 7 如此难以处理我的 MVC 4 应用程序中的 POST 请求,我该怎么做才能让它也处理 POST 请求?