开发者

Error handling in MVC

I've struggled a couple of days with the error handling in MVC. I still do not have got it right. (I've also read most of the questions here at SO and googled until my fingers bled)

What I want to do:

  1. Use the standard [Authorize] attribute
  2. Redirect all errors to my error controller (including unauthorized)
  3. Have one action per HTTP error in my error controller.

What I do not want to do:

  1. Put the [ErrorHandler] on all of my controllers (can it be used on my base controller)?
  2. Use a custom Authorize attribute.

Actually I could do anything necessary (including the NOT list) as long as I get #1-3 working开发者_C百科.

What I've tried:

  1. Using Application_Error
  2. Using Controller.HandleUnknownAction
  3. Using Controller.OnException
  4. Using [ErrorHandler] on my controllers
  5. Turning on/off CustomErrors in web.config

Guess I need a combination of those or maybe something else?


You could also handle all your error logic in the Application_Error of your Global.asax.cs and then route them dynamically bases on the different HTTP status codes:

protected void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError().GetBaseException();

    var routeData = new RouteData();

    if (ex.GetType() == typeof(HttpException))
    {
        var httpException = (HttpException)ex;

        switch (httpException.GetHttpCode())
        {
            case 401:
                routeData.Values.Add("action", "NotAuthorized");
                break;
            case 403:
                routeData.Values.Add("action", "NotAuthorized");
                break;
            case 404:
                routeData.Values.Add("action", "PageNotFound");
                break;
            default:
                routeData.Values.Add("action", "GeneralError");
                break;
        }
    }
    else
    {
        routeData.Values.Add("action", "GeneralError");
    }

    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("error", ex);

    IController errorController = new ErrorController();
    errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}

It seems the 401 doesn't throw necessary a HttpException so you want to handle that manually to fit the logic:

protected void Application_EndRequest(object sender, EventArgs e)
{
    if (Context.Response.StatusCode == 401)
    {
        throw new HttpException(401, "You are not authorised");
    }
}

And yes, your controllers inherit the attributes from your base conroller.


You can use a custom filter, just extend ErrorHandlerAttribute and make it aware of your error controller. Than add it as a global filter inside Application_Start:

GlobalFilters.Filters.Add(new CustomAErrorHandlerAttribute());


The proper way is not to use Application_Error. The proper way is to use [HandleError] attribute in combination with the customErrors section in web.config as I describe here:

http://blog.gauffin.org/2011/11/how-to-handle-errors-in-asp-net-mvc/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜