Problem description:
I am triing to create attributes, that define how to handle exceptions in my ASP.NET MVC 4 controllers, and actions. Specifically they would set the result what to return to the server. I have almost achieved the desired effect, but there is a problem with call orders. Here is an example of what I am doing currently:
[DefaultExceptionHandler]
public abstract class BaseController
{
}
public abstract class AuthorizeController : BaseController
[VeryGoodExceptionHandler]
public class VeryGoodController : AuthorizeController
{
[ViewPageExceptionHandler]
public ActionResult ViewPage()
{
throw new Exception(); //Just for demonstration
return View();
}
public ActionResult ActionWithoutAttribute()
{
return View();
}
}
This is the basic structure of my controllers. The attributes are all descendants of the following class:
public abstract class ExceptionHandlerAttributeBase : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.Result = CreateExceptionResult(filterContext.Exception);
}
protected abstract ActionResult CreateExceptionResult(Exception e);
}
CreateExceptionResult can return a JsonResult, a View, a StatusCodeResult, whatever you wish. In my case it always receives a special exception type (Some Enterprise Library magic), but that is not a necessity.
The attribute works very nicely, I put it over something, and the OnException method gets called like it should, putting the proper ActionResult in the filterContext, and sending it back to the client. The problem starts, when I want to override the attribute. It happens, that every OnException methods get called, with the same context. When only the controllers are decorated, everything is (almost) fine, at first, the one put over BaseController gets called, then the one over "VeryGoodController", overriding the result. It would be nice to get rid of the base call, but whatever. In the case of the Action, and the controllers decorated, the calling order happens to be: the action attribute's OnException (setting the desired result), the base controller's OnException, and the child controller's OnException (overriding the desired result). ExceptionContext doesn't have any attributes to use as a flag for further processing (Maybe the Exception attribute could be set to null, but that's not something I'd do).
QUESTION: So the question is how can I get to a) get the OnException method of the Action to be called last, and/or if possible b) deny the less specific methods from being called (in a more efficient way, then just have their result overwritten)?
Some extra info: I have used this answer as a reference. Also, if I register the filter in the way described in this post, and do not add the attributes, the same happens.
Thanks in advance, Robert
OnExceptionmethod call. I think you can solve it there. - Venemo