There are basically 2 ways to handle exceptions as a cross-cutting concern
in asp.net core. One is by using IExceptionFilter
(IAsyncExceptionFilter
for async handling) and one is by using exception handler middleware. The exception filters are not able to handle all exceptions such as exception occurred in result execution (when serializing data, ...). So it's the most reliable to handle the exception using exception handler middleware.
You can find more about exception filter yourself, it's very easy to use for your scenario (targeting a specific controller) simply by decorating your controller class with an attribute. However here I would like to introduce how you can handle it using exception handler middleware which can be configured in the Configure
method of the Startup
class. Here we use IExceptionHandlerFeature
to get the exception info (if any):
//exception handler for errors in other controllers & pages ...
app.UseExceptionHandler("/Error");
//exception handler for specific controllers
app.MapWhen(context => {
var controller = context.GetRouteValue("controller")?.ToString();
return controller?.ToLower() == "your_controller_name";
}, subApp => {
subApp.Run(async context =>
{
var exceptionHandlerFeature = context.Features.Get<IExceptionHandlerFeature>();
var exception = exceptionHandlerFeature?.Error;
if (exception != null)
{
//prepare the error by your own
var error = new { Messsage = exception.Message };
context.Response.ContentType = "application/json";
//set status code of your choice
//context.Response.StatusCode = ;
//write JSON response containing the error
await context.Response.WriteAsync(JsonSerializer.Serialize(error));
}
});
});
Note we use MapWhen
to switch the pipeline to a terminal middleware (configured by subApp
). That terminal middleware will intercept the request from being further processed by the other middlewares after it in the processing flow. You can see that the order of placing the UseExceptionHandler
for other cases is important. It must be placed before the MapWhen
due to how the middlewares are built along the request processing pipeline.
You can also create your own custom middelware into a separate class (following either convention-based or factory-based approach).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…