Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 861|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-10 22:03:57 | 显示全部楼层 |阅读模式

     

    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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 17:19 , Processed in 0.058081 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表