Startup 和 Middleware(中间件)
在上一节(文章链接)中提到ASP.NET Core WebApp 必须含有Startup类,在本节中将重点讲解Startup类以及Middleware(中间件)在Startup类中的使用。
Startup Class
Startup Class中含有两个重要方法:Configure方法用于每次http请求的处理,比如后面要讲的中间件(Middleware),就是在configure方法中配置。而ConfigureServices方法在Configure方法前调用,它是一个可选的方法,可在configureServices依赖注入接口或一些全局的框架,比如EntityFramework、MVC等。Startup 类的 执行顺序:构造 -> configureServices->configure
。
1、Startup Constructor(构造函数)
主要实现一些配置的工作,方法参数如下:
-
IHostingEnvironment
: 用于访问应用程序的特殊属性,比如applicationName
,applicationVersion
。通过IHostingEnvironment
对象下的属性可以在构造中实现配置工作。比如获取当前根路径找到配置json文件地址,然后ConfigurationBuilder初始化配置文件,最后可以通过GetSection()方法获取配置文件。代码清单如下:
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json");
var configuration = builder.Build();
var connStr = configuration.GetSection("Data:DefaultConnection:ConnectionString").Value;
根目录下的配置文件如下:
{
"Data": {
"DefaultConnection": {
"ConnectionString": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;"
}
}
}
-
ILoggerFactory
: 提供创建日志的接口,可以选用已经实现接口的类或自行实现此接口,下面代码使用最简单的控制台作为日志输出。
public Startup(IHostingEnvironment env, ILoggerFactory logger)
{
var log = logger.CreateLogger("default");
logger.AddConsole();
log.LogInformation("start configure");
}
2、ConfigureServices
主要实现了依赖注入(DI)的配置,方法参数如下:
- IServiceCollection:整个ASP.NET Core 默认带有依赖注入(DI),IServiceCollection是依赖注入的容器,首先创建一个类(Foo)和接口(IFoo),代码清单如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1
{
public interface IFoo
{
string GetFoo();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1
{
public class Foo : IFoo
{
public string GetFoo()
{
return "foo";
}
}
}
在ConfigureServices 中将接口和实现注入至容器
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IFoo, Foo>();
}
如果想在每次Http请求后都使用IFoo的GetFoo()方法来处理,上面讲到可以在Configure方法中注册函数,在注册过程中由于使用了依赖注入(DI),因此可以直接通过RequestServices.GetRequiredService<IFoo>()
泛型方法将IFoo对象在容器中取出。
app.Run((context) =>
{
var str = context.RequestServices.GetRequiredService<IFoo>().GetFoo();
return context.Response.WriteAsync(str);
});
除了自己的接口外,还支持通过扩展方法添加更多的注入方法,比如EntityFramework、mvc框架都实现自己的添加方法。
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IFoo, Foo>();
}
3、Configure方法
主要是http处理管道配置和一些系统配置,参数如下:
-
IApplicationBuilder
: 用于构建应用请求管道。通过IApplicationBuilder下的run方法传入管道处理方法。这是最常用方法,对于一个真实环境的应用基本上都需要比如权限验证、跨域、异常处理等。下面代码调用IApplicationBuilder.Run方法注册处理函数。拦截每个http请求,输出Hello World。
public void Configure(IApplicationBuilder app)
{
app.Run((context) => context.Response.WriteAsync("Hello World!"));
}
IHostingEnvironment
: 同构造参数ILoggerFactory
: 同构造参数
Middleware
中间件是一个处理http请求和响应的组件,多个中间件构成了处理管道(Handler pipeline),每个中间件可以决定是否传递至管道中的下一中间件。一旦注册中间件后,每次请求和响应均会被调用。
1、中间件注册
中间件的注册在startup中的Configure方法完成,在configure方法中使用IApplicationBuilder对象的Run、Map、Use方法传入匿名委托(delegate)。上文示例注册IFoo.GetFoo()方法就是一个典型的中间件。
- Run & Use: 添加一个中间件至请求管道。它们在功能很类似但是也存在一些区别,先来看下两个方法的定义。
public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware);
public static void Run(this IApplicationBuilder app, RequestDelegate handler);
Run是通过扩展方法语法来定义,传入入参是RequestDelegate的委托,执行完一个第一个run后是不会激活管道中的第二个run方法,这样代码执行结果只会输出一个“hello world!”
app.Run((context) => context.Response.WriteAsync("Hello World!"));
app.Run((context) => context.Response.WriteAsync("Hello World 1!"));
而use方法的入参则是Func<>的委托包含两个入参和一个返回值,这样在第一个函数执行完成后可以选择是否继续执行后续管道中的中间件还是中断。
app.Use((context, next) =>
{
context.Response.WriteAsync("ok");
return next();
});
app.Use((context, next) =>
{
return context.Response.WriteAsync("ok");
});
- Map: 含有两个参数pathMatche和configuration,通过请求的url地址匹配相应的configuration。例如可以将url路径是/admin的处理函数指定为如下代码:
app.Map("/admin", builder =>
{
builder.Use((context, next) => context.Response.WriteAsync("admin"));
});
2、常用中间件
Middleware | 功能描述 |
---|---|
Authentication | 提供权限支持 |
CORS | 跨域的配置 |
Routing | 配置http请求路由 |
Session | 管理用户会话 |
Static Files | 提供对静态文件的浏览 |
这里有一些官方的示例,链接
以上内容有任何错误或不准确的地方请大家指正,不喜勿喷!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。
参考链接
[1] https://docs.asp.net/en/latest/fundamentals/middleware.html
[2] http://www.talkingdotnet.com/app-use-vs-app-run-asp-net-core-middleware/
Startup 和 Middleware(中间件)的更多相关文章
-
ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件)
ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件) Startup Class 1.Startup Constructor(构造函数) 2.Configure ...
-
ASP.NET MVC随想录——创建自定义的Middleware中间件
经过前2篇文章的介绍,相信大家已经对OWIN和Katana有了基本的了解,那么这篇文章我将继续OWIN和Katana之旅——创建自定义的Middleware中间件. 何为Middleware中间件 M ...
-
创建自定义的Middleware中间件
创建自定义的Middleware中间件 阅读目录 何为Middleware中间件 使用Inline方式注册Middleware 使用Inline+ AppFunc方式注册Middleware 定义原生 ...
-
Django中Middleware中间件
Django中Middleware中间件 1 Middleware中间件概述 django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法.实际上当 ...
-
.Net Core:Middleware中间件管道
.NetCore中的Middleware是装配到管道处理请求和响应的组件:每个组件都可以决定是否继续进入下一个管道.并且可以在进入下一个管道前后执行逻辑: 最后一个管道或者中断管道的中间件叫终端中间件 ...
-
Django分析之Middleware中间件
写了几周的脚本,今天终于开始接触web框架了~学习Python的web框架,那么Django就几乎是必修课了,这次的工作是先打打下手,主要的任务是在setting中添加版本号,在渲染静态css,js的 ...
-
Express ( MiddleWare/中间件 路由 在 Express 中使用模板引擎 常用API
A fast, un-opinionated, minimalist web framework for Node.js applications. In general, prefer simply ...
-
Django中的MiddleWare中间件
1. middleware简介 Django的middleware的概念相当于SSH框架里面的filter的概念.中间键的作用就是对所有的request,在request前,和在response后做一 ...
-
Jerry的CRM Middleware(中间件)文章合集
我在SAP成都研究院做过的CRM中间件的项目其实并不是很多: 1. 2013年下半年和2014年上半年曾经支持过中联重科和蒙牛的CRM项目相关的中间件问题; 2. 2014年上半年做过一个CRM物料主 ...
随机推荐
-
mm/memory
/* * linux/mm/memory.c * * Copyright (C) 1991, 1992 Linus Torvalds */ /* * demand-loading started ...
-
jwplayer 网页在线播放插件
1.到官网 https://www.jwplayer.com/ 注册,取得key并下载免费版本(免费版只支持mp4格式): 2.编辑如下网页即可在线播放: <!DOCTYPE html> ...
-
hdu 4619 Warm up 2_最大独立集
三个人整个下午都想不出这题 后来看题解,竟然用匈牙利算法的最大独立集,我顿时晕了. 题意:给竖着和横着的方块,除去重叠的,最多能留下几个方块 #include <cstdlib> #inc ...
-
java SimpleDateFormat日期与时间戳的相互转换
自我总结,有什么不到位的地方,各位可以帮忙纠正补充一下,感激不尽! 目的:SimpleDateFormat类可以很随意的组合日期时间的格式,不止单纯的yyyy-MM-dd这种格式 废话不多说,上代码 ...
-
Vue-admin工作整理(十九):从数字渐变组件谈第三方JS库Count-to的使用
1.组件封装基础 npm install countup@latest 2.组件中使用id值 3.组件中获得dom 如何封装一个组件,在组件中用到需要传入HTML元素ID值的JS库时如何处理,如何获取 ...
-
4. svg学习笔记-文档结构元素和样式的使用
svg除了绘图元素之外还有一部分是专门用于文档结构的,这类元素有<g>,<use>,<defs>,<symbol>等 <g>元素 如果我们仅 ...
-
scroll滚动条样式修改
一般我们有两种情况会出现滚动条,一种是overflow,一种是使用scroll. 当我们需要改变这个滚动条样式的时候,我们需要做以下的修改: html: <div id="style- ...
-
2018-2019-1 20189221 《Linux内核原理与分析》第八周作业
2018-2019-1 20189221 <Linux内核原理与分析>第八周作业 实验七 编译链接过程 gcc –e –o hello.cpp hello.c / gcc -x cpp-o ...
-
TortoiseSVN使用步骤和trunk,Branch,Tag详细说明
1 安装及下载client 端 2 什么是SVN(Subversion)? 3 为甚么要用SVN? 4 怎么样在Windows下面建立SVN Repository? 5 建立一个Working目录 6 ...
-
ace 在线编辑器 知识点
ace 常用方法: 功能 语句 设置值 editor.setValue("the new text here"); // or session.setValue 获取值 edito ...