当前位置:网站首页>ASP. Net 6 middleware series - Custom middleware classes
ASP. Net 6 middleware series - Custom middleware classes
2022-04-23 03:06:00 【Dotnet cross platform】
This article is ASP.NET 6 The first of a series of middleware articles 2 part , Click here to Read page 1 part .
In the last article , We discussed what middleware is , What is its role , And in ASP.NET 6 A simple way to add middleware to the application pipeline .
In this article , We will extend and build some custom middleware classes based on these .
The sample project
stay GitHub You can get the code involved in this article on :
https://github.com/zilor-net/ASPNET6Middleware/tree/Part2
Standard middleware architecture
With us in The first 1 part What you do in , Most of the time, we want middleware to be a separate class , Not in Program.cs Create in file .
Let's go back to the first 1 Partial content , A response “Hello Dear Readers!” The content of middleware ?
app.Run(async context =>
{
await context.Response.WriteAsync("Hello Dear Readers!");
});
Next , Let's create a custom middleware class to achieve the same effect .
Basic knowledge of middleware class
The following is an empty class , We will use this middleware :
namespace ASPNET6Middleware.Middleware
{
public class SimpleResponseMiddleware
{
}
}
The middleware class consists of three parts :
First , Any middleware class must have RequestDelegate
Private member instance of type , The instance is populated by the constructor of the class .
RequestDelegate
Represents the next Middleware in the pipeline :
namespace ASPNET6Middleware.Middleware
{
private readonly RequestDelegate _next;
public SimpleResponseMiddleware(RequestDelegate next)
{
_next = next;
}
}
secondly , This class must have a async Method InvokeAsync()
, It accepts a HttpContext
Type as its first argument :
public class SimpleResponseMiddleware
{
private readonly RequestDelegate _next;
public SimpleResponseMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
//...Implementation
}
}
Third , Middleware must have its own implementation . For this middleware , All we have to do is return a custom response :
public class SimpleResponseMiddleware
{
private readonly RequestDelegate _next;
public SimpleResponseMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
await context.Response.WriteAsync("Hello Dear Readers!");
}
}
Be careful : stay InvokeAsync()
In the method , Most middleware will call await next(context);
, Any middleware that does not do so will be a terminal middleware , It represents the end of the pipeline , The middleware behind it will not execute .
Add middleware to the pipeline
here , We can use UseMiddleware<>()
Method , Add this middleware class to Program.cs In the document app in :
app.UseMiddleware<LayoutMiddleware>();
For simple middleware classes , That's enough .
However , The more common way is to use the extension method , Instead of using it directly UseMiddleware<>()
, Because this can provide us with a more specific package :
namespace ASPNET6Middleware.Extensions
{
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseSimpleResponseMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<SimpleResponseMiddleware>();
}
}
}
Then we can use this extension method like this :
app.UseSimpleResponseMiddleware();
Both methods are correct , But I personally prefer the clarity and readability of the extension method .
Build logging middleware
stay The first 1 part I introduced , One of the most common scenarios for middleware is logging , In particular, record the request path or response header 、 Response body, etc .
LoggingService class
We will build a logging middleware class , It only does two things :
Record the request path .
Record the unique response header .
First , We have to create interfaces ILoggingService
And the class LoggingService
.
namespace ASPNET6Middleware.Logging
{
public class LoggingService : ILoggingService
{
public void Log(LogLevel logLevel, string message)
{
// The specific implementation of log is omitted
}
}
public interface ILoggingService
{
public void Log(LogLevel level, string message);
}
}
Then we need to be in Program.cs Lieutenant general LoggingService
Added to the application Services
Collection :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddTransient<ILoggingService, LoggingService>();
Middleware classes can also inject services like ordinary classes .
LoggingMiddleware class
Now we need a LoggingMiddleware
Class to log .
First , Let's make LoggingMiddleware
Class to create a good middleware structure , It accepts a in the constructor ILoggingService
As a parameter :
namespace ASPNET6Middleware.Middleware
{
public class LoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILoggingService _logger;
public LoggingMiddleware(RequestDelegate next, ILoggingService logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
//...
}
}
}
Our task is to record the path of the request and the unique header of the response , This means that await next(context)
There is code before and after :
namespace ASPNET6Middleware.Middleware
{
public class LoggingMiddleware
{
//..
public async Task InvokeAsync(HttpContext context)
{
// Record the incoming request path
_logger.Log(LogLevel.Information, context.Request.Path);
// Call the next Middleware in the pipeline
await _next(context);
// Get a unique response header
var uniqueResponseHeaders
= context.Response.Headers
.Select(x => x.Key)
.Distinct();
// Record the response header name
_logger.Log(LogLevel.Information, string.Join(", ", uniqueResponseHeaders));
}
}
}
take LoggingMiddleware Add to pipe
Because I prefer to use the extension method to add middleware to the pipeline , Let's create a new extension method :
namespace ASPNET6Middleware.Extensions
{
public static class MiddlewareExtensions
{
//...
public static IApplicationBuilder UseLoggingMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<LoggingMiddleware>();
}
}
}
Last , We need to be in Program.cs Middle note invocation of our new extension method , take LoggingMiddleware
Class is added to the pipeline :
app.UseLoggingMiddleware();
When we run the application , We can see the code ( Through breakpoints ) The request path and response header can be recorded correctly .
In the next article in this series , We will talk about the execution sequence of middleware , Show a new middleware that records execution time , It also discusses some common problems that may occur when creating middleware pipelines .
版权声明
本文为[Dotnet cross platform]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230301333918.html
边栏推荐
- Detailed explanation of distributed things
- 编码电机PID调试(速度环|位置环|跟随)
- Middle and rear binary tree
- Introduction to ACM [inclusion exclusion theorem]
- .NET7之MiniAPI(特别篇):.NET7 Preview3
- tf. keras. layers. Inputlayer function
- Due to 3 ²+ four ²= five ², Therefore, we call '3,4,5' as the number of Pythagorean shares, and find the array of all Pythagorean shares within n (including n).
- Numpy append function
- Traversal of l2-006 tree (middle and later order determination binary tree & sequence traversal)
- C read / write binary file
猜你喜欢
Introduction to ACM [TSP problem]
tf. keras. layers. MaxPooling? D function
Thoughts on the 2022 national network security competition of the national secondary vocational group (only one idea for myself) - network security competition questions (8)
Er and eer models
ASP.NET 6 中间件系列 - 执行顺序
微软是如何解决 PC 端程序多开问题的——内部实现
宁德时代地位不保?
C#中切片语法糖的使用
Traversal of l2-006 tree (middle and later order determination binary tree & sequence traversal)
tf. keras. layers. Timedistributed function
随机推荐
Golden nine silver ten interview season, you are welcome to take away the interview questions (with detailed answer analysis)
ASP.NET 6 中间件系列 - 执行顺序
Binary tree
tf. keras. layers. Embedding function
c#可变参数params的介绍
Recommend reading | share the trader's book list and ask famous experts for trading advice. The trading is wonderful
The whole network is the most complete. How to do interface automation test? Proficient in interface automation test details
Niuke white moon race 5 [problem solving mathematics field]
MYSQL03_ SQL overview, rules and specifications, basic select statements, display table structure
C# 读写二进制文件
Thoughts on the 2022 national network security competition of the national secondary vocational group (only one idea for myself) - network security competition questions (10)
Realize QQ login with PHP
Laravel new route file
Assembly learning Chapter III of assembly language (Third Edition) written by Wang Shuang
Thoughts on the 2022 national network security competition of the national secondary vocational group (only one idea for myself) - network security competition questions (9)
微软是如何解决 PC 端程序多开问题的——内部实现
HLS / chisel uses CORDIC hyperbolic system to realize square root calculation
Ningde's position in the times is not guaranteed?
最通俗易懂的依赖注入与控制反转
编码电机PID调试(速度环|位置环|跟随)