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

时间:2011-10-18 08:35:26

标签: 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" }
);

在Visual Studio中可以正常工作,但在生产中我收到了IIS错误页面。

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

注意:我想要重定向到特定于404的网址;而是我在请求的URL上提供404错误页面(我认为从可用性的角度来看这是正确的方法)。

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

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

** SOLUTION * *
Dommer获得了建议Response.TrySkipIisCustomErrors=true;的奖励(我认为)是必要的。但还有其他两个关键细节:

  • 自定义错误需要在web.config中显示<​​em> (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));          
}

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

return NotFound();

注意: RedirectToAction()

锦上添花:
我生成并传递到视图中的模型是将URL的罗嗦位添加到我们的搜索引擎中,并在友好的404页面上显示前三个结果作为建议。

2 个答案:

答案 0 :(得分: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" }
);

如果您想要更全面的答案,请查看以下内容:How can I properly handle 404 in ASP.NET MVC?

修改

要摆脱自定义IIS错误,请尝试将错误控制器更改为:

Response.StatusCode = 404;
Response.TrySkipIisCustomErrors=true; // add this line

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

答案 1 :(得分:0)

请尝试这样

 routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "account", action = "index", id = UrlParameter.Optional } // Parameter defaults
            );


routes.MapRoute(
                        "404-PageNotFound", // Route name
                        "{*url}", 
                        new { controller = "Error", action = "PageNotFound", id = UrlParameter.Optional } // Parameter defaults
                    );