Custom error pages in ASP.NET MVC 5

2019-05-17 08:17发布

问题:

I want to add custom error pages to my project. I found this post about my problem and i try to implement it.

So :

  • i add 404.cshtml, 404.html, 500.cshtml and 500.html pages
  • set response status code in added cshtml files
  • comment adding HandleErrorAttribute to global filters
  • update my web.config file

But now when i try to go by path http://localhost:120/foo/bar where my app is on http://localhost:120 i get next page :

Server Error in '/' Application.

Runtime Error

Description: An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.

I set <customErrors mode="Off" to see what problem is. It was - The resource cannot be found. which is logical. But when i set <customErrors mode="On" - i again get Runtime error.

What can cause it and how to solve it?


My config file :

<system.web>
    <customErrors mode="Off" redirectMode="ResponseRewrite" defaultRedirect="~/500.cshtml">
        <error statusCode="404" redirect="~/404.cshtml"/>
        <error statusCode="500" redirect="~/500.cshtml"/>
    </customErrors>
</system.web>

<system.webServer>
    <httpErrors errorMode="Custom">
        <remove statusCode="404"/>
        <error statusCode="404" path="404.html" responseMode="File"/>
        <remove statusCode="500"/>
        <error statusCode="500" path="500.html" responseMode="File"/>
    </httpErrors>
</system.webServer>

IIS version 8.5

回答1:

What version of IIS are you using? If 7+ then ignore custom errors using <customErrors mode="Off"> and use <httpErrors>. Using the method below the latter will show your error page without changing the URL which IMO is the preferred way of handling these things.

Set up an Error Controller and put your 404 and 500 in there like so:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" />
    <remove statusCode="500" />
    <error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
    <error statusCode="500" path="/error/servererror" responseMode="ExecuteURL" />
 </httpErrors>

In the controller:

public class ErrorController : Controller
{
    public ActionResult servererror()
    {
        Response.TrySkipIisCustomErrors = true;
        Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        return View();
    }

    public ActionResult notfound()
    {
        Response.TrySkipIisCustomErrors = true;
        Response.StatusCode = (int)HttpStatusCode.NotFound;
        return View();
    }

}

Then obviously set up the corresponding view for each error covered.



回答2:

Your redirect url is not correct. Make it ~/404.html and ~/500.html. Notice that I changed the extension from .cshtml. Make sure the files exist and you are pointing to the correct location.



回答3:

I had to do the following:

  1. Remove the defaultPath from httpErrors and defaultRedirect from customErrors.
  2. Make sure in Global.asax I had registered a default route:

    routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { action = "Index", id = UrlParameter.Optional 
    });
    

I'm not sure why step 1 was necessary and step 2 was because we're doing EPiServer.