如何传递参数给ASP.NET Core的中间件(Middleware)
问题描述
当我们在ASP.NET Core中定义和使用中间件(Middleware)的时候,有什么好的办法可以给中间件传参数吗?
解决方案
在ASP.NET Core项目中添加一个POCO类来传递参数到中间件,例如下面的GreetingOptions类
public class GreetingOptions
{
public string GreetAt { get; set; }
public string GreetTo { get; set; }
}
然后添加一个中间件GreetingMiddleware
public class GreetingMiddleware
{
private readonly RequestDelegate next;
private readonly GreetingOptions options; public GreetingMiddleware(
RequestDelegate next,
GreetingOptions options)
{
this.next = next;
this.options = options;
} public async Task Invoke(
HttpContext context)
{
var message = $"Good {this.options.GreetAt} {this.options.GreetTo}";
await context.Response.WriteAsync(message);
}
}
解决方案A:实例类型(Instance Type)
通过添加一个扩展方法类GreetingMiddlewareExtension,来配置中间件GreetingMiddleware,并传递参数GreetingOptions options
public static class GreetingMiddlewareExtension
{
public static IApplicationBuilder UseGreeting(this IApplicationBuilder app, GreetingOptions options)
{
return app.UseMiddleware<GreetingMiddleware>(options);
}
}
在ASP.NET Core项目中Startup类的Configure方法中,启用GreetingMiddleware中间件,并传递参数到中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseGreeting(new GreetingOptions
{
GreetAt = "Morning",
GreetTo = "Tahir"
});
}
解决方案B:方法类型(Function Type)
通过添加一个扩展方法类GreetingMiddlewareExtension,来配置中间件GreetingMiddleware,并通过委托Action<GreetingOptions> configureOptions来传递参数GreetingOptions
public static class GreetingMiddlewareExtension
{
public static IApplicationBuilder UseGreeting(this IApplicationBuilder app, Action<GreetingOptions> configureOptions)
{
var options = new GreetingOptions();
configureOptions(options); return app.UseMiddleware<GreetingMiddleware>(options);
}
}
在ASP.NET Core项目中Startup类的Configure方法中,启用GreetingMiddleware中间件,并通过委托Action<GreetingOptions>传递参数到中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseGreeting(options =>
{
options.GreetAt = "Morning";
options.GreetTo = "Tahir";
});
}
讨论
在前面的一篇文章中我们讨论了,定义和使用中间件(Middleware)的最好方法是,将中间件定义在一个单独的类中,然后通过扩展方法将其添加到ASP.NET Core的中间件管道(pipeline)中。
我们可以通过上面介绍的解决方案A和B,将需要传递到中间件的参数都封装为一个POCO类,并创建一个扩展方法,用下面两种方式作为扩展方法的参数:
注意:POCO实例是通过. UseMiddleware()方法的params object[]参数来传递到中间件的构造函数中的,也就是说我们可以通过params object[]来传递任意多个参数到中间件中,只要类型和中间件的构造函数参数匹配即可。我们还可以将依赖注入参数和POCO实例参数一起定义在中间件的构造函数中,如下所示:
public class GreetingMiddleware
{
private readonly RequestDelegate next;
private readonly GreetingOptions options; //IHostingEnvironment env是依赖注入参数,GreetingOptions options是POCO实例参数
public GreetingMiddleware(RequestDelegate next, IHostingEnvironment env, GreetingOptions options)
{
string environmentName = env.EnvironmentName; this.next = next;
this.options = options;
} public async Task Invoke(
HttpContext context)
{
var message = $"Good {this.options.GreetAt} {this.options.GreetTo}";
await context.Response.WriteAsync(message);
}
}
配置依赖注入服务
前面介绍的两种解决方案同样也可以用来配置依赖注入(dependency injection)服务的容器。
为了演示,我们先添加一个POCO类MessageOptions和用到的枚举MessageFormat
public enum MessageFormat
{
None,
Upper,
Lower
} public class MessageOptions
{
public MessageFormat Format { get; set; }
}
然后添加一个依赖注入接口IMessageService,及其实现类MessageService
public interface IMessageService
{
string FormatMessage(string message);
}
public class MessageService : IMessageService
{
private readonly MessageOptions options; public MessageService(MessageOptions options)
{
this.options = options;
} public string FormatMessage(string message)
{
// use options
return this.options.Format == MessageFormat.None ? message :
this.options.Format == MessageFormat.Upper ? message.ToUpper() :
message.ToLower();
}
}
同样,接下来我们就用两种解决方案,来定义MessageService的扩展方法类MessageServiceExtension
解决方案A:实例类型(Instance Type)
public static class MessageServiceExtension
{
// Instance Type
public static IServiceCollection AddMessageFormatter(this IServiceCollection services, MessageOptions options)
{
return services.AddScoped<IMessageService>(factory =>
{
return new MessageService(options);
});
}
}
在ASP.NET Core项目中Startup类的ConfigureServices方法中,注册IMessageService和MessageService的依赖注入服务
// Instance Type
public void ConfigureServices(IServiceCollection services)
{
services.AddMessageFormatter(new MessageOptions
{
Format = MessageFormat.Lower
});
}
解决方案B:方法类型(Function Type)
public static class MessageServiceExtension
{
// Function Type
public static IServiceCollection AddMessageFormatter(this IServiceCollection services, Action<MessageOptions> configureOptions)
{
var options = new MessageOptions();
configureOptions(options); return services.AddScoped<IMessageService>(factory =>
{
return new MessageService(options);
});
}
}
在ASP.NET Core项目中Startup类的ConfigureServices方法中,注册IMessageService和MessageService的依赖注入服务
// Function Type
public void ConfigureServices(IServiceCollection services)
{
services.AddMessageFormatter(options =>
{
options.Format = MessageFormat.Lower;
});
}
本文参考自:Passing Parameters to Middleware in ASP.NET Core 2.0
如何传递参数给ASP.NET Core的中间件(Middleware)的更多相关文章
- ASP.NET Core 开发-中间件(Middleware)
ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...
- asp.net core mvc 中间件之WebpackDevMiddleware
asp.net core mvc 中间件之WebpackDevMiddleware WebpackDevMiddleware中间件主要用于开发SPA应用,启用Webpack,增强网页开发体验.好吧,你 ...
- ASP.NET Core:中间件
一.什么是中间件 我们都知道,任何的一个web框架都是把http请求封装成一个管道,每一次的请求都是经过管道的一系列操作,最终才会到达我们写的代码中.而中间件就是用于组成应用程序管道来处理请求和响应的 ...
- asp.net core mvc 中间件之路由
asp.net core mvc 中间件之路由 路由中间件 首先看路由中间件的源码 先用httpContext实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合 然后把路由上下文 ...
- 如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容?
原文:如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容? 文章名称: 如何在ASP.NET Core自定义中间件读取Request.Body和 ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- ASP.NET Core路由中间件[3]: 终结点(Endpoint)
到目前为止,ASP.NET Core提供了两种不同的路由解决方案.传统的路由系统以IRouter对象为核心,我们姑且将其称为IRouter路由.本章介绍的是最早发布于ASP.NET Core 2.2中 ...
- ASP.NET Core路由中间件[2]: 路由模式
一个Web应用本质上体现为一组终结点的集合.终结点则体现为一个暴露在网络中可供外界采用HTTP协议调用的服务,路由的作用就是建立一个请求URL模式与对应终结点之间的映射关系.借助这个映射关系,客户端可 ...
- ASP.NET Core之中间件
本文翻译自:http://www.tutorialsteacher.com/core/aspnet-core-middleware 基本概念 ASP.NET Core引入了中间件的概念,中间件是在AS ...
随机推荐
- 【读书笔记】iOS-成为一名开发者
iOS开发者计划是按年付费的,在过期前60天可以开始续费.如果你不续费的话,你将无法发布应用.另外苹果会吊销你的开发者证书和发布证书.最后,苹果将你在iTunes App Store上的所有应用下架. ...
- 从零开始学习html(三) 认识标签(第二部分)
一.使用ul,添加新闻信息列表 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Ty ...
- 安卓开发中strings.xml的使用
为了使用方便也是为了代码规范化,我们都将文字信息放在res-values-strings.xml中, 因为开发中需要用到将文字的换行,百度了一下,可以将文字段信息直接在strings.xml文件中换行 ...
- 《Inside C#》笔记(十五) 非托管代码 上
为了保证向后兼容性,C#和.NET可以通过非托管的方式运行旧代码.非托管代码是指没有被.NET运行时管控的代码.非托管代码主要包括:平台调用服务(PlatformInvocation Services ...
- js replace替换 忽略大小写问题
实现就是控制台的内容“abc”,但是后台返回的是“ABC”,这个时候在前台遍历,需要将后台返回的在控制台标红. 当然控制台可以是 abc Abc等大小写混合,以下代码都可替换. var flagnew ...
- [20170623]利用传输表空间恢复数据库2.txt
[20170623]利用传输表空间恢复数据库2.txt --//继续上午的测试,测试truncate,是否可行,理论讲应该没有问题.我主要的目的测试是否要切换日志.--//参考链接 : http:// ...
- 洗礼灵魂,修炼python(12)--python关键词,包
关键词 1.什么是关键词: 就是系统已经定义好的一些关键词语法,可以直接使用,很明显的就是在IDE里这些关键词会高亮显示的就是 2.有哪些关键词: 前面我们一直在说关键词,内置函数,到底有哪些关键词对 ...
- 关于使用WeUI在IE中提示“font-face 未能完成 OpenType 嵌入权限检查。权限必须是可安装的。”的问题
@font-face是css3中定义字体的规则. 首先,在使用weui时,在Chrome.Firefox下没有问题,但是在IE下提示“font-face 未能完成 OpenType 嵌入权限检查.权限 ...
- 转:SQL Server - 使用 Merge 语句实现表数据之间的对比同步
表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...
- Nginx日志格式log_format详解
PS:Nginx日志相关指令主要有两条,一条是log_format,用来设置日志格式,另外一条是access_log,用来指定日志文件的存放路径.类型.缓存大小等,一般放在Nginx的默认主配置文件/ ...