.NET Core MVC中间件使用记录日志


中间件是一种装配到应用管道以处理请求和响应的软件。 每个组件:

  • 选择是否将请求传递到管道中的下一个组件。
  • 可在管道中的下一个组件前后执行工作。

请求委托用于生成请求管道。 请求委托处理每个 HTTP 请求。

使用 RunMap 和 Use 扩展方法来配置请求委托。 可将一个单独的请求委托并行指定为匿名方法(称为并行中间件),或在可重用的类中对其进行定义。 这些可重用的类和并行匿名方法即为中间件,也叫中间件组件。 请求管道中的每个中间件组件负责调用管道中的下一个组件,或使管道短路。 当中间件短路时,它被称为“终端中间件”,因为它阻止中间件进一步处理请求。

将 HTTP 处理程序和模块迁移到 ASP.NET Core 中间件介绍了 ASP.NET Core 和 ASP.NET 4.x 中请求管道之间的差异,并提供了更多的中间件示例。

官网介绍地址:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-6.0 

 

C# 全选
using Coldairarrow.Util;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Coldairarrow.Api
{
    public class RequestLogMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        public RequestLogMiddleware(RequestDelegate next, ILogger<RequestLogMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            Stopwatch watch = Stopwatch.StartNew();
            string resContent = string.Empty;

            //返回Body需特殊处理
            Stream originalResponseBody = context.Response.Body;
            using var memStream = new MemoryStream();
            context.Response.Body = memStream;

            try
            {
                await _next(context);

                memStream.Position = 0;
                resContent = new StreamReader(memStream).ReadToEnd();

                memStream.Position = 0;
                await memStream.CopyToAsync(originalResponseBody);
            }
            catch
            {
                throw;
            }
            finally
            {
                context.Response.Body = originalResponseBody;

                watch.Stop();

                if (resContent?.Length > 1000)
                {
                    resContent = new string(resContent.Copy(0, 1000).ToArray());
                    resContent += "......内容太长已忽略";
                }

                string log =
            @"方向:请求本系统
Url:{Url}
Time:{Time}ms
Method:{Method}
ContentType:{ContentType}
Body:{Body}
StatusCode:{StatusCode}
Response:{Response}
";
                _logger.LogInformation(
                    log,
                    context.Request.Path,
                    (int)watch.ElapsedMilliseconds,
                    context.Request.Method,
                    context.Request.ContentType,
                    context.RequestServices.GetService<RequestBody>().Body,
                    context.Response.StatusCode,
                    resContent
                    );
            }
        }
    }
}

 

C# 全选
using Coldairarrow.Util;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Text;
using System.Threading.Tasks;

namespace Coldairarrow.Api
{
    public class RequestBodyMiddleware
    {
        private readonly RequestDelegate _next;

        public RequestBodyMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            if ((context.Request.ContentType ?? string.Empty).Contains("application/json"))
            {
                context.Request.EnableBuffering();
                string body = await context.Request.Body?.ReadToStringAsync(Encoding.UTF8);
                context.RequestServices.GetService<RequestBody>().Body = body;
            }

            await _next(context);
        }
    }
}

 

C# 全选
using Coldairarrow.Util;

namespace Coldairarrow.Api
{
    public class RequestBody : IScopedDependency
    {
        public string Body { get; set; }
    }
}

 

使用:

startUp.cs中

app.UseMiddleware<T>()

C# 全选
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //跨域
            app.UseCors(x =>
                {
                    x.AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .DisallowCredentials();
                })
                .UseForwardedHeaders(new ForwardedHeadersOptions
                {
                    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
                })
                .UseMiddleware<RequestBodyMiddleware>()
                .UseMiddleware<RequestLogMiddleware>()
                .UseDeveloperExceptionPage()
                .UseStaticFiles(new StaticFileOptions
                {
                    ServeUnknownFileTypes = true,
                    DefaultContentType = "application/octet-stream"
                })
                .UseRouting()
                .UseAuthentication()
                .UseAuthorization()
                .UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers().RequireAuthorization();
                })
                .UseOpenApi()//添加swagger生成api文档(默认路由文档 /swagger/v1/swagger.json)
                .UseSwaggerUi3()//添加Swagger UI到请求管道中(默认路由: /swagger).
                ;
        }
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
张国生
上一篇:隐藏input文本框为数字number类型时的上下箭头
下一篇:ASP.NET Core统一接口返回模型
评论列表

发表评论

评论内容
昵称:
关联文章

.NET Core MVC中间使用记录
.NET Core 自定义中间 Middleware
.net core MVC 使用 jquery ajax请求 Post json
asp.net - 在 ASP.NET Core MVC 中嵌套 TagHelper
ASP.NET MVC和ASP.NET Core MVC中获取当前URL/Controller/Action
20210930 更新
20210908 更新
ASP.NET MVC使用@Url.Action 多个参数中间&被URL编码了
.NET6中一些常用组件的配置及使用记录,持续更新中。。。
.NET Core ResponseCache 浏览器缓存
.NET Core MVC 实现长时间任务的进度显示
ASP.NET Core MVC中的路由约束
在Winform项目和Web API的.NetCore项目中使用Serilog 来记录日志信息
使用.NET 6开发TodoList应用(12)——实现ActionFilter
YESWEB接口日志记录
.NETCore和.NET5 MVC使用 Session
ASP.NET MVC快速入门(一)
版本记录
.Net Core 5.x Api开发笔记 -- 基础日志(Log4Net)(八)
.net core MVC页面源码文件中文被编码

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码