自定义ASP.NET MVC 404错误页面的路由

时间:2009-02-16 16:37:05

标签: asp.net asp.net-mvc asp.net-mvc-routing http-status-code-404 custom-error-pages

我正在尝试在有人输入网址时创建自定义HTTP 404错误页面 它不会在ASP.NET MVC中调用有效的操作或控制器,而不是显示通用的“未找到资源”ASP.NET错误。

我不想使用web.config来处理这个问题。

我可以采取任何类型的路由魔法来捕获任何无效的网址吗?

更新:我尝试了给出的答案,但是我仍然收到了丑陋的“资源未找到”消息。

另一次更新:好的,显然RC1中发生了一些变化。我甚至尝试在HttpException上专门捕获404,它仍然只是给了我“未找到资源”页面。

我甚至使用了MvcContrib的资源功能,没有 - 同样的问题。有什么想法吗?

10 个答案:

答案 0 :(得分:101)

我尝试在生产服务器上启用自定义错误3个小时,似乎我找到了最终的解决方案,如何在没有任何路由的ASP.NET MVC中执行此操作。

要在ASP.NET MVC应用程序中启用自定义错误,我们需要(IIS 7 +):

  1. system.web部分下的网络配置中配置自定义页面:

    <customErrors mode="RemoteOnly"  defaultRedirect="~/error">
        <error statusCode="404" redirect="~/error/Error404" />
        <error statusCode="500" redirect="~/error" />
    </customErrors>
    

    RemoteOnly表示在本地网络上您会看到真正的错误(在开发过程中非常有用)。我们还可以为任何错误代码重写错误页面。

  2. 设置魔术响应参数和响应状态代码(在错误处理模块或错误句柄属性中)

      HttpContext.Current.Response.StatusCode = 500;
      HttpContext.Current.Response.TrySkipIisCustomErrors = true;
    
  3. system.webServer部分下的网络配置中设置另一个魔术设置:

    <httpErrors errorMode="Detailed" />
    
  4. 这是我发现的最后一件事,在此之后我可以在生产服务器上看到自定义错误。

答案 1 :(得分:41)

我通过创建一个返回本文中视图的ErrorController来使我的错误处理工作。我还必须在global.asax中添加“Catch All”到路由。

如果它不在Web.config中,我看不出它会如何到达这些错误页面?我的Web.config必须指定:

customErrors mode="On" defaultRedirect="~/Error/Unknown"

然后我还补充道:

error statusCode="404" redirect="~/Error/NotFound"

答案 2 :(得分:27)

Source

NotFoundMVC - 只要在ASP.NET MVC3应用程序中找不到控制器,操作或路由,就会提供用户友好的404页面。 将呈现名为NotFound的视图,而不是默认的ASP.NET错误页面。

您可以使用以下命令通过nuget添加此插件: Install-Package NotFoundMvc

NotFoundMvc在Web应用程序启动期间自动安装。它处理ASP.NET MVC通常抛出404 HttpException的所有不同方式。这包括缺少控制器,动作和路线。

分步安装指南:

1 - 右键单击​​您的项目并选择Manage Nuget Packages ...

2 - 搜索NotFoundMvc并安装它。 enter image description here

3 - 安装完成后,将向项目中添加两个文件。如下面的屏幕截图所示。

enter image description here

4 - 打开Views / Shared中新添加的NotFound.cshtml,并根据您的意愿修改它。现在运行应用程序并输入一个不正确的URL,您将看到一个用户友好的404页面。

enter image description here

不再是,用户会收到错误消息,例如Server Error in '/' Application. The resource cannot be found.

希望这会有所帮助:)

P.S:感谢Andrew Davey制作这样一个非常棒的插件。

答案 3 :(得分:19)

在web.config中尝试此操作以替换IIS错误页面。这是我猜的最佳解决方案,它也会发出正确的状态代码。

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="500" subStatusCode="-1" />
    <error statusCode="404" path="Error404.html" responseMode="File" />
    <error statusCode="500" path="Error.html" responseMode="File" />
  </httpErrors>
</system.webServer>

来自Tipila - Use Custom Error Pages ASP.NET MVC的更多信息

答案 4 :(得分:15)

此解决方案不需要web.config文件更改或catch-all路由。

首先,创建一个像这样的控制器;

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = "Regular Error";
        return View();
    }

    public ActionResult NotFound404()
    {
        ViewBag.Title = "Error 404 - File not Found";
        return View("Index");
    }
}

然后在“Views / Error / Index.cshtml”下创建视图;

 @{
      Layout = "~/Views/Shared/_Layout.cshtml";
  }                     
  <p>We're sorry, page you're looking for is, sadly, not here.</p>

然后在Global asax文件中添加以下内容:

protected void Application_Error(object sender, EventArgs e)
{
        // Do whatever you want to do with the error

        //Show the custom error page...
        Server.ClearError(); 
        var routeData = new RouteData();
        routeData.Values["controller"] = "Error";

        if ((Context.Server.GetLastError() is HttpException) && ((Context.Server.GetLastError() as HttpException).GetHttpCode() != 404))
        {
            routeData.Values["action"] = "Index";
        }
        else
        {
            // Handle 404 error and response code
            Response.StatusCode = 404;
            routeData.Values["action"] = "NotFound404";
        } 
        Response.TrySkipIisCustomErrors = true; // If you are using IIS7, have this line
        IController errorsController = new ErrorController();
        HttpContextWrapper wrapper = new HttpContextWrapper(Context);
        var rc = new System.Web.Routing.RequestContext(wrapper, routeData);
        errorsController.Execute(rc);

        Response.End();
}

如果在执行此操作后仍然出现自定义IIS错误页面,请确保在Web配置文件中注释掉(或清空)以下部分:

<system.web>
   <customErrors mode="Off" />
</system.web>
<system.webServer>   
   <httpErrors>     
   </httpErrors>
</system.webServer>

答案 5 :(得分:10)

只需在路由表的末尾添加catch all route并显示您想要的任何页面。

请参阅:How can i make a catch all route to handle '404 page not found' queries for ASP.NET MVC?

答案 6 :(得分:5)

如果你在MVC 4工作,你可以看this解决方案,它对我有用。

将以下Application_Error方法添加到Global.asax

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "Index");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    IController controller = new ErrorController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();

控制器本身非常简单:

public class ErrorController : Controller
{
    public ActionResult Index(int statusCode, Exception exception)
    {
        Response.StatusCode = statusCode;
        return View();
    }
}

检查Mvc4CustomErrorPage at GitHub的完整源代码。

答案 7 :(得分:0)

我遇到了同样的问题,您需要做的是,不必在Views文件夹的web.config文件中添加customErrors属性,而是必须将它添加到项目根文件夹的web.config文件中

答案 8 :(得分:0)

这是真正的答案,它允许在一个地方完全自定义错误页面。 无需修改web.config或创建单独的代码。

也适用于MVC 5.

将此代码添加到控制器:

        if (bad) {
            Response.Clear();
            Response.TrySkipIisCustomErrors = true;
            Response.Write(product + I(" Toodet pole"));
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            //Response.ContentType = "text/html; charset=utf-8";
            Response.End();
            return null;
        }

基于http://www.eidias.com/blog/2014/7/2/mvc-custom-error-pages

答案 9 :(得分:0)

我将讨论一些具体情况,

如果您在HomeController中使用如下所示的“ PageNotFound方法”

[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

这行不通。但是您必须清除如下所示的Route标签,

//[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

并且如果您将其更改为web.config中的“方法”名称,则有效。 但是,不要忘记在web.config

中执行以下代码
<customErrors mode="On">
  <error statusCode="404" redirect="~/PageNotFound" /> 
 *// it is not "~/404" because it is not accepted url in Route Tag like [Route("404")]*
</customErrors>