ASP.NET Core ModelState Validation Filter

ASP.NET Core ModelState Validation Filter

I like my ASP.NET Core controllers and actions very clean and I recommend to not catch all Exceptions inside your Action.

You can have it much easier and simplier - with your custom Exception Middleware.

For exemaple I want to catch all NotImplementedException (I hope you do not have any of them in your final code) and return the HTTP status code 501 (HttpStatusCode.NotImplemented) I can just use this middleware implementation:

    public class NotImplementedExceptionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<NotImplementedExceptionMiddleware> _logger;

        public NotImplementedExceptionMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
        {
            _next = next ?? throw new ArgumentNullException(nameof(next));
            _logger = loggerFactory?.CreateLogger<NotImplementedExceptionMiddleware>() ?? throw new ArgumentNullException(nameof(loggerFactory));
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (NotImplementedException ex)
            {
                if (!context.Response.HasStarted)
                {
                    int errorCode = (int)HttpStatusCode.NotImplemented;

                    context.Response.Clear();
                    context.Response.StatusCode = errorCode;
                    context.Response.ContentType = "application/json";

                    // this is a sample error result object
                    ErrorResult error = new ErrorResult("Not implemented", ex.Message);
                    await context.Response.WriteAsync(error.ToJson());
                }
            }
        }
    }
A simple extention to register the middleware cleaner:

    public static class NotImplementedExceptionMiddlewareExtensions
    {
        public static IApplicationBuilder UseNotImplementedExceptionMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<NotImplementedExceptionMiddleware>();
        }
    }

And register this middleware:

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IPingPongService pingPongService)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        // Use Middleware
        app.UseNotImplementedExceptionMiddleware();

        app.UseMvc(); 
    }

Done.