【netcore基础】MVC API全局异常捕捉中间件ExceptionHandlerMiddleWare
项目中想通过统一的接口格式返回异常信息,而不是404 500等HTTP协议层的异常响应
例如
{ "status":0, "code":0, "message":"用户名或密码不正确", "detail":"", "data":null }
我们需要引用一个异常处理中间件,ExceptionHandlerMiddleWare
代码如下
using GeduData.Server; using GeduService.Resp; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System; using System.IO; using System.Net; using System.Threading.Tasks; using System.Xml.Serialization; namespace GeduDistributionApi.Extension { public class ExceptionHandlerMiddleWare { private readonly RequestDelegate next; public ExceptionHandlerMiddleWare(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context) { try { await next(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private static async Task HandleExceptionAsync(HttpContext context, Exception exception) { if (exception == null) { return; } await WriteExceptionAsync(context, exception).ConfigureAwait(false); } private static async Task WriteExceptionAsync(HttpContext context, Exception exception) { //返回友好的提示 HttpResponse response = context.Response; //状态码 int nCode = 0; if (exception is GeduException) { nCode = ((GeduException)exception).Code; } else if (exception is Exception) { nCode = 500; } response.ContentType = context.Request.Headers["Accept"]; ExceptionResp resp = new ExceptionResp { Status = 0, Code = nCode, Message = exception.Message, }; response.ContentType = "application/json"; await response.WriteAsync(JsonConvert.SerializeObject(resp)).ConfigureAwait(false); } /// <summary> /// 对象转为Xml /// </summary> /// <param name="o"></param> /// <returns></returns> private static string Object2XmlString(object o) { StringWriter sw = new StringWriter(); try { XmlSerializer serializer = new XmlSerializer(o.GetType()); serializer.Serialize(sw, o); } catch { //Handle Exception Code } finally { sw.Dispose(); } return sw.ToString(); } } }
这里的黄色标注的部分就是我想要接口返回的json对象结构,可自定义
有了这个中间件,我们在Startup.cs里的Configure方法进行配置即可
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseCors("AllowSpecificOrigin"); app.MapWhen( context => context.Request.Path.ToString().EndsWith(".report"), appBranch => { appBranch.UseUeditorHandler(); }); app.UseHttpsRedirection(); //异常处理中间件 app.UseMiddleware(typeof(ExceptionHandlerMiddleWare)); app.UseMvc(); //https://localhost:5001/swagger/ app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); app.UseHangfireServer(); app.UseHangfireDashboard(); app.UseStaticFiles(); }
这样,在接口的业务逻辑里,无论有什么异常抛出,我们都可以统一通过中间件进行处理,返回指定格式的json内容
这里还可以定义自己业务逻辑异常,以便区分系统Exception
爽歪歪