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:
[Authorize]
attributeWhat I do not want to do:
[ErrorHandler]
on all of my controllers (can it be used on my base controller)?Actually I could do anything necessary (including the NOT list) as long as I get #1-3 working.
What I've tried:
Application_Error
Controller.HandleUnknownAction
Controller.OnException
[ErrorHandler]
on my controllersCustomErrors
in web.configGuess I need a combination of those or maybe something else?
Summary on MVC Error Handling config <customErrors> and log unhandled exceptions that get called back to your HttpApplication Error method. You can use HandleErrorAttribute or OnException to provide fine-grained control of how you display error type messages to your users.
Error handling refers to the response and recovery procedures from error conditions present in a software application. In other words, it is the process comprised of anticipation, detection and resolution of application errors, programming errors or communication errors.
You can propagate the error from a function to the code that calls that function, handle the error using a do - catch statement, handle the error as an optional value, or assert that the error will not occur.
Exception filter in MVC provides an ability to handle the exceptions for all the controller methods at a single location. This is by creating a class, which inherits from the FilterAttribute and IExceptionFilter interface.
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With