Search code examples
asp.net-mvcasp.net-coreexceptionfilterattribute

Return to original view from MVC action filter


Im working on a asp.net core website and im trying to make som global validation exception handling using Filters. The backend can at random places throw fluentapi ValidationException and I want to catch these and show the error messages to the user. This filter only cares about ValidationExceptions. All other exceptions will be handled later..

Instead of using a try/catch in every post action in all my controllers, I want to use a filter that catches only ValidationExceptions, add the errors to the ModelState and then return to the original view with the updated ModelState.

I have tried many things but every time I just get a blank page after the filter finishes. I can easily set a new RedirectToRouteResult witht the controller and action from the context. But then I dont have the ModelState and values the user entered..

public class PostExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        if (context.Exception is FluentValidation.ValidationException)
        {
            var ex = context.Exception as FluentValidation.ValidationException;
            context.Exception = null;
            context.HttpContext.Response.StatusCode = 200;
            context.ExceptionHandled = true;
            foreach (var item in ex.Errors.ToList())
            {
                context.ModelState.AddModelError(item.PropertyName, item.ErrorMessage);
            }

            // Done with the stuff I want.
            // Now please go back to the original view with the updated modelstate and values
        }
        else if (context.Exception is UnauthorizedAccessException)
        {
            // Do something else...
        }
        else
        {
            // Do something else...
        }
        base.OnException(context);
    }
}

Solution

  • You cannot access the particlar Model(related to Action Method) in Exception Filters. So you have to handle the error at Controller level if you want to add Errors to model.

    try
    {
        //Do something
    }
    Catch(Exception e)
    {
        ModelState.AddModelError(string key, string errorMessage);
        Return View(model)
    }
    

    The error message will present itself in the <%: Html.ValidationSummary() %> in your View

    Without try-catch blocks you won't know if exception occured in Action Method, So that you can add Custom Errors to Model.