Home > OS >  How to access ModelState in UseExceptionHandler
How to access ModelState in UseExceptionHandler

Time:12-23

I have domain service that throws a custom DomainServiceValidationException for a business validation. I want to globally capture the exception and return in ModelState. My current working solution is using ExceptionFilterAttribute

public class ExceptionHandlerAttribute : ExceptionFilterAttribute
{
    private readonly ILogger<ExceptionHandlerAttribute> _logger;

    public ExceptionHandlerAttribute(ILogger<ExceptionHandlerAttribute> logger)
    {
        _logger = logger;
    }
    public override void OnException(ExceptionContext context)
    {
        
        if (context == null || context.ExceptionHandled)
        {
            return;
        }

       if(context.Exception is DomainServiceValidationException)  
       {
          context.ModelState.AddModelError("Errors", context.Exception.Message);
          context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
          context.Result = new BadRequestObjectResult(context.ModelState);
       }
       else
       {
            handle exception
       }
    }

}

I want to know if there is any way to access ModelState in UseExceptionHandler middleware

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime)
{            
        app.UseExceptionHandler(new ExceptionHandlerOptions()
        {
            ExceptionHandler = async (context) =>
            {
                var ex = context.Features.Get<IExceptionHandlerFeature>().Error;

               // how to access to ModelState here                        
                
            }
        });                
    }            
}

CodePudding user response:

Shorten answer:

No, you cannot access ModelState in UseExceptionHandler middleware.

Explanation:

Firstly you need to know ModelState is only available after Model Binding.

Then Model Binding invokes before Action Filters and after Resource Filters(See Figure 1). But Middleware invokes before Filters(See Figure 2).

Figure 1:

enter image description here

Figure 2:

enter image description here

Reference:

How Filters work

Conclusion:

That is to say, you can not get the ModelState in UseExceptionHandler middleware.

Workaround:

You can only store the ModelState automatically in Filters(Action Filters or Exception Filters or Result Filters), then you can use it within middleware.

app.UseExceptionHandler(new ExceptionHandlerOptions()
{
    ExceptionHandler = async (context) =>
    {
        var ex = context.Features.Get<IExceptionHandlerFeature>().Error;
        // how to access to ModelState here                        
        var data = context.Features.Get<ModelStateFeature>()?.ModelState;
    }
});

Reference:

How to store ModelState automatically

  • Related