How to implement proper HTTP error handling in .NET MVC 2?

流过昼夜 提交于 2019-11-27 06:19:24

Here's one technique you could use. Define an ErrorsController which will serve the error pages:

public class ErrorsController : Controller
{
    public ActionResult Http404()
    {
        Response.StatusCode = 404;
        return Content("404", "text/plain");
    }

    public ActionResult Http500()
    {
        Response.StatusCode = 500;
        return Content("500", "text/plain");
    }

    public ActionResult Http403()
    {
        Response.StatusCode = 403;
        return Content("403", "text/plain");
    }
}

and then in Global.asax you could subscribe for the Application_Error event where you could log the exception and execute the corresponding action of the ErrorsController:

protected void Application_Error(object sender, EventArgs e)
{
    var app = (MvcApplication)sender;
    var context = app.Context;
    var ex = app.Server.GetLastError();
    context.Response.Clear();
    context.ClearError();
    var httpException = ex as HttpException;

    var routeData = new RouteData();
    routeData.Values["controller"] = "errors";
    routeData.Values["exception"] = ex;
    routeData.Values["action"] = "http500";
    if (httpException != null)
    {
        switch (httpException.GetHttpCode())
        {
            case 404:
                routeData.Values["action"] = "http404";
                break;
            case 403:
                routeData.Values["action"] = "http403";
                break;
            case 500:
                routeData.Values["action"] = "http500";
                break;
        }
    }
    IController controller = new ErrorsController();
    controller.Execute(new RequestContext(new HttpContextWrapper(context), routeData));
}

And now all that's left is to start throwing proper exceptions:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        throw new HttpException(404, "NotFound");
    }
}

For HTTP 404 errors (without redirects) take a look at my blog post on the subject. This might give you some good ideas:

http://hectorcorrea.com/blog/returning-http-404-in-asp-net-mvc/16

This doesn't answer your question, but it is important to note that HTTP status 500 indicates that something went wrong on the server, so your example:

POST /User/New/new-user-name-too-long-for-db-column-constraint

Is not valid grounds to throw a 500, its a data validation issue and should be handled by MVC data annotations or a jQuery validation framework or etc. Just showing an error message next to the TextBox saying "User Name too long" is much better.

This is a very old question. but I thought It's worth it if I introduce you to a much much cleaner way to handle Http Exceptions that I saw in dear "Jesse Webb's answer".

The solution is to use the httpErrors element of the system.webServer section:

<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="-1" />
  <remove statusCode="500" subStatusCode="-1" />
  <error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
  <error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>

You also can log all exceptions in this way. "Read the "Jesse Webb's answer"".

This really feels much cleaner and also works as well as every other solution (without redirect).

Note: This only works work in IIS 7 and and newer. (Because of the httpErrors element which was recently added.

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