Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of the usage of ASP.NET Core Middleware and official commonly used Middleware

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Editor to share with you the use of ASP.NET Core middleware and official commonly used middleware example analysis, I hope you will learn something after reading this article, let's discuss it!

I. what is middleware

As we all know, any web framework encapsulates a http request into a pipeline, and each request is a series of operations through the pipeline before it finally reaches the code we write. Middleware is the component used to make up the application pipeline to process requests and responses. Each component in the pipeline can choose whether to forward the request to the next component and perform certain actions before and after the next component is called in the pipeline. The request delegate is used to establish the request pipeline, requesting the delegate to process each HTTP request.

Middleware can be considered to have two basic responsibilities:

Select whether to pass the request to the next middleware in the pipe.

You can perform some work before and after the next middleware in the pipeline.

The request delegate is configured using Run, Map, and Use extension methods of type IApplicationBuilder and passed to the Configure method in the Startup class. Each individual request delegate can be specified as an embedded anonymous method or defined in a reusable class. These reusable classes are called "middleware" or "middleware components". Each middleware component located in the request pipeline is responsible for invoking the next component in the pipeline, or short-circuiting the call chain at the right time. Middleware is a typical AOP application.

The ASP.NET Core request pipeline consists of a series of request delegates that are called one after another, as shown in the following Microsoft official middleware request pipeline diagram (in which threads of execution are executed in the order of black arrows):

Middleware short circuit: each delegate has the opportunity to perform operations before and after the next delegate. Any delegate can choose to stop passing to the next delegate, but instead end the request and start responding, which is the short circuit of the request pipeline, which is a meaningful design because it avoids some unnecessary work. For example, an authorization middleware cannot call the next delegate until it is authenticated, otherwise it will be short-circuited and return a "Not Authorized" response. Exception handling delegates need to be called early in the pipeline so that they can catch exceptions that occur at a deeper level within the pipeline. A short circuit can be represented by the following picture:

In the figure above, we can think of middleware 1 as authentication middleware. The HTTP request is sent first through the authentication middleware. If authentication fails, the response is directly given and returned, and the request is no longer passed to the following middleware 2 and middleware 3.

The execution of the middleware is related to the order in which the call is made, and then returns in the opposite order when responding.

Requests can be short-circuited at each step, so we need to add middleware in the correct order, such as exception handling middleware, we need to add it at the beginning, so that we can catch exceptions and subsequent exceptions that may occur in the middle at the first time. and finally do the processing to return.

Let's look at what middleware is provided in the Configure method:

Public void Configure (IApplicationBuilder app, IWebHostEnvironment env) {if (env.IsDevelopment ()) {/ / exception middleware app.UseDeveloperExceptionPage ();} / routing middleware app.UseRouting (); / / authorization middleware app.UseAuthorization (); / / endpoint middleware app.UseEndpoints (endpoints = > {endpoints.MapControllers ();}) } the difference between middleware and filter

Middleware and filters are both AOP ideas, and their functions are similar, so what's the difference between them?

The filter is more relevant to the business, focusing on the application itself and on how to implement the business, such as formatting the output and validating the requested ViewModel, so the filter is sure to be used. Filters are part of MVC, which can intercept some information in your Action context, which middleware does not have. It can be considered that the filter is an additional function, it is only a feature incidental to the middleware. Middleware is an important part of the pipeline model, which is indispensable, but the filter can be absent.

2. Common methods of middleware

Run, Use, Map and MapWhen are defined in the middleware, and we will explain these methods one by one.

1. Run method

Let's first look at the definition of the Run () method:

As can be seen in the definition in the Run () method, there is only one parameter of the RequestDelegate delegate type and no Next parameter, so the Run () method is also called terminal middleware and does not pass the request to the next middleware, that is, there is a "short circuit". Look at the following code:

/ / the Run method adds a RequestDelegate delegate to the application's request pipeline / / at the end of the pipeline, terminal middleware app.Run (handler: async context = > {await context.Response.WriteAsync (text: "Hello World1\ r\ n");}); app.Run (handler: async context = > {await context.Response.WriteAsync (text: "Hello World2\ r\ n");})

The result of running the program:

It can be seen that only the information of middleware 1 is output, but no information of middleware 2 is output, indicating that a short circuit has occurred.

Note: the Run () method is called terminal middleware and should be placed at the end of all middleware, otherwise the middleware after the Run () method will not be executed.

2. Use method

Let's first look at the definition of the Use () method:

You can see that the parameter of the Use method is a Func delegate, the input parameter is a delegate of type RequestDelegate, and the return parameter is also a delegate of type RequestDelegate. Here, it means to call the next middleware. Let's take a look at the definition of the RequestDelegate delegate:

You can see that RequestDelegate is a delegate with a parameter of type HttpContext. HttPContext represents the Http request context, and the request information can be obtained. The return value is of type Task. After understanding the parameters of the Use () method, we write a custom Use () method:

/ / add a Func delegate to the application's request pipeline, which is actually the so-called middleware. The / / context parameter is HttpContext, indicating that the context object / / next parameter of the HTTP request represents the next middleware delegate in the pipeline. If next is not called, the pipeline will short-circuit / / multiple middleware can be linked together with Use (async (context, next) = > {await context.Response.WriteAsync (text: "hello Use1\ r\ n"); / / call the next delegate await next ();}) App.Use (async (context, next) = > {await context.Response.WriteAsync (text: "hello Use2\ r\ n"); / / call the next delegate await next ();})

The result of running the program:

As we said above, you can do some work before and after calling the middleware. Take a look at the following code:

/ / add a Func delegate to the application's request pipeline, which is actually the so-called middleware. The / / context parameter is HttpContext, indicating that the context object of the HTTP request / / next parameter represents the next middleware delegate in the pipeline. If next is not called, the pipeline will be short-circuited / / multiple middleware can be linked together with Use (async (context, next) = > {/ / solve the Chinese garbled problem context.Response.ContentType = "text/plain; charset=utf-8" Await context.Response.WriteAsync (text: "Middleware 1: incoming request\ r\ n"); / / call the next delegate await next (); await context.Response.WriteAsync (text: "Middleware 1: outgoing response\ r\ n");}); app.Use (async (context, next) = > {await context.Response.WriteAsync (text: "Middleware 2: incoming request\ r\ n") / / invoke the next delegate await next (); await context.Response.WriteAsync (text: "Middleware 2: outgoing response\ r\ n");}); app.Run (handler:async context = > {await context.Response.WriteAsync (text: "Middleware 3: process request and generate response\ r\ n");})

The result of running the program:

We can summarize the execution order of the above code:

The request first arrives at middleware 1 and then outputs (middleware 1: incoming request)

Then middleware 1 calls next (). Next () invokes middleware 2 in the pipeline.

Middleware 2 output (middleware 2: incoming request).

Then middleware 2 calls next (). Next () invokes middleware 3 in the pipeline.

Middleware 3 processes the request and generates the response, instead of calling the next middleware, so we see the output (middleware 3: processes the request and generates the response).

At this point, management began to reverse.

At this point, the controller will hand it back to the middleware 2 and pass it the response generated by the middleware 3. Middleware 2 output (middleware 2: outgoing response).

Finally, middleware 2 is handing control to middleware 1.

The final output of middleware 1 (middleware 1: outgoing response), which is the result of our last look.

We know that there are two parameters in the Use () method, and the next parameter indicates that the next middleware in the pipeline is called. If next is not called, the pipeline will also be short-circuited, which is equivalent to the Run () method. See the following code:

/ / add a Func delegate to the application's request pipeline, which is actually the so-called middleware. The / / context parameter is HttpContext, indicating that the context object of the HTTP request / / next parameter represents the next middleware delegate in the pipeline. If next is not called, the pipeline will be short-circuited / / multiple middleware can be linked together with Use (async (context, next) = > {/ / solve the Chinese garbled problem context.Response.ContentType = "text/plain; charset=utf-8" Await context.Response.WriteAsync (text: "Middleware 1: incoming request\ r\ n"); / / call the next delegate await next (); await context.Response.WriteAsync (text: "Middleware 1: outgoing response\ r\ n");}); app.Use (async (context, next) = > {await context.Response.WriteAsync (text: "Middleware 2: incoming request\ r\ n") / / invoke the next delegate await next (); await context.Response.WriteAsync (text: "Middleware 2: outgoing response\ r\ n"); / / app.Run (handler:async context = > / / {/ / await context.Response.WriteAsync (text: "Middleware 3: process the request and generate the response\ r\ n"); / /}) The / / Use method can also not call next to indicate a short circuit app.Use (async (context, next) = > {await context.Response.WriteAsync (text: "Middleware 3: processing requests and generating responses\ r\ n");})

The result of running the program:

You can see that if you use the Use () method without calling next, the effect will be the same as using the Run () method, which will short-circuit the pipeline.

3. Map method

Map, as a convention, diverts the pipeline. Map distributes the request pipeline based on a given request path match. If the request path starts with the specified path, the branch is executed. Look at the definition of the Map () method:

You can see that the Map method has two parameters: the first parameter is the matching rule, the second parameter is the Action generic delegate, and the generic delegate parameter is of type IApplicationBuilder, which is the same as the first parameter type of the Configure method. This means that a method that implements an Action generic delegate can be added to the middleware pipeline for execution.

Let's first define a method whose argument is of type IApplicationBuilder:

/ IApplicationBuilderprivate void HandleMap1 (IApplicationBuilder app) {app.Run (handler: async context = > {await context.Response.WriteAsync (text: "Hello Map1");});} / IApplicationBuilderprivate void HandleMap2 (IApplicationBuilder app) {app.Run (handler: async context = > {await context.Response.WriteAsync (text: "Hello Map2") });}

Then look at the code that uses the Map method:

/ / Map can be executed according to matching URL. To put it simply, branch selection and execution based on URL / / is somewhat similar to the route in MVC / / matching URL: http://localhost:5000/Map1app.Map(pathMatch: "/ Map1", configuration: HandleMap1); / / matching URL: http://localhost:5000/Map2app.Map(pathMatch: "/ Map2", configuration: HandleMap2)

Run the program, then type: http://localhost:5000/Map1 in the browser address bar, and output the result:

Enter: http://localhost:5000/Map2 in the address bar and output the result:

Map also supports nesting, as shown in the following code:

/ / nested Mapapp.Map (pathMatch: "/ Map1", configuration: App1 = > {/ / App1.Map ("/ Map2", action= > {action.Run (async context = > {await context.Response.WriteAsync ("This is / Map1/Map2");}); App1.Run (async context = > {await context.Response.WriteAsync ("This is no-map");});})

Access the http://localhost:5000/Map1/123 output result:

Access the http://localhost:5000/Map1 output result:

Access the http://localhost:5000/Map1/Map2 output result:

Map can also match multiple segments at the same time, see the following code:

Run the program and output the results:

Access the http://localhost:5000/Map1/Map2 output result:

4. Mapwhen method

MapWhen is based on the given predicate branch request pipeline. Any request that causes Func to return the predicate of true is mapped to a new pipe branch.

Let's first look at the definition of the Mapwhen method:

You can see that the MapWhen method has two parameters: the first parameter is a delegate of type Func, the input parameter is HttpContext, and the output parameter is of type bool. The second parameter is the Action delegate, which is of type IApplicationBuilder, which means that the method that implements the Action delegate can also be added to the middleware pipeline for execution.

Looking at the following example, if the name query parameter is included in the url, the HandleName method is executed, and if the age query parameter is included, the HandleAge method is executed, otherwise the Run () method is executed.

The HandleName and HandleAge methods are defined as follows:

Private void HandleName (IApplicationBuilder app) {app.Run (handler: async context = > {await context.Response.WriteAsync (text: $"This name is: {context.Request.Query [" name "]});} private void HandleAge (IApplicationBuilder app) {app.Run (handler: async context = > {await context.Response.WriteAsync (text: $" This age is: {context.Request.Query ["age"} ");}

The corresponding MapWhen method is defined as follows:

/ / if the accessed url parameter contains name, execute HandleNameapp.MapWhen (/ / Func delegate, input parameter is HttpContext, and return Bool value predicate: context = > {/ / determine whether name return context.Request.Query.ContainsKey ("name") is included in the url parameter;}, configuration: HandleName) / / if the accessed url parameter contains name, execute HandleAgeapp.MapWhen (/ / Func delegate, input parameter is HttpContext, and return Bool value predicate: context = > {/ / determine whether age return context.Request.Query.ContainsKey ("age") is included in the url parameter;}, configuration: HandleAge); app.Run (async context = > {await context.Response.WriteAsync ("There is non-Map delegate\ r\ n");})

Run the program and output the results:

Add name query parameters to url to output the result:

Add age query parameters to url to output the result:

III. Custom middleware

In the above example, we all use the automatic method of official middleware, but we can also write one ourselves.

Middleware follows the principle of displaying dependencies and exposes all dependencies in its constructor. Middleware can take advantage of UseMiddleware extension methods and inject services directly through their constructors. The dependency injection service is populated automatically.

The ASP.NET Core convention middleware class must include the following:

Has a common constructor of type RequestDelegate parameter.

There must be a public method named Invoke or InvokeAsync, which must satisfy two conditions: the method return type is Task, and the first parameter of the method must be of type HttpContext.

Let's customize a middleware for recording IP and create a new class RequestIPMiddleware. The code is as follows:

Using Microsoft.AspNetCore.Http;using System.Threading.Tasks;namespace MiddlewareDemo.Middleware {/ Middleware for recording IP addresses / public class RequestIPMiddleware {/ / Private fields private readonly RequestDelegate _ next / Common constructor. The parameter is of type RequestDelegate / and the dependency injection service automatically completes the injection / public RequestIPMiddleware (RequestDelegate next) {_ next = next. } / Invoke method / return value is Task, parameter type is HttpContext / Http context / public async Task Invoke (HttpContext context) {await context.Response.WriteAsync ($"User IP: {context.Connection.RemoteIpAddress.ToString ()}\ r\ n") / / call the next delegate in the pipeline await _ next.Invoke (context);}

Then create an extension method to extend IApplicationBuilder:

Using Microsoft.AspNetCore.Builder;namespace MiddlewareDemo.Middleware {public static class RequestIPExtensions {/ extension method to extend IApplicationBuilder / public static IApplicationBuilder UseRequestIP (this IApplicationBuilder builder) {/ / UseMiddleware return builder.UseMiddleware ();}

Finally, use custom middleware in the Configure method of the Startup class:

/ / use custom middleware app.UseRequestIP ()

Run the program to view the results:

This completes a custom middleware.

4. Official middleware 1. Exception handling middleware

When the application is running in the development environment, the developer exception page middleware (UseDeveloperExceptionPage) reports errors while the application is running.

When the application is running in a production environment, the exception handling middleware (UseExceptionHandler) catches the exceptions thrown in the middleware below.

2. HTTPS redirect middleware

HTTPS redirect middleware (UseHttpsRedirection) redirects HTTP requests to HTTPS.

3. Static file middleware

Static file middleware (UseStaticFiles) returns static files and simplifies further request processing.

4. Cookie middleware

Cookie Policy Middleware (UseCookiePolicy) enables applications to comply with EU general data protection regulations.

5. Routing middleware

Routing middleware (UseRouting) is used for routed requests.

6. Identity authentication middleware

Authentication middleware (UseAuthentication) attempts to authenticate the user and does not allow the user to access secure resources until the authentication is passed.

7. Authorized middleware

Authorization middleware (UseAuthorization) is used to authorize which resources the authenticated user can access.

8. Session middleware

Session middleware (UseSession) establishes and maintains session state. If your application uses session state, invoke the session middleware after Cookie policy middleware and before MVC middleware.

9. Terminal routing middleware

Endpoint routing middleware (UseEndpoints) is used to add Razor Pages endpoints to the request pipeline.

After reading this article, I believe you have some understanding of "sample Analysis of ASP.NET Core Middleware usage and official commonly used Middleware". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report