.NET Core中使用NLog之中间件(Middleware)和过滤器(Filter)

接着上篇,咋们咋会聊聊Middleware这个类似Filter的东西,为什么说类似了,因为他们功能类似,但是过滤器和中间件他们的关注点是不一样的,也就是说职责不一样,干的事情就不一样。

同作为两个AOP利器;Filter(过滤器)更贴合业务,它关注于应用程序本身,比如你看ActionFilter 和 ResultFilter,它都直接和你的ActionActionResult交互了,比如对输出结果进行格式化,对请求的ViewModel进行数据验证啦,肯定就是用Filter无疑了。它是MVC的一部分,它可以拦截到你Action上下文的一些信息,而中间件是没有这个能力的;而每一个Middleware(中间件)都都可以在请求之前和之后进行操作。请求处理完成之后传递给下一个请求,一般用在比如身份验证,Session存储,日志记录等。其实我们的 Asp.net core项目中本身已经包含了很多个中间件。比如 身份认证中间件 UseAuthorization()等系列。

接着咋们做个实际例子一起看看,应用场景如下:

通过后端记录每一次的访问请求日志,同时需要根据需要排除一些Controller 或者Action 不记录请求的日志信息。

思考:经过分析我需要创建一个全局的中间件进行拦截路由,并且写入日志;同时需要添加一个特性Attribute 进行标注那些Controller或者Action 不需要进行日志记录。

1、创建Middleware文件夹,在当前文件夹下创建中间件类LogsMiddleware,记录日志,如下图:

 

 LogsMiddleware代码如下:

public class LogsMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly INLogHelper _logHelper;
        public LogsMiddleware(RequestDelegate next, INLogHelper logHelper)
        {
            _next = next;
            _logHelper = logHelper;
        }

        public async Task Invoke(HttpContext context)
        {
            var endpoint = context.Features.Get<IEndpointFeature>()?.Endpoint;
            if (endpoint == null)
            {
                await _next(context);
                return;
            }

            using (var scope = context.RequestServices.CreateScope())
            {
                //var _logger = scope.ServiceProvider.GetService<ILogger<LogsMiddleware>>();

                var attruibutes = endpoint.Metadata.OfType<NoLogsAttriteFilter>();
                if (attruibutes.Count() <= 0)
                {
                    //_logger.LogInformation($" url:{context.Request.Path}, 访问时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                    _logHelper.LogInfo($" url:{context.Request.Path}, 访问时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                }

                //记录 排除的特殊Message 信息
                foreach (var attribute in attruibutes)
                {
                    //_logger.LogInformation(attribute.Message);
                    _logHelper.LogInfo(attribute.Message);
                }

            }

            await _next(context);
        }
    }
View Code

 

2、在Filter文件下创建过滤器NoLogsAttriteFilter继承Attribute,拦截路由不需要记录日志的action,如下图:

 

 NoLogsAttriteFilter代码如下:

public class NoLogsAttriteFilter : Attribute
    {
        /// <summary>
        /// 这里加这个主要是把获取到的信息在中间件中打印出来,区分中间件的拦截用处
        /// </summary>
        public string Message = "";

        public NoLogsAttriteFilter(string message)
        {
            Message = message;
        }
    }
View Code

 

3、修改Startup 中Configure的代码如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseEndpointRouting();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseMiddleware<LogsMiddleware>();//添加日志记录中间件
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

        }
View Code

关键修改内容:

添加日志记录中间件  ===> app.UseMiddleware<LogsMiddleware>();

手动调用UseEndpointRouting ===>app.UseEndpointRouting();

4、HomeController 控制器中的两个Action 代码如下:

 

 

5、运行项目查看日志,测试两个action的日志中间件结果:

 

 

 以上就是Filter和Middleware简单介绍的实例使用,以此记录加深个人印象的同时也希望能帮助到有需要的博友!!!

posted @ 2021-07-28 16:11  HI_Hub_MI  阅读(860)  评论(1编辑  收藏  举报