Routing for custom ASP.NET MVC 404 Error page

强颜欢笑 提交于 2019-11-26 03:36:53

问题


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.

I don\'t want to use the web.config to handle this.

Is there any kind of routing magic I can do to catch any invalid URLs?

Update: I tried the answer given, however I still get the ugly \"Resource Not Found\" message.

Another update: Ok, apparently something changed in RC1. I\'ve even tried specifically trapping 404 on an HttpException and it still just gives me the \"Resource Not Found\" page.

I\'ve even used MvcContrib\'s resource\'s feature and nothing - same problem. Any ideas?


回答1:


Just add catch all route at the end of the routes table and display whatever page you want with it.

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




回答2:


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.

To enable custom errors in ASP.NET MVC application we need (IIS 7+):

  1. Configure custom pages in web config under system.web section:

    <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). 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:

    <httpErrors errorMode="Detailed" />
    

This was final thing that I've found and after this I can see custom errors on production server.




回答3:


I got my error handling to work by creating an ErrorController that returns the views in this article. I also had to add the "Catch All" to the route in global.asax.

I cannot see how it will get to any of these error pages if it is not in the Web.config..? My Web.config had to specify:

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

and then I also added:

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



回答4:


Source

NotFoundMVC - Provides a user-friendly 404 page whenever a controller, action or route is not found in your ASP.NET MVC3 application. A view called NotFound is rendered instead of the default ASP.NET error page.

You can add this plugin via nuget using: Install-Package NotFoundMvc

NotFoundMvc automatically installs itself during web application start-up. It handles all the different ways a 404 HttpException is usually thrown by ASP.NET MVC. This includes a missing controller, action and route.

Step by Step Installation Guide :

1 - Right click on your Project and Select Manage Nuget Packages...

2 - Search for NotFoundMvc and install it.

3 - Once the installation has be completed, two files will be added to your project. As shown in the screenshots below.

4 - Open the newly added NotFound.cshtml present at Views/Shared and modify it at your will. Now run the application and type in an incorrect url, and you will be greeted with a User friendly 404 page.

No more, will users get errors message like Server Error in '/' Application. The resource cannot be found.

Hope this helps :)

P.S : Kudos to Andrew Davey for making such an awesome plugin.




回答5:


Try this in web.config to replace IIS error pages. 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




回答6:


This solution doesn't need web.config file changes or catch-all routes.

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;

 @{
      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:

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:

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



回答7:


If you work in MVC 4, you can watch this solution, it worked for me.

Add the following Application_Error method to my 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.




回答8:


I had the same problem, the thing you have to do is, instead of adding the customErrors attribute in the web.config file in your Views folder, you have to add it in the web.config file in your projects root folder




回答9:


Here is true answer which allows fully customize of error page in single place. No need to modify web.config or create separate code.

Works also in 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




回答10:


I will talk about some specific cases,

if you are using 'PageNotFound method' in HomeController like below

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

it wouldn't work this. But you must clear Route tags like below,

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

And if you change it as method Name in web.config it works. However don't forget to do code like below in 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>


来源:https://stackoverflow.com/questions/553922/routing-for-custom-asp-net-mvc-404-error-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!