• .NET Core通过过滤器和中间件两种方式实现全局异常捕获和日志记录


    1.一共有五类过滤器IAsyncAuthorizationFilter  IAsyncResourceFilter   IAsyncActonFilter  IAsyncExceptionFilter    IAsyncResultFilter 去掉Async就是同步的

    2.注册过滤器  全局注册和Attribute注册 用在特定的Action上

    通过过滤器实现全局异常处理

    1.建立自己的一个过滤器

    public class CustomerExceptionFilter : Attribute, IExceptionFilter
    {
        private readonly ILogger logger = null;
        private readonly IHostingEnvironment environment = null;
        public CustomerExceptionFilter(ILogger<CustomerExceptionFilter> logger, IHostingEnvironment environment)
        {
            this.logger = logger;
            this.environment = environment;
        }
    
        public void OnException(ExceptionContext context)
        {
            Exception exception = context.Exception;
            string error = string.Empty;
    
            void ReadException(Exception ex)
            {
                error += string.Format("{0} | {1} | {2}", ex.Message, ex.StackTrace, ex.InnerException);
                if (ex.InnerException != null)
                {
                    ReadException(ex.InnerException);
                }
            }
    
            ReadException(context.Exception);
            logger.LogError(error);
    
            ContentResult result = new ContentResult
            {
                StatusCode = 500,
                ContentType = "text/json;charset=utf-8;"
            };
    
            if (environment.IsDevelopment())
            {
                var json = new { message = exception.Message, detail = error };
                result.Content = JsonConvert.SerializeObject(json);
            }
            else
            {
                result.Content = "抱歉,出错了";
            }
            context.Result = result;
            context.ExceptionHandled = true;
        }
    }

    2.添加Nugut包 NLog.Extensions.Logging   NLog.Web.AspNetCore ,并在 Startup.cs 文件的 Configure 方法中添加扩展

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory)
            {
                // 将 NLog
                factory.AddConsole(Configuration.GetSection("Logging"))
                       .AddNLog()
                       .AddDebug();
    
                var nlogFile = System.IO.Path.Combine(env.ContentRootPath, "nlog.config");
                env.ConfigureNLog(nlogFile);
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseMvc();
            }

    3.日志配置文件信息

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="info">
    
      <!-- Load the ASP.NET Core plugin -->
      <extensions>
        <add assembly="NLog.Web.AspNetCore"/>
      </extensions>
    
      <!-- Layout: https://github.com/NLog/NLog/wiki/Layout%20Renderers -->
      <targets>
        <target xsi:type="File" name="errorfile" fileName="/data/logs/logfilter/error-${shortdate}.log" layout="${longdate}|${logger}|${uppercase:${level}}|  ${message} ${exception}|${aspnet-Request-Url}" />
        <target xsi:type="Null" name="blackhole" />
      </targets>
    
      <rules>
        <logger name="Microsoft.*" minlevel="Error" writeTo="blackhole" final="true" />
        <logger name="*" minlevel="Error" writeTo="errorfile" />
      </rules>
    </nlog>

    4.把这个过滤器注入到容器中

                services.AddMvc(
                    options =>
                    {
                        options.Filters.Add(typeof(CustomerExceptionFilter));
                    })
                    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    只要请求进入到了MVC中间件中之后抛的异常 都会进到自定义的Filter中

    ************************

    通过中间件实现全局异常处理

    1.建立一个自定义的全局异常处理中间件

        public class ExceptionMiddleware
        {
            private readonly RequestDelegate next;
            private readonly ILogger logger;
            private IHostingEnvironment environment;
    
            public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger, IHostingEnvironment environment)
            {
                this.next = next;
                this.logger = logger;
                this.environment = environment;
            }
    
            public async Task Invoke(HttpContext context)
            {
                try
                {
                    await next.Invoke(context);
                    var features = context.Features;
                }
                catch (Exception e)
                {
                    await HandleException(context, e);
                }
            }
    
            private async Task HandleException(HttpContext context, Exception e)
            {
                context.Response.StatusCode = 500;
                context.Response.ContentType = "text/json;charset=utf-8;";
                string error = "";
    
                void ReadException(Exception ex)
                {
                    error += string.Format("{0} | {1} | {2}", ex.Message, ex.StackTrace, ex.InnerException);
                    if (ex.InnerException != null)
                    {
                        ReadException(ex.InnerException);
                    }
                }
    
                ReadException(e);
                if (environment.IsDevelopment())
                {
                    var json = new { message = e.Message, detail = error };
                    error = JsonConvert.SerializeObject(json);
                }
                else
                    error = "抱歉,出错了";
    
                await context.Response.WriteAsync(error);
            }
        }

    2.在管道中加入自定义中间件

    app.UseMiddleware<ExceptionMiddleware>();

    2.在管道中通过try catch进行异常捕获      这个中间件后面的所有代码都在 try catch里面 只要出发了异常  就会给当前中间件捕获   

       注意   在某个中间件中发生了异常  但是他抛出的时候  在当前中间件就处理掉了  没有继续往上抛出   这时候就捕获不到

     

    https://www.cnblogs.com/viter/p/10013195.html

  • 相关阅读:
    OpenCV之图像归一化(normalize)
    虚拟机网络模式说明
    大端模式和小端模式
    ASCII、Unicode、UTF-8、UTF-8(without BOM)、UTF-16、UTF-32傻傻分不清
    MFC窗口通过OpenCV显示图片
    基于FFmpeg的Dxva2硬解码及Direct3D显示(五)
    PyQt5播放实时视频流或本地视频文件
    PyQt5信号与槽关联的两种方式
    PyCharm离线安装PyQt5_tools(QtDesigner)
    DC: 8
  • 原文地址:https://www.cnblogs.com/jiangchengbiao/p/10482979.html
Copyright © 2020-2023  润新知