简体   繁体   English

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

[英]Routing for custom ASP.NET MVC 404 Error page

I am trying to make a custom HTTP 404 error page when someone types in a URL that doesn't invoke a valid action or controller in ASP.NET MVC, instead of it displaying the generic "Resource Not Found" ASP.NET error. 当有人键入不调用ASP.NET MVC中的有效操作或控制器的URL而不显示通用的“未找到资源”ASP.NET错误时,我试图创建自定义HTTP 404错误页面。

I don't want to use the web.config to handle this. 我不想使用web.config来处理这个问题。

Is there any kind of routing magic I can do to catch any invalid URLs? 是否有任何类型的路由魔法可以捕获任何无效的URL?

Update: I tried the answer given, however I still get the ugly "Resource Not Found" message. 更新:我尝试了给出的答案,但我仍然得到丑陋的“资源未找到”消息。

Another update: Ok, apparently something changed in RC1. 另一个更新:好的,显然RC1中发生了一些变化。 I've even tried specifically trapping 404 on an HttpException and it still just gives me the "Resource Not Found" page. 我甚至试图在HttpException上专门捕获404,它仍然只是给我“未找到资源”页面。

I've even used MvcContrib's resource's feature and nothing - same problem. 我甚至使用过MvcContrib的资源功能,没有 - 同样的问题。 Any ideas? 有任何想法吗?

I've tried to enable custom errors on production server for 3 hours, seems I found final solution how to do this in ASP.NET MVC without any routes. 我试图在生产服务器上启用自定义错误3个小时,似乎我找到了最终解决方案如何在没有任何路由的ASP.NET MVC中执行此操作。

To enable custom errors in ASP.NET MVC application we need (IIS 7+): 要在ASP.NET MVC应用程序中启用自定义错误,我们需要(IIS 7+):

  1. Configure custom pages in web config under system.web section: system.web部分下的web配置中配置自定义页面:

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

    RemoteOnly means that on local network you will see real errors (very useful during development). RemoteOnly意味着在本地网络上您将看到真正的错误(在开发过程中非常有用)。 We can also rewrite error page for any error code. 我们还可以为任何错误代码重写错误页面。

  2. Set magic Response parameter and response status code (in error handling module or in error handle attribute) 设置魔术响应参数和响应状态代码(在错误处理模块或错误句柄属性中)

      HttpContext.Current.Response.StatusCode = 500; HttpContext.Current.Response.TrySkipIisCustomErrors = true; 
  3. Set another magic setting in web config under system.webServer section: system.webServer部分下的web配置中设置另一个魔术设置:

     <httpErrors errorMode="Detailed" /> 

This was final thing that I've found and after this I can see custom errors on production server. 这是我发现的最后一件事,在此之后我可以在生产服务器上看到自定义错误。

I got my error handling to work by creating an ErrorController that returns the views in this article. 我通过创建一个返回本文中视图的ErrorController来使我的错误处理工作。 I also had to add the "Catch All" to the route in global.asax. 我还必须在global.asax中添加“Catch All”到路由。

I cannot see how it will get to any of these error pages if it is not in the Web.config..? 如果它不在Web.config中,我无法看到它将如何到达任何这些错误页面。? My Web.config had to specify: 我的Web.config必须指定:

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

and then I also added: 然后我还补充说:

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

Source 资源

NotFoundMVC - Provides a user-friendly 404 page whenever a controller, action or route is not found in your ASP.NET MVC3 application. NotFoundMVC - 只要在ASP.NET MVC3应用程序中找不到控制器,操作或路由,就会提供用户友好的404页面。 A view called NotFound is rendered instead of the default ASP.NET error page. 将呈现名为NotFound的视图,而不是默认的ASP.NET错误页面。

You can add this plugin via nuget using: Install-Package NotFoundMvc 您可以使用以下命令通过nuget添加此插件:Install-Package NotFoundMvc

NotFoundMvc automatically installs itself during web application start-up. NotFoundMvc在Web应用程序启动期间自动安装。 It handles all the different ways a 404 HttpException is usually thrown by ASP.NET MVC. 它处理ASP.NET MVC通常抛出404 HttpException的所有不同方式。 This includes a missing controller, action and route. 这包括缺少控制器,动作和路线。

Step by Step Installation Guide : 分步安装指南:

1 - Right click on your Project and Select Manage Nuget Packages... 1 - 右键单击​​您的项目并选择Manage Nuget Packages ...

2 - Search for NotFoundMvc and install it. 2 - 搜索NotFoundMvc并安装它。 在此输入图像描述

3 - Once the installation has be completed, two files will be added to your project. 3 - 安装完成后,将向项目中添加两个文件。 As shown in the screenshots below. 如下面的屏幕截图所示。

在此输入图像描述

4 - Open the newly added NotFound.cshtml present at Views/Shared and modify it at your will. 4 - 打开Views / Shared中新添加的NotFound.cshtml,并根据您的意愿修改它。 Now run the application and type in an incorrect url, and you will be greeted with a User friendly 404 page. 现在运行应用程序并输入一个不正确的URL,您将看到一个用户友好的404页面。

在此输入图像描述

No more, will users get errors message like Server Error in '/' Application. The resource cannot be found. 此外,用户是否会Server Error in '/' Application. The resource cannot be found.收到错误消息,如“ Server Error in '/' Application. The resource cannot be found. Server Error in '/' Application. The resource cannot be found.

Hope this helps :) 希望这可以帮助 :)

PS : Kudos to Andrew Davey for making such an awesome plugin. PS:感谢Andrew Davey制作了这么棒的插件。

Try this in web.config to replace IIS error pages. 在web.config中尝试此操作以替换IIS错误页面。 This is the best solution I guess, and it sends out the correct status code too. 这是我猜的最佳解决方案,它也会发出正确的状态代码。

<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>

More info from Tipila - Use Custom Error Pages ASP.NET MVC 来自Tipila的更多信息- 使用自定义错误页面ASP.NET MVC

This solution doesn't need web.config file changes or catch-all routes. 此解决方案不需要web.config文件更改或catch-all路由。

First, create a controller like this; 首先,创建一个这样的控制器;

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

Then create the view under "Views/Error/Index.cshtml" as; 然后在“Views / Error / Index.cshtml”下创建视图;

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

Then add the following in the Global asax file as below: 然后在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();
}

If you still get the custom IIS error page after doing this, make sure the following sections are commented out(or empty) in the web config file: 如果在执行此操作后仍然出现自定义IIS错误页面,请确保在Web配置文件中注释掉(或清空)以下部分:

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

Just add catch all route at the end of the routes table and display whatever page you want with it. 只需在路由表的末尾添加catch all route并显示您想要的任何页面。

See: How can i make a catch all route to handle '404 page not found' queries for ASP.NET MVC? 请参阅: 如何捕获所有路由以处理ASP.NET MVC的“未找到404页面”查询?

If you work in MVC 4, you can watch this solution, it worked for me. 如果您在MVC 4中工作,您可以观看解决方案,它对我有用。

Add the following Application_Error method to my Global.asax : 将以下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();

The controller itself is really simple: 控制器本身非常简单:

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

Check the full source code of Mvc4CustomErrorPage at GitHub . 在GitHub上查看Mvc4CustomErrorPage的完整源代码。

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

Here is true answer which allows fully customize of error page in single place. 这是真正的答案,允许在一个地方完全自定义错误页面。 No need to modify web.config or create separate code. 无需修改web.config或创建单独的代码。

Works also in MVC 5. 也适用于MVC 5。

Add this code to controller: 将此代码添加到控制器:

        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;
        }

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

I will talk about some specific cases, 我会谈谈一些具体的案例,

if you are using 'PageNotFound method' in HomeController like below 如果您在HomeController中使用'PageNotFound方法',如下所示

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

it wouldn't work this. 它不会起作用。 But you must clear Route tags like below, 但是你必须清除下面的Route标签,

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

And if you change it as method Name in web.config it works. 如果您在web.config中将更改为方法名称, 则可以正常工作。 However don't forget to do code like below in 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM