MVC:404路线在生产中无法正常工作

Fau*_*ust 5 asp.net-mvc iis-7 asp.net-mvc-routing http-status-code-404

我在global.asax的底部有以下路由:

//404 ERRORS:
routes.MapRoute(
    "404-PageNotFound",
    "{*url}",
    new { controller = "Error", action = "PageNotFound" }
);
Run Code Online (Sandbox Code Playgroud)

哪个在Visual Studio中工作正常,但在生产中我得到了IIS错误页面.

这条路线不应该捕获任何未被其他人捕获的URL,因此从IIS的角度来看没有404吗?我还需要在web.config中做些什么吗?

注:我希望重定向到一个404特定URL; 而是我在请求的URL上提供404错误页面(我认为从可用性的角度来看这是正确的方法).

更新
在我的错误控制器中,我正在设置Response.StatusCode = 404;,这似乎是问题.当我删除它并再次部署到生产时,我再次获得友好的错误页面.但是,我相信我确实需要HTTP标头中的404状态 - 出于搜索引擎优化的目的 - 所以现在我的问题变为:

修订问题
IIS如何/为什么拦截响应并发送其开箱即用的404错误,我该如何防止这种情况?

**解决方案**
Dommer获得奖品以表明Response.TrySkipIisCustomErrors=true;哪些(我认为)是必要的.但还有另外两个关键细节:

  • 需要在web.config(duh!)中启用自定义错误
  • 404动作必须具有[HandleErrors]属性.

让它在任何地方工作
由于某些URL可能会映射到"404-PageNotFound"以外的路由但包含无效参数,并且由于我不想重定向到404页面,因此我在基本控制器中创建了此操作:

[HandleError]
public ActionResult NotFound()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true;     
    return View("PageNotFound", SearchUtilities.GetPageNotFoundModel(HttpContext.Request.RawUrl));          
}
Run Code Online (Sandbox Code Playgroud)

并且在任何继承基础的控制器动作中,每当我捕获无效的路由参数时,我只需要调用它:

return NotFound();
Run Code Online (Sandbox Code Playgroud)

注意:不是 RedirectToAction()

锦上添花:
我生成并传递到视图中的模型是将URL的多余部分输入到我们的搜索引擎中,并在友好的404页面上显示前3个结果作为建议.

Tom*_*ler 4

问题是您的请求与您之前的路由之一匹配,然后失败。一个可能的解决方案是尝试限制其他路线,如下所示:

// This will match too many things, so let's constrain it to those we know are valid
   routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new { controller = "Home|OtherController|AnotherController|..." } // regular expression matching all valid controllers
);

//404 ERRORS:
routes.MapRoute(
    "404-PageNotFound",
    "{*url}",
    new { controller = "Error", action = "PageNotFound" }
);
Run Code Online (Sandbox Code Playgroud)

如果您想要更全面的答案,请查看以下内容:How can I妥善处理 ASP.NET MVC 中的 404?

编辑:

要消除自定义 IIS 错误,请尝试将错误控制器更改为如下所示:

Response.StatusCode = 404;
Response.TrySkipIisCustomErrors=true; // add this line
Run Code Online (Sandbox Code Playgroud)

MSDN 文档:http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors.aspx