【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

 

爽歪歪

 

posted @ 2018-10-18 09:58  0539  阅读(4304)  评论(7编辑  收藏  举报