[英]ASP.Net Core exception handling middleware
I am trying to use middleware for exception handling in my ASP.Net Core 3.0 Web API project:我正在尝试在我的 ASP.Net Core 3.0 Web API 项目中使用中间件进行异常处理:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
await HandleException(context, ex);
}
}
private static Task HandleException(HttpContext context, Exception ex)
{
HttpStatusCode code = HttpStatusCode.InternalServerError; // 500 if unexpected
// Specify different custom exceptions here
if (ex is CustomException) code = HttpStatusCode.BadRequest;
string result = JsonConvert.SerializeObject(new { error = ex.Message });
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return context.Response.WriteAsync(result);
}
}
startup.cs启动.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add controllers with a route prefix
services.AddControllers(x => { x.UseGeneralRoutePrefix($"api/v{Configuration["APIVersion"]}"); });
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v0.1", new OpenApiInfo { Title = "My API", Version = "v0.1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v0.1/swagger.json", "My API V1");
});
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Controller Controller
[HttpPost]
public ActionResult Method()
{
if (condition)
throw new CustomException();
else
return Ok();
}
but the exception thrown in the controller doesn't get handled by the middleware.但是 controller 中抛出的异常不会被中间件处理。 What would be the correct way to use the middleware?
使用中间件的正确方法是什么?
It seems that看起来
app.UseDeveloperExceptionPage();
was preventing the exception handling middleware from catching exceptions.正在阻止异常处理中间件捕获异常。 Removing it solves the problem.
删除它可以解决问题。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(ApiConstantVars.AZURE_POLICY);
app.UseCors(ApiConstantVars.CORS_POLICY_NAME);
app.UseAuthentication();
app.UseMvc();
app.Run(
async context =>
{
var handler = context.Features.Get<Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature>();
if (handler != null && handler.Error != null)
{
var errorModel = new OperationResult
{
IsSuccess = false,
};
//Handle the JSON request to respond in its origin format
if (context.Request.ContentType.ToUpper().IndexOf("JSON") != -1)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = 400; //Set the Status Code to responde JSON Failed requests
await context.Response
.WriteAsync(Newtonsoft.Json.JsonConvert.SerializeObject(new { error = "Unhandled internal error", success = false, origin = context.Request.Path }))
.ConfigureAwait(false);
}
else
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
await context.Response.WriteAsync(Newtonsoft.Json.JsonConvert.SerializeObject(handler.Error.Message))
.ConfigureAwait(false);
}
}
else
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
await context.Response
.WriteAsync(Newtonsoft.Json.JsonConvert.SerializeObject(new { message = "Unhandled internal error" }))
.ConfigureAwait(false);
}
});
}
app.UseMiddleware<ErrorHandlingMiddleware>();
I think you should use it this way.我认为您应该以这种方式使用它。 Add this line to the Configure method
将此行添加到 Configure 方法
public class ExceptionHandlerMiddleware{
private readonly RequestDelegate _next;
public ExceptionHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context).ConfigureAwait(false);
}
catch (Exception)
{
await HandleExceptionAsync(context).ConfigureAwait(false);
}
}
private static Task HandleExceptionAsync(HttpContext context)
{
var result = JsonConvert.SerializeObject(new
{
StatusCode = 500,
Message = "Internal Server Error",
Data = string.Empty,
Status = "Failed"
});
context.Response.ContentType = "application/json";
context.Response.StatusCode = 500;
return context.Response.WriteAsync(result);
}
}
// for extension method
public static class ExceptionHandlerMiddlewareExtensions
{
public static void UseExceptionHandlerMiddleware(this IApplicationBuilder app)
{
app.UseMiddleware<ExceptionHandlerMiddleware>();
}
}
// use it like below
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
// your code
if (env.IsDevelopment()) // if want to use in development too
{
app.UseExceptionHandlerMiddleware();
}
else
{
app.UseExceptionHandlerMiddleware();
}
// your code
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.