(The key to control of request processing:: Middleware Lesson 21) - Study Notes (next) combat .NET Core Development

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

Creative Commons License

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]).

Guess you like

Origin www.cnblogs.com/MingsonZheng/p/12459751.html