21 | Middleware: the key to control of request processing
If the Map when a little complicated logic, not only to determine its URL address, and a special judge to do, you can do to become a delegate decision logic
We have to determine when we requested address contains abc, and output new abc
app.MapWhen(context =>
{
return context.Request.Query.Keys.Contains("abc");
}, builder =>
{
builder.Run(async context =>
{
await context.Response.WriteAsync("new abc");
});
});
Start a program, there is no output
When we start back at the default address input? Abc = 1, you can see the output of the new abc
Run a method used here, and the one used in the method is Use
app.Map("/abc", abcBuilder =>
{
abcBuilder.Use(async (context, next) =>
{
//await context.Response.WriteAsync("Hello");
await next();
await context.Response.WriteAsync("Hello2");
});
});
What is the difference between Run and Use is it?
Use means that we can be like a full registration as middleware, will come next injection, we can decide whether to follow middleware
Run the meaning says this is the end of our middleware executed, it is not behind the implementation of the middleware, where the return request
How do we like UseRouting UseEndpoints as to design our own middleware it?
Here a good definition of a MyMiddleware
namespace MiddlewareDemo.Middlewares
{
class MyMiddleware
{
RequestDelegate _next;
ILogger _logger;
public MyMiddleware(RequestDelegate next, ILogger<MyMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
using (_logger.BeginScope("TraceIdentifier:{TraceIdentifier}", context.TraceIdentifier))
{
_logger.LogDebug("开始执行");
await _next(context);
_logger.LogDebug("执行结束");
}
}
}
}
Middleware is defined by an agreed manner, middleware or class contains a method Invoke InvokeAsync such a method, it returns a Task, the parameter a is the HttpContext, in fact, to be understood that the same is entrusted with the middleware , as long as our class include such a method, it can register as a middleware into, and to identify the frame
There is also defined a MyBuilderExtensions
namespace Microsoft.AspNetCore.Builder
{
public static class MyBuilderExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<MyMiddleware>();
}
}
}
Our middleware registered in, this method is UseMyMiddleware
By this definition, we can use their own middleware
app.UseMyMiddleware();
Start the program, the output is as follows:
Console output
dbug: MiddlewareDemo.Middlewares.MyMiddleware[0]
=> RequestPath:/weatherforecast RequestId:0HLU50UEM3M9F:00000001, SpanId:|77f92fe8-4a6d800968327989., TraceId:77f92fe8-4a6d800968327989, ParentId: => TraceIdentifier:0HLU50UEM3M9F:00000001
开始执行
dbug: MiddlewareDemo.Middlewares.MyMiddleware[0]
=> RequestPath:/weatherforecast RequestId:0HLU50UEM3M9F:00000001, SpanId:|77f92fe8-4a6d800968327989., TraceId:77f92fe8-4a6d800968327989, ParentId: => TraceIdentifier:0HLU50UEM3M9F:00000001
执行结束
Page controller output
[{"date":"2020-03-11T23:30:55.3411696+08:00","temperatureC":20,"temperatureF":67,"summary":"Warm"},{"date":"2020-03-12T23:30:55.3417863+08:00","temperatureC":52,"temperatureF":125,"summary":"Bracing"},{"date":"2020-03-13T23:30:55.3417916+08:00","temperatureC":-3,"temperatureF":27,"summary":"Mild"},{"date":"2020-03-14T23:30:55.341792+08:00","temperatureC":35,"temperatureF":94,"summary":"Balmy"},{"date":"2020-03-15T23:30:55.3417923+08:00","temperatureC":37,"temperatureF":98,"summary":"Sweltering"}]Hello2
If you want to implement a circuit breaker, is not a logical follow-up to the implementation, comment out the line
_logger.LogDebug("开始执行");
//await _next(context);
_logger.LogDebug("执行结束");
Start the program, the page will not output anything, it will only print out the execution of middleware in the console, the controller does not perform follow-up
This realization of a circuit breaker, which means you can use your own middleware do control request, and at very flexible control
In the course of the use of middleware, requires great attention is the order registered middleware, which determines the order of execution timing of middleware, middleware will be some effect of the circuit breaker, certain middleware will do some requested content processing
There is also a more crucial point is that once you start the application refers to Response write when subsequent middleware can not go to operating its header, it is to be noted
Context.Response.HasStarted can be judged by whether the content has started in response to the output of the body, once the output content, the operation would not have header
This work is Creative Commons Attribution - NonCommercial - ShareAlike 4.0 International License Agreement for licensing.
Welcome to reprint, use, repost, but be sure to keep the article signed by Zheng Ziming (containing links: http://www.cnblogs.com/MingsonZheng/), shall not be used for commercial purposes, be sure to publish the same work based on the paper license modification .
If you have any questions, please contact me ([email protected]).