<httpErrors> does not work

Asked

Viewed 306 times

1

I’m trying to make a mistake handling with this setting:

  <system.webServer>
    <modules>
      <remove name="FormsAuthentication"/>
    </modules>

    <httpErrors  errorMode="Custom" defaultResponseMode="File">
      <remove statusCode="404" />
      <error statusCode="404" path="/Erro/404.html" />
    </httpErrors>

  </system.webServer>

My page 404.html is inside Views/Erro/404.html.

But when running a url that does not exist it does not do the processing, comes the default IIS error page.

I saw several tutorials and each one does a different thing, for example:

Use subStatusCode='-1' or use defaultResponseMode="ExecuteURL"

Which in my case didn’t work.

Can anyone see anything wrong in the configuration?

2 answers

2

Yes. Some.

The correct configuration initially would be like this:

<configuration>
...
  <system.web>
  ...
    <customErrors mode="On">
      <error statusCode="404" redirect="~/Views/Erro/404.html" />
    </customErrors> 
  ...
  </system.web>
...
</configuration>

But I particularly don’t like this way because it goes against the architecture of MVC. I’m more of a use approach Actions of Controllers to produce more interesting error screens:

<configuration>
...
  <system.web>
  ...
    <customErrors mode="On" defaultRedirect="~/Error/Index">
      <error statusCode="404" redirect="~/Error/NotFound"/>
      <error statusCode="403" redirect="~/Error/BadRequest"/>
    </customErrors>
  ...
  </system.web>
...
</configuration>

The problem is that this mode causes the transfer to return a 302 code, and soon after a 200 code, which hurts the HTTP protocol, since we had an error (ie 400 codes onwards), so we need to adapt again.

<configuration>
...
  <system.web>
  ...
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Error/Index">
      <error statusCode="404" redirect="~/Error/NotFound"/>
      <error statusCode="403" redirect="~/Error/BadRequest"/>
    </customErrors>
  ...
  </system.web>
...
</configuration>

Another problem: this doesn’t work right, because ASP.NET MVC uses Server.Transfer to redirect to content static, non-dynamic. In the end, the configuration would look like this:

<configuration>
...
  <system.web>
  ...
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Views/Erro/404.html">
      <error statusCode="404" redirect="~/Error/NotFound"/>
      <error statusCode="403" redirect="~/Error/BadRequest"/>
    </customErrors>
  ...
  </system.web>
...
</configuration>

Anyway, I don’t really like any of these ways. I prefer another, proposed by this reply here:

Global.asax.Cs

public class MvcApplication : HttpApplication
{
    protected void Application_EndRequest()
    {
        if (Context.Response.StatusCode == 404)
        {
            Response.Clear();

            var rd = new RouteData();

            rd.Values["controller"] = "Errors";
            rd.Values["action"] = "NotFound";

            IController c = new ErrorsController();
            c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
        }
    }
}

Errorscontroller.Cs

public sealed class ErrorsController : Controller
{
    public ActionResult NotFound()
    {
        ActionResult result;

        object model = Request.Url.PathAndQuery;

        if (!Request.IsAjaxRequest())
            result = View(model);
        else
            result = PartialView("_NotFound", model);

        return result;
    }
}

I would say that is the most decent way to handle HTTP errors in an MVC application.

In fact, it is worth reading the answer that Linkei here. It explains more thoroughly all the problems of using HTTP errors by setting.

  • I chose to put within <system.webserver> to make a wider treatment possible, if put within <system.web> it is more limited. One legal article I read about this is this, but not what he did there didn’t work on my http://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

0


I found the problem:

You said put <customErrors mode="Off" /> inside </system.web>

I can’t explain exactly why this, maybe one treatment breaks the other, but in my case.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.