.NET 6版本中间件的使用

.NET 6版本中间件的使用

中间件是一种处理HTTP请求和响应的可重用组件,通常用于添加处理逻辑或修改请求和响应。本文将演示如何创建.NET 6版本的中间件。

创建中间件

让我们从创建一个简单的中间件类开始。我们将打印请求的URL,然后调用下一个中间件:

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine($"[MyMiddleware] URL: {context.Request.Path}");

        await _next(context);
    }
}

在上面的代码中,我们定义了一个MyMiddleware类,它实现了InvokeAsync方法。在这个方法中,我们打印了请求的URL,并调用下一个中间件。

注册中间件

在.NET 6中,注册中间件的方式也类似于.NET 5。我们可以将我们的中间件添加到应用程序的请求处理管道中。

builder.UseMiddleware<MyMiddleware>();

请注意,上面的代码应该在app.UseRouting()之后调用,但在app.UseEndpoints()之前。

完整的Program.cs文件如下所示:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseMiddleware<MyMiddleware>();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

app.Run();

在上面的代码中,我们将MyMiddleware添加到了请求处理管道中。然后我们添加了一些其他的中间件,例如HTTPS重定向和静态文件服务。

测试中间件

现在我们已经完成了自己的中间件,我们来测试它。

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            ...
        })
        .ToArray();
    }
}

上面的代码中,我们创建了一个简单的WeatherForecastController,其中有一个Get()操作。我们将在这个操作中测试我们的中间件。

通过调用Swagger UI来测试应用程序:

  • 在浏览器中导航到https://{your_host}/swagger/index.html
  • 选择“GET WeatherForecast”操作,然后单击“Try it out”按钮。
  • 单击“Execute”按钮。

您应该看到控制台输出我们的自定义中间件的URL:

[MyMiddleware] URL: /WeatherForecast

中间件的顺序

在注册多个中间件时,它们的顺序非常重要。请求将从第一个中间件开始处理,然后逐个传递到下一个中间件,直到到达最后一个中间件,然后响应将根据这些中间件的顺序返回。在.NET 6中,您可以通过调用 UseMiddleware<T>UseMiddleware 方法添加多个中间件。

例如,让我们创建一个新的中间件类,以便我们可以测试中间件的顺序:

public class MySecondMiddleware
{
    private readonly RequestDelegate _next;

    public MySecondMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine("[MySecondMiddleware] Start");

        await _next(context);

        Console.WriteLine("[MySecondMiddleware] End");
    }
}

在上面的代码中,我们定义了一个名为MySecondMiddleware的新中间件类,它与MyMiddleware类非常相似。它在请求处理管道的开头打印了消息,然后在请求处理管道的结尾打印了另一个消息。

现在,我们可以将两个中间件添加到应用程序中:

app.UseMiddleware<MyMiddleware>();
app.UseMiddleware<MySecondMiddleware>();

您应该注意到,我们添加了 MyMiddlewareMySecondMiddleware 中间件,它们的顺序是有意义的,因为它们将按照注册的顺序依次处理请求。

如果我们在测试控制器方法时,您会看到控制台输出,它显示请求和响应在两个中间件中传递。输出如下:

[MyMiddleware] URL: /WeatherForecast
[MySecondMiddleware] Start
[MySecondMiddleware] End

您可以看到,请求通过了 MyMiddleware 中间件,然后通过 MySecondMiddleware 中间件。注意消息的顺序是相反的,因为我们将它们注册成了相反的顺序。

控制中间件的流程

在.NET 6中,我们可以通过终止请求来控制中间件流程。如果我们需要在请求处理管道中停止中间件的处理过程,则可以使用 HttpContext.Abort() 方法。

例如,让我们为我们的控制器方法添加一些逻辑,并在中间件中检查该逻辑。如果条件不满足,我们将终止请求处理过程。

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        if (id < 1 || id > 5)
        {
            return BadRequest("Invalid ID");
        }

        return Ok(Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            ...
        }).ToArray());
    }
}

在上面的代码中,我们更改了 Get() 操作以检查传递的 id 值。如果 id 不在1到5的范围内,则返回400响应。

现在,让我们在 MyMiddleware 中间件中添加一些逻辑,以检查请求是否是有效请求。

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine($"[MyMiddleware] URL: {context.Request.Path}");

        if (context.Request.Path == "/WeatherForecast/2")
        {
            context.Response.StatusCode = StatusCodes.Status404NotFound;
            await context.Response.WriteAsync("Resource not found");
            return;
        }

        await _next(context);
    }
}

在上面的代码中,我们添加了一个检查,如果URL是 /WeatherForecast/2,则返回404响应并终止请求处理过程。

现在,当我们通过查找 /WeatherForecast/2 在浏览器中测试应用程序时,我们应该收到 Resource not found 响应。并且应用程序将在 MyMiddleware 中间件中止请求处理过程。

总结:

在本文中,我们演示了如何在.NET 6中创建和使用中间件,并介绍了如何控制中间件的顺序。中间件是.NET Web应用程序中非常有用的组件,它允许我们轻松地处理请求和响应。注意中间件的注册顺序是非常重要的,尤其是在使用多个中间件的情况下。我们还演示了如何将自定义逻辑添加到控制器方法中,并在中间件中检查该逻辑。中间件是.NET Web应用程序非常有用的组件,并且.NET 6为中间件的处理带来了更多的灵活性。

posted @ 2023-04-08 14:10  做梦的努力者  阅读(128)  评论(0编辑  收藏  举报