Introduction to ASP. NET Core middleware and project practices, asp. netcore
Preface
This article is actually used in the development of our own projects. It fits into the actual application and is an in-depth use of middleware, not a simple Hello World.
Role of Middleware (Middleware)
We know that any web framework encapsulates http requests into a pipeline, and each request passes through a series of operations in the pipeline, and finally enters the code we write. Middleware is a component in the application pipeline to intercept the request process for some other processing and response. There can be many middleware. Each middleware can intercept requests in the pipeline and decide whether to transfer requests to the next middleware.
Asp.net core provides the IApplicationBuilder interface to register middleware to the asp.net pipeline request. middleware is a typical AOP application.
Each middleware can operate before and after a request. After the request is processed, it is passed to the next request.
Running Mode of Middleware
By default, the execution order of the middleware is determinedStartup.cs
File, inpublic void Configure(IApplicationBuilder app){}
Method.
There are three ways to register "Middleware" in the pipeline"
1.app.Use()
,IApplicationBuilder
It is provided by the API native and used for registration.
2.app.Run()
Is an extension method, which requiresRequestDelegate
The delegate contains the Http context information without the next parameter, because it is always executed in the last step of the pipeline.
3.app.Map()
Is also an extension method, similar to the MVC routing, which is generally used for processing some special request paths. For example, www.example.com/token.
The Run and Map above are also called internal Use, which is an extension of the IApplicationBuilder interface. If you think the names are not accurate enough, the following extension method is the authentic registration of middleware, it is also the most powerful.
app.UseMiddleware<>()
That's it. Why is it powerful? It not only provides the function of registering middleware, but also the function of dependency injection (DI), which will be used in most cases in the future.
Differences between Middleware (Middleware) and Filter
Those familiar with the MVC framework should know that MVC also provides five filters for us to process the code that needs to be executed before and after the request. They areAuthenticationFilter
,AuthorizationFilter
,ActionFilter
,ExceptionFilter
,ResultFilter
.
According to the description, we can see that the middleware and filter functions are similar. What are their differences? Why is it necessary to build a middleware?
In fact, filters and middleware have different concerns. That is to say, they have different responsibilities and do different things.
For example, the middleware is like the blade of eshinos, and the filter is like the anger of the dragon. The Treasure of the treassa, you are a warrior holding the anger of the dragon, even though all the injuries are done to the battlefield, you still lose attribute because of the low damage caused by the Rolling Rod.
The same as the two AOP tools, the filter is more suitable for the business. It focuses on the application itself. For example, if you see ActionFilter and ResultFilter, it interacts directly with your Action and ActionResult, is it very close to you? I have some examples, such as formatting my output results and verifying the data of the ViewModel of my request. It must be a Filter. It is part of MVC. It can intercept some information about your Action context, and middleware does not have this capability.
What do we need middleware?
So when will middleware be used? My understanding is that some of the things that need to be done in the pipeline are usable in our applications, such as identity authentication, Session storage, and logging. In fact, our asp.net core project already contains many middleware.
For example, when creating an asp.net core application
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){ app.UseDeveloperExceptionPage(); app.UseStaticFiles(); loggerFactory.AddConsole(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });}
I am too lazy to download the source code. We use Reflector to view the source code:
// Extension Method 'app. useDeveloperExceptionPage (); 'public static class extends exceptionpageextensions {// Methods public static IApplicationBuilder UseDeveloperExceptionPage (this IApplicationBuilder app) {if (app = null) {throw new ArgumentNullException ("app");} return UseMiddlewareExtensions. useMiddleware <exceptionpagemiddleware> (app, Array. empty <object> () ;}// Extension Method 'app. useStaticFiles (); 'public static class StaticFileExtensions {// Methods public static IApplicationBuilder UseStaticFiles (this IApplicationBuilder app) {if (app = null) {throw new ArgumentNullException ("app");} return UseMiddlewareExtensions. useMiddleware <StaticFileMiddleware> (app, Array. empty <object> ());}}
We can see that app.UseDeveloperExceptionPage()
,app.UseStaticFiles()
And so on.
How to customize your own Middleware
Background: When middleware is used in our project, we need to share User information with other departments. Taking the platform and subsystem as an example, we are developing a sub-system where user information, login, registration and other functions are stored on the platform. This is a cross-language system developed in Java language, when you access some pages of the sub-system, you need to verify whether to log on. In other pages, you do not need to verify whether to log on. Therefore, you need an Identity verification system to replace the Identity function.
Fortunately, Microsoft has provided us with a set of authentication middleware.Microsoft.AspNetCore.Authentication
In the namespace, we only need to expand and add our own functions. How can this problem be solved? Check the Code directly.
According to conventions, the middleware class requires an Invoke method, and the signature ispublic async Task Invoke(HttpContext context){}
The following is an example of middleware class:
public class RequestLoggerMiddleware{ private readonly RequestDelegate _next; private readonly ILogger _logger; public RequestLoggerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger<RequestLoggerMiddleware>(); } public async Task Invoke(HttpContext context) { _logger.LogInformation("Handling request: " + context.Request.Path); await _next.Invoke(context); _logger.LogInformation("Finished handling request."); }}
After understanding the above conventions, we began to define our own middleware Class.
We need a flowchart to clarify the logic, so that the logic can be clearer when writing code.
One requirement of the platform is that after the sub-system exits, the user needs to call an interface of the platform to notify them that they want to do some follow-up services.
OK to start the verification code.
- First, create
PlatformAuthoricationMiddleware
It inherits fromMicrosoft.AspNetCore.Authentication
ClassAuthenticationMiddleware
, BecauseAuthenticationMiddleware
The Invoke function has been implemented, so we only need to override some methods in it. We also need some configuration, such as ReturnUrl In the flowchart, the Cookie Key value of the platform, and the interface address used to verify the user's validity.
- Create
Options
Class for configuration settings, we get the name:PlatformAuthenticationOptions
, InheritAuthenticationOptions
And implementIOptions<T>
Interface, so that you can directly configure it in Startup.
- We only need to rewrite
AuthenticationMiddleware
InCreateHandler
The method is enough. In Handler, we can implement the middleware function.
- Create a Handler class for processing and name it
PlatformAuthenticationHandler
, Inherited fromAuthenticationHandler<TOptions>
Used to process calls in the request.
So far, the core class we need has been established, and the rest is to fill in the code.
1. InPlatformAuthenticationHandler
RewriteHandleAuthenticateAsync()
Method to Control the main process.
2. InPlatformAuthenticationHandler
RewriteFinishResponseAsync()
Method To store sessions.
3. InPlatformAuthenticationHandler
RewriteHandleSignOutAsync()
Method, to control logout, because after the user logs out, we need to notify the platform to do some other operations.
4. InPlatformAuthenticationHandler
RewriteHandleUnauthorizedAsync()
Method.
Finally, we need an extension class to register our middleware to the pipeline using the extension method.
public static class MiddlewareExtensions{ public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException(nameof(app)); } return app.UseMiddleware<PlatformAuthenticationMiddleware>(); } public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app, CookieAuthenticationOptions options) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return app.UseMiddleware<PlatformAuthenticationMiddleware>(Options.Create(options)); }}
InStartup
Moderateapp.UsePlatformAuthentication()
Public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {loggerFactory. addConsole (Configuration. getSection ("Logging"); // register the PlatformAuthentication middleware app. usePlatformAuthentication (new PlatformAuthenticationOptions () {UserSessionStore = new UserSessionStore (),}); app. useMvc ();}
Now that the implementation of our core middleware business process has come out, I will paste the code in a short time, which will affect reading, if you are interested in the specific implementation, you can go to the following address to view the code, with a comment on the specific process.
Sample source code: demo
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.