Middleware official website documentation: Middleware is a piece of software that is assembled into the application pipeline to handle requests and responses.

  • Choose whether to pass the request to the next component in the pipeline.
  • Work can be performed before and after the next component in the pipeline.

Create a middleware pipeline using IApplicationBuilder

The ASP.NET  Core request pipeline contains a series of request delegates, which are called in turn. The figure below illustrates this concept. Execute along the black arrow.

DotNET_Core_3.0_Middleware_0.png

IApplicationBuilder provides three extension methods to configure request delegation

  • The app.Run function adds a terminal middleware because it is not passed down the request and is often exposed to run at the end of the pipeline. Instance code
  app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, middleware!");
        });
  • app.Use links multiple request delegates together. The next parameter represents the next delegate in the pipeline. A pipe short can be equated with aap.run by not calling the next parameter. You can usually perform operations before and after the next delegate, as shown in the following example:

 

 

  app.Use(async (context, next) =>
        {
            / / Before the transfer operation 
            await next.Invoke ();
             / / before the transfer operation 
        });

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }

 

 

  • The Map extension is used as a convention to create a pipe branch. Map creates a request pipe branch based on a match for a given request path. If the request path begins with a given path, the branch is executed. The example code is as follows

 

 

  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>");
        });
    }

 

 

Custom middleware

The following demonstrates the middleware that records the api input and output parameters.

1. Create a webapi project, add a simple post method to the default WeatherForecastController controller, the code is as follows

 

 

 [HttpPost]
        public string PostWeatherForecast([FromBody]WeatherForecastA weatherForecastA)
        {
            Return  " added successfully " ;
        }

 

 

public class WeatherForecastA
    {
        public int TemperatureC { get; set; }
    }

2. Create a new middleware class. CS file as shown

 

The default code after selection is as follows:

 

 

 // 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>();
        }
    }

 

 

Scaffolding automatically creates an Invoke method for us to pass to the next middleware. An extension method, UseLogReqResponseMiddleware, that adds custom middleware to the http request pipeline.

The above invoke is not asynchronous, we can change it ourselves. The following code shows the log input of the input parameters and output information of an api request.

 

 

 // 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();
             // convert the request body stream to a string 
            string bodyAsText = await new StreamReader(request.Body).ReadToEndAsync(); // record request information 
            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);
                 // Convert to string 
                string text = await  new StreamReader(response.Body).ReadToEndAsync();
                 // Set offset 0 from new. 
                response.Body.Seek( 0 , SeekOrigin.Begin);

                / / Record the return value 
                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>();
        }
    }

 

 

Then add the following line of code to the Configure method of the Startup class to add the custom middle to the pipeline for the HTTP request.

app.UseLogReqResponseMiddleware (); / / record http request input, output value;

We simulate the request in postman

DotNET_Core_3.0_Middleware_12.png

The information printed on the console is as follows:

DotNET_Core_3.0_Middleware_13.png

Orignal link:https://www.cnblogs.com/chengtian/p/11799530.html