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