Middleware document explains official website: Middleware is fitted to the conduit application software requests and responses for each middleware:
- Selecting whether a request to the next pipeline component.
- Work may be performed before or after the assembly of a pipeline.
Use IApplicationBuilder create middleware pipeline
ASP.NET Core request pipeline includes a series of requests delegate, in turn calls. The following figure illustrates this concept. The black arrow executed.
IApplicationBuilder method provides three extended configuration request delegation
- app.Run action add a terminal application, because the request does not pass downwardly, often run at the end of the pipe is disclosed. The example code
app.Run(async context => { await context.Response.WriteAsync("Hello, middleware!"); });
- app.Use multiple requests commissioned linked together. parameter indicates a next delegate in the pipeline. By not calling the next parameter is equivalent to a short circuit conduit so aap.run. Typically the next operation, as shown in the following example performed before and after the commission:
app.Use ( the async (context, Next) => { // before transmitting the operation of the await next.Invoke (); // before transmitting operation }); app.run ( the async context => { the await context.Response.WriteAsync ( " 2nd from the delegate hello. " ); }); }
- Map expansion as a convention to create a pipeline branch. Map based on the given path matches the request to create a branch pipeline request. If a given request path beginning of the path, the branch is executed. The example code below
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 demo recording api input and output parameters of the middleware.
Webapi 1. Create a project, add a simple method in the default post WeatherForecastController controller, as follows
[HttpPost] public String PostWeatherForecast ( int TemperatureC) { return " added successfully " ; }
2. Create a new class .CS intermediate file in FIG.
After selecting the default code 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 help us create an Invoke method, passing to the next middleware. A custom middleware added to the http request pipeline extension method UseLogReqResponseMiddleware.
The above invoke not asynchronous, we ourselves can change, input parameters and output log information The following code shows a print request 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; var buffer = new byte[Convert.ToInt32(request.ContentLength)]; await request.Body.ReadAsync(buffer, 0, buffer.Length); //把请求body流转换成字符串 var bodyAsText = Encoding.UTF8.GetString(buffer); //记录请求信息 var requestStr = $"{request.Scheme} {request.Host}{request.Path} {request.QueryString} {bodyAsText}"; logger.LogDebug("Request:" + requestStr); var originalBodyStream = httpContext.Response.Body; using (var responseBody = newThe MemoryStream ()) { httpContext.Response.Body = the responseBody; the await -next (httpContext); var Response = httpContext.Response; response.Body.Seek ( 0 , SeekOrigin.Begin); // into a string String text = the await new new the StreamReader (response.body) .ReadToEndAsync (); // new setting offsets 0 response.Body.Seek ( 0 , SeekOrigin.Begin); // record 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 in the method Configure Startup class, the middle to add a custom HTTP pipeline request.
app.UseLogReqResponseMiddleware (); // record http request input and output values;
We simulate the request postman
Information printed on the console as follows: