首页 > 编程语言 >写入自定义 ASP.NET Core 中间件

写入自定义 ASP.NET Core 中间件

时间:2024-05-26 11:22:16浏览次数:24  
标签:Core builder 自定义 app 中间件 next context public

中间件是一种装配到应用管道以处理请求和响应的软件。 ASP.NET Core 提供了一组丰富的内置中间件组件,但在某些情况下,你可能需要写入自定义中间件。

自定义中间件类

通常,中间件封装在类中,并且通过扩展方法公开。

一、内联中间件(不推荐)

 

请考虑以下内联中间件,该中间件通过查询字符串设置当前请求的区域性:

using System.Globalization;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseHttpsRedirection();
//内联中间件
app.Use(async (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.
    await next(context);
});

app.Run(async (context) =>
{
    await context.Response.WriteAsync(
        $"CurrentCulture.DisplayName: {CultureInfo.CurrentCulture.DisplayName}");
});

app.Run();

 

Use 扩展可以使用两个重载:

  • 一个重载采用 HttpContext 和 Func<Task>。 不使用任何参数调用 Func<Task>
  • 另一个重载采用 HttpContext 和 RequestDelegate。 通过传递 HttpContext 调用 RequestDelegate

二、中间件封装在类中(推荐)

using System.Globalization;

namespace Middleware.Example;

public class RequestCultureMiddleware
{
    private readonly RequestDelegate _next;

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

    public async Task InvokeAsync(HttpContext context)
    {
        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);
    }
}

public static class RequestCultureMiddlewareExtensions
{
    public static IApplicationBuilder UseRequestCulture(
        this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<RequestCultureMiddleware>();
    }
}

 

中间件类(RequestCultureMiddleware)必须包括:

  • 具有类型为 RequestDelegate 的参数的公共构造函数。
  • 名为 Invoke 或 InvokeAsync 的公共方法。 此方法必须:
    • 返回 Task
    • 接受类型 HttpContext 的第一个参数。

构造函数和 Invoke/InvokeAsync 的其他参数由依赖关系注入 (DI) 填充。

通过 Program.cs 调用中间件:

using Middleware.Example;
using System.Globalization;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseHttpsRedirection();

app.UseRequestCulture();

app.Run(async (context) =>
{
    await context.Response.WriteAsync(
        $"CurrentCulture.DisplayName: {CultureInfo.CurrentCulture.DisplayName}");
});

app.Run();

中间件依赖项

中间件应通过在其构造函数中公开其依赖项来遵循显式依赖项原则。 在每个应用程序生存期构造一次中间件。

中间件组件可通过构造函数参数从依赖关系注入 (DI) 解析其依赖项。 此外,UseMiddleware 还可直接接受其他参数。

按请求中间件依赖项

中间件在应用启动时构造,因此具有应用程序生存期。 在每个请求过程中,中间件构造函数使用的范围内生存期服务不与其他依赖关系注入类型共享。 若要在中间件和其他类型之间共享范围内服务,请将这些服务添加到 InvokeAsync 方法的签名。 InvokeAsync 方法可接受由 DI 填充的其他参数:

namespace Middleware.Example;

public class MyCustomMiddleware
{
    private readonly RequestDelegate _next;

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

    // IMessageWriter is injected into InvokeAsync
    public async Task InvokeAsync(HttpContext httpContext, IMessageWriter svc)
    {
        svc.Write(DateTime.Now.Ticks.ToString());
        await _next(httpContext);
    }
}

public static class MyCustomMiddlewareExtensions
{
    public static IApplicationBuilder UseMyCustomMiddleware(
        this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyCustomMiddleware>();
    }
}

 生存期和注册选项包含范围内生存期服务的中间件的完整示例。

以下代码用于测试以上中间件:

using Middleware.Example;
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddScoped<IMessageWriter, LoggingMessageWriter>();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseMyCustomMiddleware();

app.MapGet("/", () => "Hello World!");

app.Run();

  IMessageWriter 接口和实现:

namespace Middleware.Example;

public interface IMessageWriter
{
    void Write(string message);
}

public class LoggingMessageWriter : IMessageWriter
{

    private readonly ILogger<LoggingMessageWriter> _logger;

    public LoggingMessageWriter(ILogger<LoggingMessageWriter> logger) =>
        _logger = logger;

    public void Write(string message) =>
        _logger.LogInformation(message);
}

  

 

  

 

 

标签:Core,builder,自定义,app,中间件,next,context,public
From: https://www.cnblogs.com/friend/p/18213442

相关文章

  • sqlite 不支持毫秒怎么办,可以用sqlalchemy自定义类型
    fromsqlalchemyimportDECIMAL,Index,String,Date,Integer,Text,CHAR,SmallInteger,Float,Time,case,and_,extract,Boolean,Enum,TypeDecorator#自定义类型classDateTimeString(TypeDecorator):impl=Stringdefprocess_bind_param(self,value......
  • 自定义一个SpringBoot场景启动器
    前言一个刚刚看完SpringBoot自动装配原理的萌新依据自己的理解写下的文章,如有大神发现错误,敬请斧正,不胜感激。分析SpringBoot自动配置原理SpringBoot的启动从被@SpringBootApplication修饰的启动类开始,@SpringBootApplicaiotn注解中最重要的注解是@EnableAutoConfigurat......
  • .NET Core中给上传图片的添加水印
    一.安装System.Drawing.Common库工具->NuGet包管理->程序包管理控制台输入命令Install-PackageSystem.Drawing.Common二.代码案例实现usingMicrosoft.AspNetCore.Http;usingMicrosoft.AspNetCore.Mvc;usingSystem.Drawing;usingSystem.Drawing.Imaging;usingSy......
  • 2024永久免费破解版CorelDRAW汉化百度云网盘下载
     CorelDRAW®GraphicsSuite2024无疑是一款配备齐全的专业设计工具包,它以其卓越的性能和丰富的功能,为设计师们提供了高效且令人惊艳的矢量插图、布局、照片编辑和排版项目。这款软件套件不仅功能强大,而且价格实惠,用户可以通过订阅的方式获得持续的价值。订阅CorelDRAW®Gr......
  • Vue3实战笔记(40)—组件逻辑复用:自定义Hooks的完全指南
    文章目录前言一、状态管理二、副作用处理三、生命周期钩子总结前言自定义Hooks是Vue3中的一个重要特性,它允许您创建可重用的函数,以便在组件之间共享状态和逻辑。以下是一些关于自定义Hooks的常见用法。一、状态管理使用reactive或ref来创建响应式数据,并在组件中......
  • aspnetcore插件开发dll热加载 二
    这一篇文章应该是个总结。投简历的时候是不是有人问我有没有abp的开发经历,汗颜!在各位大神的尝试及自己的总结下,还是实现了业务和主机服务分离,通过dll动态的加载卸载,控制器动态的删除添加。项目如下: 演示效果: 下面就是代码部分:重点1.IActionDescriptorChangeProvider......
  • HarmonyOS 鸿蒙应用开发 - 创建自定义组件
     开发者定义的称为自定义组件。在进行UI界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。1、创建自定义组件1、组件必须使用 @Component 修......
  • C++ 组含子项自定义排序通用设计
    #include<memory>classBase;usingBaseSp=std::shared_ptr<Base>;classBase{public:  explicitBase(intid):ID(id){}  intID;};classSorter{public:  virtualboolsort(constBaseSp&l,constBaseSp&r){returntrue;......
  • Mybatis-plus核心功能-自定义SQL
    MyBatis-Plus提供了强大的条件构造器。通过条件构造器可以写一些复杂的SQL语句,从而提高我们的开发效率。通过EntityWrapper(简称EW,MP封装的一个查询条件构造器)或者Condition(与EW类似)来让用户自由的构建查询条件,简单便捷,没有额外的负担,能够有效提高开发效率,它主要用于处理......
  • Android 背景资源自定义 ShapeDrawble
    前言制作随时可以编辑的背景图,不需要向UI要背景图。【规则的】ShapeDrawable 是绘制形状的Drawable,定义了基本的几何图形,如(矩形,圆形,线条等)ShapeDrawable 根元素是 <shape/>效果图分别四种形状情况:ectangle(矩形)、oval(椭圆,包括圆)、line(线段)、ring(环形)......