2
votes

I have been trying to configure Custom Error pages in ASP.NET MVC 5 but with little complete success.

To do this, I have followed this guide: http://benfoster.io/blog/aspnet-mvc-custom-error-pages

Web.config customerrors

<customErrors mode="On" defaultRedirect="~/500.aspx" redirectMode="ResponseRewrite">
  <error statusCode="401" redirect="~/401.aspx" />
  <error statusCode="403" redirect="~/401.aspx" />
  <error statusCode="404" redirect="~/404.aspx" />      
</customErrors>

Web.config httpErrors

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

I have removed the HandleErrorAttribute from filter config.

With this setup, I get the following results:

  • Browse to a non-existent static resource
    Example: http://my.website.com/fakeresource.htm
    This results in the static 404.htm file configured in the httpErrors section.
    The Url is preserved in the browser address bar
    A 404 status code is correctly set.

  • Browse to a bad route
    Example: http://my.website/realcontroller/fakeaction
    This results in a HttpException being thrown when a matching route cannot be found.
    The 404.aspx page is displayed.
    The Url is preserved in the browser address bar.
    A 404 status code is correctly set.

  • Browse to a valid route, but with an invalid ID for a database resource
    Example: http://my.website.com/realcontroller/realaction/22
    (22 is the ID of a resource which does not exist, the Action will return the HttpNotFound() method.
    This results in the static 404.htm file configured in the httpErrors section.
    The Url is preserved in the browser address bar
    A 404 status code is correctly set.
    If I throw HttpException(404, "Not Found") instead of using HttpNotFound(), I get the 404 defined in customErrors

  • Exceptions & Unauthorised Requests
    Also all work correctly using this configuration of Web.config

However, any action which checks ModelState with ModelSate.IsValid, or adds errors using ModelState.AddModelError("InputName", "Error Message"); results in a 400 Bad request.

Here are the errors I get in IE & Chrome:

IE
IE

Chrome
Chrome

Instead, what I should be getting is the original view, with the validation messages displayed next to the inputs which failed validation.

If I remove the httpErrors section from web.config, the issue is resolved, but I no longer get custom IIS error pages.

I have also tried every option of the existingResponse property on httpErrors but different options breaks either the error pages or the ModelState validation.

Finally I tried setting Response.TrySkipIisCustomErrors = true; and this appear to fix the problem in the action I was testing.

But this means that I have to set this property on every action which uses ModelState, and that just doesn't sound right.

What am I doing wrong?

UPDATE To test if this was project specific, I created a new project in VS2012 and configured the same error pages. Frustratingly, everything worked. The only difference I can think of now is that the project experiencing the problem originally started out using MVC 4, and was upgraded to MVC 5.

1
Have you tried setting detailed errors to on in IIS? blogs.msdn.com/b/rakkimk/archive/2007/05/25/…Slicksim
@Slicksim My understanding is that this is exactly what the httpErrors section is configuring in web.configphilreed
I thought the same, but practice shows something different. With the responsecode being set to an error, IIS 7+ hides the html that is returned and injects it's own. setting the detailed errors to on fixed loads of issues i had with things like thisSlicksim

1 Answers

1
votes

It would appear that custom errors had nothing to do with the bad request I encountered. Instead, there was another form on the page which was incorrectly also being called when the main form was being posted.