.NET Core 3.0 中間件 Middleware


中間件官網文檔解釋:中間件是一種裝配到應用管道以處理請求和響應的軟件 每個中間件:

  • 選擇是否將請求傳遞到管道中的下一個組件。
  • 可在管道中的下一個組件前后執行工作。

使用 IApplicationBuilder 創建中間件管道

ASP.NET Core 請求管道包含一系列請求委托,依次調用。 下圖演示了這一概念。 沿黑色箭頭執行。

IApplicationBuilder提供了三個擴展方法配置請求委托

  • app.Run 作用添加一個終端中間件,因為不在向下傳遞請求,常常公開在管道末尾運行。實例代碼
  app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, middleware!");
        });
  • app.Use 將多個請求委托鏈接在一起。next 參數表示管道中的下一個委托。 可通過不 調用 next 參數使管道短路等同於aap.run。 通常可在下一個委托前后執行操作,如以下示例所示:
  app.Use(async (context, next) =>
        {
            // 傳遞前操作
            await next.Invoke();
            // 傳遞前操作
        });

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
  • Map 擴展用作約定來創建管道分支。 Map 基於給定請求路徑的匹配項來創建請求管道分支。 如果請求路徑以給定路徑開頭,則執行分支。實例代碼如下
  private static void HandleMapTest1(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 1");
        });
    }

    private static void HandleMapTest2(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 2");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1", HandleMapTest1);

        app.Map("/map2", HandleMapTest2);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
        });
    }

自定義中間件

以下演示記錄api輸入輸出參數的中間件。

1.創建一個webapi項目,在默認的WeatherForecastController控制器中添加一個簡單的post方法,代碼如下

 [HttpPost]
        public string PostWeatherForecast([FromBody]WeatherForecastA weatherForecastA)
        {
            return "添加成功";
        }
public class WeatherForecastA
    {
        public int TemperatureC { get; set; }
    }

2.新建一個中間件類.CS文件如圖

選擇之后默認代碼如下:

 // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
    public class LogReqResponseMiddleware
    {
        private readonly RequestDelegate _next;

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

        public Task Invoke(HttpContext httpContext)
        {

            return _next(httpContext);
        }
    }

    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class LogReqResponseMiddlewareExtensions
    {
        public static IApplicationBuilder UseLogReqResponseMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<LogReqResponseMiddleware>();
        }
    }

腳手架自動幫我們創建一個 Invoke方法,傳遞給下一個中間件。一個將自定義的中間件添加到了http請求管道的擴展方法UseLogReqResponseMiddleware。

上面invoke不是異步的,我們自己可以改動,以下代碼展示 一個api請求的輸入參數和輸出信息的日志打印

 // You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
    public class LogReqResponseMiddleware
    {
        private readonly RequestDelegate _next;

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

        public async Task Invoke(HttpContext httpContext, ILogger<LogReqResponseMiddleware> logger)
        {
            var request = httpContext.Request;
    request.EnableBuffering();
//把請求body流轉換成字符串  string bodyAsText = await new StreamReader(request.Body).ReadToEndAsync();//記錄請求信息 var requestStr = $"{request.Scheme} {request.Host}{request.Path} {request.QueryString} {bodyAsText}"; logger.LogDebug("Request:" + requestStr); request.Body.Seek(0, SeekOrigin.Begin); var originalBodyStream = httpContext.Response.Body; using (var responseBody = new MemoryStream()) { httpContext.Response.Body = responseBody; await _next(httpContext); var response = httpContext.Response; response.Body.Seek(0, SeekOrigin.Begin); //轉化為字符串 string text = await new StreamReader(response.Body).ReadToEndAsync(); //從新設置偏移量0 response.Body.Seek(0, SeekOrigin.Begin); //記錄返回值 var responsestr = $"{response.StatusCode}: {text}"; logger.LogDebug("Response:" + responsestr); await responseBody.CopyToAsync(originalBodyStream); } } } // Extension method used to add the middleware to the HTTP request pipeline. public static class LogReqResponseMiddlewareExtensions { public static IApplicationBuilder UseLogReqResponseMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<LogReqResponseMiddleware>(); } }

然后在Startup類的Configure方法中添加下面一行代碼,把自定義的中間添加到了HTTP請求的管道中。

app.UseLogReqResponseMiddleware();//記錄http請求 輸入、輸出值;

我們在postman中模擬請求

控制台上打印的信息如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM