NET core middleware and the preface to the actual project
In the previous article mainly introduced the status of Dotnetcore project, this article is in the development of their own projects in the actual use, compared to the actual application, is a deep use of middleware, not a simple Hello world, if you think this article is useful to you, may wish to point a "recommended 】。
Directory
- The role of middleware (middleware)
- How the Middleware Works
- The difference between middleware (middleware) and filters (filter)
- What situation do we need middleware
- How to customize your own middleware
The role of middleware (middleware)
We know that any web framework is encapsulating HTTP requests into a single pipeline, and each request is a pipeline of operations that eventually arrive in the code we write. Then the middleware is a component in the application pipeline that intercepts the request process for some other processing and response. Middleware can have many, each middleware can intercept requests in the pipeline, it can decide whether to transfer the request to the next middleware.
ASP. NET core provides an IApplicationBuilder
interface for registering middleware with ASP. NET pipeline request, middleware is a typical AOP application. Here is a Microsoft Official middleware Pipeline request diagram:
As you can see, each middleware can be manipulated before and after the request. The request processing is completed and passed to the next request.
How the Middleware Works
By default, the order in which the middleware is executed is performed according to the order in which the Startup.cs
files are registered in the public void Configure(IApplicationBuilder app){}
method.
There are about 3 ways to register "middleware" in a pipeline
app.Use()
, the IApplicationBuilder
interface is native to provide, register, etc. use it.
app.Run()
, is an extension method that requires a RequestDelegate
delegate that contains the context information for the HTTP, without the next parameter because it is always executed at the end of the pipeline.
app.Map()
, is also an extension method, similar to the MVC route, the use is usually some special request path processing. such as: Www.example.com/token and so on.
The above run,map is also called the use of the Iapplicationbuilder interface expansion, if you think the name is not accurate, then the following extension method is the authentic registration middleware, but also the most powerful.
app.UseMiddleware<>()
Yes, that's it. Why do you say powerful? Because it not only provides the function of registering middleware, but also provides the function of dependency injection (DI), which is used in most cases later.
The difference between middleware (middleware) and filters (filter)
Students familiar with the MVC framework should know that MVC also provides 5 filters for the code we need to execute before and after the request. The distinction is,,, AuthenticationFilter
AuthorizationFilter
ActionFilter
ExceptionFilter
, ResultFilter
.
According to the description, you can see that the middleware and filter functions are similar, then what is the difference between them? Why do we have to do a middleware again?
In fact, filters and middleware their focus is not the same, that is, the responsibility is different, do things differently.
For a chestnut, middleware like 埃辛诺斯战刃
, filter like 巨龙之怒,泰蕾苟萨的寄魂杖
, you a warrior 巨龙之怒,泰蕾苟萨的寄魂杖
to take to the battlefield to kill, although all have hurt, but you take the staff hurt low do not say, also minus the attributes ah.
As a two AOP tool, the filter is more business-focused, it focuses on the application itself, such as you see ActionFilter
and ResultFilter
, it is directly with your action,actionresult interaction, is not very close to you, then I have some such as the output of my results are formatted, The ViewModel of my request is verified by the data, it must be with the filter undoubtedly. It's part of MVC, it can intercept some information about your action context, and middleware doesn't have that ability.
What situation do we need middleware
So when is middleware used? My understanding is that some of the things that need to be done in the pipeline, such as authentication, session storage, logging, and so on, are in our applications and business relationships are small. In fact, our ASP. NET core project itself already contains a lot of middleware.
For example, when creating a new ASP. NET core application, the default generated template
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?}"); });}
Too lazy to download the source code, we use reflector to view the source code:
Extension method ' app. Usedeveloperexceptionpage (); 'public static class developerexceptionpageextensions{//Methods < Span class= "Hljs-keyword" >public static iapplicationbuilder Usedeveloperexceptionpage (this IApplicationBuilder app) { Span class= "Hljs-keyword" >if (app = = null) {throw new ArgumentNullException (return usemiddlewareextensions.usemiddleware<developerexceptionpagemiddleware> (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> ()); }}
Can be seen app.UseDeveloperExceptionPage()
, and app.UseStaticFiles()
so on are implemented through the middleware.
How to customize your own middleware
Background: The scenario in which our project uses middleware is the need to share user information with other departments. To the platform and subsystem example, we are developing a subsystem, wherein the user information, login, registration and other functions are placed on the platform, which is a multi-lingual system, the platform is the Java language development, users in the access to some of the subsystem's pages need to verify whether to log on, Other pages do not require authentication to log in, so an authentication system is required in place of the identity feature.
Fortunately, Microsoft has provided us with a set of authentication middleware, in the Microsoft.AspNetCore.Authentication
namespace, we just need to expand, add their own features on the line. How do you do it specifically? Look directly at the code.
According to the conventional, the middleware class needs to have an invoke method, the signature is public async Task Invoke(HttpContext context){}
, the following is an example of a middleware class:
PublicClassrequestloggermiddleware{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.")}}
Having understood the above conventions, we began to define our own middleware class.
We need a flowchart to clear up the logic, so that the idea of writing code is clearer.
The platform has a requirement that the user after our subsystem exits, to invoke the platform of an interface to notify them that they want to do some follow-up business.
OK, start the code.
- First create a
PlatformAuthoricationMiddleware
, it inherits from the Microsoft.AspNetCore.Authentication
next class AuthenticationMiddleware
, because the AuthenticationMiddleware
invoke function has been implemented, so we just need to rewrite (override) Some of the methods inside it. Wait, we seem to need some configuration, such as the ReturnUrl in the flowchart, the key value of the platform's cookie, and the interface address of the platform to verify the user's legitimacy.
- Set up an options class to configure the settings, we take the name:
PlatformAuthenticationOptions
, Inherit AuthenticationOptions
, and implement the IOptions<T>
interface, this can be directly configured in startup.
- We just need to rewrite
AuthenticationMiddleware
the CreateHandler
method in the line, in the handler can achieve the function of our middleware.
- It then creates a processing handler class, named
PlatformAuthenticationHandler
, that inherits the AuthenticationHandler<TOptions>
call that is used to process the request.
At this point, our core needs of the class has been established, the rest is to fill the code.
- In the
PlatformAuthenticationHandler
override HandleAuthenticateAsync()
method, the master process is controlled.
- In the
PlatformAuthenticationHandler
override FinishResponseAsync()
method, the session is stored operations.
- In the
PlatformAuthenticationHandler
override HandleSignOutAsync()
method, do the logout control, because after the user log out we have to notify the platform to do some other things.
- In the
PlatformAuthenticationHandler
override HandleUnauthorizedAsync()
method, do not authenticate the operation.
Finally, we need an extension class to register our middleware in the pipeline with extension methods.
PublicStaticClassmiddlewareextensions{PublicStatic IapplicationbuilderUseplatformauthentication (This iapplicationbuilder app) {if (app = =NULL) {ThrowNew 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)); }}
In the Startup
middle isapp.UsePlatformAuthentication()
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); //注册PlatformAuthentication中间件 app.UsePlatformAuthentication(new PlatformAuthenticationOptions() { UserSessionStore = new UserSessionStore(), }); app.UseMvc();}
Now, the implementation of our middleware core business process has come out, I have not much space to paste the code, will affect the reading, interested in the implementation of the specific friends can go to the following address to view the code, there are specific process comments.
Sample source code:
Https://github.com/yuleyule66/PlatformAuthMiddleware
This address: http://www.cnblogs.com/savorboard/p/5586229.html
NET core middleware and project combat