中间件-异常处理

带着问题去思考!大家好!

处理异常的方式有

  • 1:异常处理页
  • 2:异常处理匿名委托方法
  • 3:IExceptionFilter
  • 4:ExceptionFilterAttribut
    public class ErrorHandlerStartup : IStartup
        {
            /// <summary>
            /// Add and configure any of the middleware
            /// </summary>
            /// <param name="services">Collection of service descriptors</param>
            /// <param name="configuration">Configuration root of the application</param>
            public void ConfigureServices(IServiceCollection services, IConfiguration configuration, ITypeFinder typeFinder)
            {
            }
    
            /// <summary>
            /// Configure the using of added middleware
            /// </summary>
            /// <param name="application">Builder for configuring an application's request pipeline</param>
            public void Configure(IApplicationBuilder application)
            {    
                //异常处理
                application.UseExceptionHandler();
                //400处理
                application.UseBadRequestResult();
                //404处理
                application.UsePageNotFound();
            }
    
        

 这里我们可以 新创建一个Startup,实现我们定义的IStartup接口,接口的定义主要是为了实现其他的服务注册和配置应用程序请求管道(IApplicationBuilder)。

 /// <summary>
    /// 配置应用程序启动时异常处理中间件
    /// </summary>
    public class ErrorHandlerStartup : IStartup
    {
        /// <summary>
        /// Add and configure any of the middleware
        /// </summary>
        /// <param name="services">Collection of service descriptors</param>
        /// <param name="configuration">Configuration root of the application</param>
        public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
        {
        }
        /// <summary>
        /// Configure the using of added middleware
        /// </summary>
        /// <param name="application">Builder for configuring an application's request pipeline</param>
        public void Configure(IApplicationBuilder application)
        {    
            //异常处理
            application.UseExceptionHandler();
            //400处理
            application.UseBadRequestResult();
            //404处理
            application.UsePageNotFound();
        }
    }

 

这里的三个方法分别实现了以上处理方式

第一个方法我们实现了IApplicationBuilder的UseExceptionHandler

1:这里具体我们通过Run来进行启动

2:通过HttpContext的IFeatureCollection(表示HTTP特性的集合) 来获取Error

application.UseExceptionHandler(handler =>
            {
                handler.Run(async context =>
                {
                    var exception = context.Features.Get<IExceptionHandlerFeature>()?.Error;
                    if (exception != null)
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "application/json";
                        string errorMsg = "程序访问异常,请稍后重试!";

                        string requestPara = string.Empty;
                        var request = context.Request;
                        var method = request.Method.ToUpper();
                        if (method == "POST" || method == "PUT" || method == "DELETE")
                        {
                            request.Body.Position = 0;
                            using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8))
                            {
                                requestPara = reader.ReadToEnd();
                            }
                        }
                        int errorCode = 1;
                        string requestId = string.Empty;

                        
                        //写入日志系统
                        
                        //自定义异常返回
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(new ApiResultModel()
                        {
                            ErrorCode = errorCode,
                            Msg = errorMsg
                        })).ConfigureAwait(false);
                    }
                });
            });
View Code

第二个方法IApplicationBuilder的UseStatusCodePages(添加带有给定选项的StatusCodePages中间件,用于检查状态代码在400到599之间且没有正文的响应。)来实现

application.UseStatusCodePages(context =>
            {
                //handle 404 (Bad request)
                if (context.HttpContext.Response.StatusCode == StatusCodes.Status400BadRequest)
                {
                    var logger = EngineContext.Current.Resolve<ILogger>();
                    logger.Error($"Error 400. Bad request,{context.HttpContext.Request.Path.Value}");
                }

                return Task.CompletedTask;
            });
View Code

第三种我们通过IApplicationBuilder的UseStatusCodePages

application.UseStatusCodePages(async context =>
            {
                //handle 404 Not Found
                if (context.HttpContext.Response.StatusCode == StatusCodes.Status404NotFound)
                {
                    var webHelper = EngineContext.Current.Resolve<IWebHelper>();
                    if (!webHelper.IsStaticResource())
                    {
                        //get original path and query
                        var originalPath = context.HttpContext.Request.Path;
                        var originalQueryString = context.HttpContext.Request.QueryString;

                        //store the original paths in special feature, so we can use it later
                        context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
                        {
                            OriginalPathBase = context.HttpContext.Request.PathBase.Value,
                            OriginalPath = originalPath.Value,
                            OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
                        });
//404页面
                        string pageNotFoundUrl="";
                        if (string.IsNullOrWhiteSpace(pageNotFoundUrl))
                        {
                            return;
                        }
                        context.HttpContext.Request.Path = pageNotFoundUrl;
                        context.HttpContext.Request.QueryString = QueryString.Empty;
                        try
                        {
                            //re-execute request with new path
                            await context.Next(context.HttpContext);
                        }
                        finally
                        {
                            //return original path to request
                            context.HttpContext.Request.QueryString = originalQueryString;
                            context.HttpContext.Request.Path = originalPath;
                            context.HttpContext.Features.Set<IStatusCodeReExecuteFeature>(null);
                        }
                    }
                }
            });
View Code
posted @ 2020-05-29 14:24  梦一回  阅读(551)  评论(0编辑  收藏  举报