In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Today, I would like to share with you the relevant knowledge of how to use ASP.NET Core middleware. The content is detailed and the logic is clear. I believe most people still know too much about this, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.
1. Preface
The entire flow of processing between the HTTP Request request and the result returned by HTTP Response is a request pipeline (request pipeline). Middleware (middleware) is a component that is assembled to a request pipeline to handle requests and responses. Each component:
You can choose whether to pass the request to the next component in the pipe.
Work can be performed before and after the next component in the pipe.
The middleware (middleware) processing flow is shown in the following figure:
two。 Use middleware
Each middleware in the ASP.NET Core request pipeline contains a series of request delegates (request delegates) to process each HTTP request, which is called in turn. The request delegate is configured in the Strartup.Configure method by using Run, Use, and Map extension methods of type IApplicationBuilder. Let's learn about the middleware by configuring examples of Run, Use, and Map extension methods.
2.1 Runpublic class Startup {public void Configure (IApplicationBuilder app) {/ / first request delegate Run app.Run (async context = > / / embedded anonymous method {await context.Response.WriteAsync ("Hello, World!");}); / / second request delegate Run app.Run (async context = > / / embedded anonymous method {await context.Response.WriteAsync ("Hey, World!");}) }}
Response result:
From the above code, the Run method is specified as an embedded anonymous method (called parallel middleware, in-line middleware), while the embedded anonymous method does not specify the execution of the next request delegate, a process called pipeline short circuit, and the middleware is also called "terminal middleware" (terminal middleware) because it prevents the middleware from processing the request next. So Run terminated the request when the first request delegated, and did not execute the second request delegate directly returned Hello, World! Output text. According to the official website, Run is a convention, and some middleware components may expose their own Run methods, which can only be run at the end of the pipeline (that is, the Run method is only used when the middleware performs the last request delegate).
2.2 Usepublic void Configure (IApplicationBuilder app) {app.Use (async (context, next) = > {context.Response.ContentType = "text/plain; charset=utf-8"; await context.Response.WriteAsync ("before entering the first delegate to execute the next delegate\ r\ n"); / / calling the next delegate in the pipeline await next.Invoke () Await context.Response.WriteAsync ("finish the first delegate and execute the next delegate\ r\ n");}); app.Run (async context = > {await context.Response.WriteAsync ("enter the second delegate\ r\ n"); await context.Response.WriteAsync ("Hello from 2nd delegate.\ r\ n"); await context.Response.WriteAsync ("end the second delegate\ r\ n") });}
Response result:
As you can see from the above code, the Use method links multiple request delegates together. The next parameter represents the next delegate in the pipeline. Invoking the next request delegate without calling the next parameter shorts the pipeline. 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. Therefore, exception handling delegates should be invoked in the pipeline as early as possible so that they can catch exceptions that occur at a later stage of the pipeline.
2.3 Map and MapWhen
The Map:Map extension creates a pipe branch based on the request path.
The MapWhen:MapWhen extension creates a pipe branch based on the request condition.
Map example:
Public class Startup {private static void HandleMapTest1 (IApplicationBuilder app) {app.Run (async context = > {await context.Response.WriteAsync ("MapTest1");});} private static void HandleMapTest2 (IApplicationBuilder app) {app.Run (async context = > {await context.Response.WriteAsync ("MapTest2");}) } 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.
");})
The following table uses the previous code to display requests and responses from http://localhost:5001.
Request
Response
Localhost:5001
Hello from non-Map delegate.
Localhost:5001/map1
Map Test 1
Localhost:5001/map2
Map Test 2
Localhost:5001/map3
Hello from non-Map delegate.
As you can see from the above code, the Map method removes the matching path segment from the HttpRequest.Path and appends the path to the HttpRequest.PathBase for each request. In other words, when we enter the map1 request address in the browser, the system will execute the map1 branch pipeline to output its request delegation information, and similarly, execute map2 will output the corresponding request delegation information.
MapWhen example:
Public class Startup {private static void HandleBranch (IApplicationBuilder app) {app.Run (async context = > {var branchVer = context.Request.Query ["branch"]; await context.Response.WriteAsync ($"Branch used = {branchVer}");}) } public void Configure (IApplicationBuilder app) {app.MapWhen (context = > context.Request.Query.ContainsKey ("branch"), HandleBranch); app.Run (async context = > {await context.Response.WriteAsync ("Hello from non-Map delegate.
");})
The following table uses the previous code to display requests and responses from http://localhost:5001.
Request
Response
Http://localhost:5001
Hello from non-Map delegate.
Https://localhost:5001/?branch=master
Branch used = master
From the above code, MapWhen creates a pipe branch based on the branch condition, and we enter master on the branch condition to create its corresponding pipe branch. That is, any string condition entered on the branch condition creates a new administrative branch.
Map also supports nesting, such as:
Public void Configure (IApplicationBuilder app) {app.Map ("/ level1", level1App = > {level1App.Map ("/ level2a", level2AApp = > {/ / "/ level1/level2a" processing}); level1App.Map ("/ level2b", level2BApp = > {/ "/ level1/level2b" processing});})
You can also match multiple segments at the same time:
Public class Startup {private static void HandleMultiSeg (IApplicationBuilder app) {app.Run (async context = > {await context.Response.WriteAsync ("Map multiple segments.");});} public void Configure (IApplicationBuilder app) {app.Map ("/ map1/seg1", HandleMultiSeg) App.Run (async context = > {await context.Response.WriteAsync ("Hello from non-Map delegate.");});} 3. Sequence
The order in which middleware components are added to the Startup.Configure method defines the order in which they are invoked on requests and the reverse order of responses. This sort is critical for security, performance, and functionality.
The following Startup.Configure methods add middleware components to common applications:
Exception / error handling (Exception/error handling)
HTTP strict Transport Security Protocol (HTTP Strict Transport Security Protocol)
HTTPS redirection (HTTPS redirection)
Static file server (Static file server)
Cookie Policy Enforcement (Cookie policy enforcement)
Authentication (Authentication)
Session (Session)
MVC
Take a look at the following code:
Public void Configure (IApplicationBuilder app) {if (env.IsDevelopment ()) {/ / When the app runs in the Development environment: / / Use the Developer Exception Page to report app runtime errors. / / Use the Database Error Page to report database runtime errors. App.UseDeveloperExceptionPage (); app.UseDatabaseErrorPage ();} else {/ / When the app doesn't run in the Development environment: / / Enable the Exception Handler Middleware to catch exceptions / / thrown in the following middlewares. / / Use the HTTP Strict Transport Security Protocol (HSTS) / / Middleware. App.UseExceptionHandler ("/ Error"); app.UseHsts ();} / / Return static files and end the pipeline. App.UseStaticFiles (); / / Authenticate before the user accesses secure resources. App.UseAuthentication ();}
From the sample code above, each middleware extension method is exposed on the IApplicationBuilder through the Microsoft.AspNetCore.Builder namespace. But why should we add middleware components in this order? Let's pick a few middleware to understand.
UseExceptionHandler (exception / error handling) is the first middleware component added to the pipeline. So we can catch any exception that occurs in the application call. So why put exception / error handling first? That's because we don't have to worry about not being able to capture all the abnormal information of the entire application due to the short circuit of the previous middleware.
UseStaticFiles (static file) middleware is called in advance in the pipeline so that it can handle requests and short circuits without going through the remaining intermediate components. In other words, static file middleware can be accessed directly without UseAuthentication (authentication) check, and any file served by static file middleware, including files under wwwroot, can be accessed publicly.
UseAuthentication (authentication) occurs only after MVC selects a specific Razor page or Controller and Action.
As described above, we all understand the importance of the order of middleware.
4. Write middleware (key points)
Although ASP.NET Core provides us with a rich set of built-in middleware components, in some cases, you may need to write custom middleware.
4.1 Middleware class
Let's customize a middleware that queries the current culture:
Public class Startup {public void Configure (IApplicationBuilder app) {app.Use ((context, next) = > {var cultureQuery = context.Request.Query ["culture"]; if (! string.IsNullOrWhiteSpace (cultureQuery)) {var culture = new CultureInfo (cultureQuery); CultureInfo.CurrentCulture = culture; CultureInfo.CurrentUICulture = culture } / / Call the next delegate/middleware in the pipeline return next ();}); app.Run (async (context) = > {await context.Response.WriteAsync ($"Hello {CultureInfo.CurrentCulture.DisplayName}");});}}
You can test by passing in a culture parameter condition. For example, http://localhost:7997/?culture=zh, http://localhost:7997/?culture=en.
But if each custom middleware were written as much code as above in the Startup.Configure method, it would be disastrous for the program (bad for maintenance and invocation). To better manage the code, we should encapsulate embedded anonymous methods into a new custom class (example custom RequestCultureMiddleware class):
Public class RequestCultureMiddleware {private readonly RequestDelegate _ next; public RequestCultureMiddleware (RequestDelegate next) {_ next = next;} public async Task InvokeAsync (HttpContext context) {context.Response.ContentType = "text/plain; charset=utf-8"; var cultureQuery = context.Request.Query ["culture"]; if (! string.IsNullOrWhiteSpace (cultureQuery)) {var culture = new CultureInfo (cultureQuery); CultureInfo.CurrentCulture = culture CultureInfo.CurrentUICulture = culture;} / / Call the next delegate/middleware in the pipeline await _ next (context);}}
Call the middleware through the Startup.Configure method:
Public class Startup {public void Configure (IApplicationBuilder app) {app.UseMiddleware (); app.Run (async (context) = > {await context.Response.WriteAsync ($"Hello {CultureInfo.CurrentCulture.DisplayName}");}} 4.2 Middleware extension method
The Startup.Configure method invocation middleware setting can be exposed through custom extension methods (calling the built-in IApplicationBuilder to expose the middleware). The example creates a RequestCultureMiddlewareExtensions extension class and exposes it through IApplicationBuilder:
Public static class RequestCultureMiddlewareExtensions {public static IApplicationBuilder UseRequestCulture (this IApplicationBuilder builder) {return builder.UseMiddleware ();}}
Then call the middleware through the Startup.Configure method:
Public class Startup {public void Configure (IApplicationBuilder app) {app.UseRequestCulture (); app.Run (async (context) = > {await context.Response.WriteAsync ($"Hello {CultureInfo.CurrentCulture.DisplayName}");});}}
Response result:
By delegating to construct the middleware, the application creates the middleware at run time and adds it to the pipeline. It should be noted here that the creation of middleware is singleton, and there is only one instance of each middleware in the application life cycle. So the question is, what should we do if our business logic requires multiple instances? Please read on.
5. Create dependency injection (DI) per request
During the creation of the middleware, the built-in IOC container creates an instance of the middleware for us, and only one instance of the middleware is created throughout the application life cycle. Usually our program does not allow such injection logic. In fact, we can understand the middleware as the entrance of the business logic, the real business logic is implemented through the Application Service layer, we only need to inject the application services into the Invoke method. ASP.NET Core provides us with this mechanism, which allows us to inject dependencies on request, that is, to create a service for each request. Example:
Public class CustomMiddleware {private readonly RequestDelegate _ next; public CustomMiddleware (RequestDelegate next) {_ next = next;} / / IMyScopedService is injected into Invoke public async Task Invoke (HttpContext httpContext, IMyScopedService svc) {svc.MyProperty (1000); await _ next (httpContext);}} public static class CustomMiddlewareExtensions {public static IApplicationBuilder UseCustomMiddleware (this IApplicationBuilder builder) {return builder.UseMiddleware ();}} public interface IMyScopedService {void MyProperty (decimal input) } public class MyScopedService: IMyScopedService {public void MyProperty (decimal input) {Console.WriteLine ("MyProperty is" + input);}} public void ConfigureServices (IServiceCollection services) {/ / inject DI service services.AddScoped ();}
Response result:
These are all the contents of the article "how to use ASP.NET Core Middleware". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.