ASP.NET Core 核心特性--宿主、启动、中间件
宿主
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
CreateDefaultBuilder 创建 IHostBuilder 对象时所包含的主要默认选项包括:
- 配置 Kestrel 服务器作为默认的 Web 服务器来负责处理 Web 的请求与响应
- 使用当前目录作为应用程序的内容目录(ContentRoot),该目录决定了 ASP.NET Core 查找内容文件(如 MVC 视图等)的位置
- 从以 ASPNETCORE_ 开头的环境变量(如 ASPNETCORE_ENVIRONMENT)中以及命令行参数中加载配置项
- 从 appsettings.json、appsettings.{Environment}.json、用户机密(仅开发环境)、环境变量和命令行参数等位置加载应用设置
- 配置日志功能,默认添加控制台输出和调式输出
- 如果应用程序被托管在 IIS 中,启动 IIS 集成,它会配置应用程序的主机地址和端口,并允许捕获启动错误等
启动
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
- ConfigureServices 用于向 ASP.NET Core 的依赖注入容器添加服务
- Configure 用于添加中间件,配置请求管道
这两个方法都会在运行时被调用,且在应用程序的整个生命周期内,只执行一次。其中 ConfigureServices 方法是可选的,而 Configure 方法则是必须的。在程序启动时,它会执行 ConfigureServices 方法(如果有),将指定的服务放入应用程序的依赖注入容器中,然后再执行 Configure 方法,向请求管道中添加中间件。
中间件
所谓中间件,就是处理 HTTP 请求和响应的组件,它本质上是一段用来处理请求与响应的代码。多个中间件之间的链式关系使之形成了管道(Pipeline)或者请求管道。管道意味着请求将从一端进入,并按照一定的顺序由每一个中间件处理,最后由另一端出来。
添加中间件:
Run & Use
// Use 方法在处理完成后还会将请求传入下一个中间件,并由它继续处理
app.Use(async (context, next) =>
{
Console.WriteLine("中间件 A:开始");
await next();// 下一个中间件
Console.WriteLine("中间件 A:结束");
});
app.Run(async (context) =>
{
Console.WriteLine("中间件 B");
await context.Response.WriteAsync("Hello, world");
});
启动程序,输出如下:
中间件 A:开始
中间件 B
中间件 A:结束
Map
app.Use(async (context, next) =>
{
Console.WriteLine("中间件 A:开始");
await next();// 下一个中间件
Console.WriteLine("中间件 A:结束");
});
// 根据是否配置指定的请求路径来决定是否在一个新分支上继续执行后续的中间件
// 并且在新分支上执行完后,不再回到原来的管道上
app.Map(new PathString("/maptest"),
a => a.Use(async (context, next) =>
{
Console.WriteLine("中间件 B:开始");
await next(); // 下一个中间件
Console.WriteLine("中间件 B:结束");
}));
app.Run(async context =>
{
Console.WriteLine("中间件 C");
await context.Response.WriteAsync("Hello, world");
});
访问 https://localhost:5001/maptest
中间件 A:开始
中间件 B:开始
中间件 B:结束
中间件 A:结束
UseWhen
// Use 方法在处理完成后还会将请求传入下一个中间件,并由它继续处理
app.Use(async (context, next) =>
{
Console.WriteLine("中间件 A:开始");
await next();// 下一个中间件
Console.WriteLine("中间件 A:结束");
});
// 所有添加的中间件都会执行
app.UseWhen(context => context.Request.Path.Value == "/maptest",
a => a.Use(async (context, next) =>
{
Console.WriteLine("中间件 B:开始");
await next(); // 下一个中间件
Console.WriteLine("中间件 B:结束");
}));
app.Run(async context =>
{
Console.WriteLine("中间件 C");
await context.Response.WriteAsync("Hello, world");
});
访问 https://localhost:5001/maptest
中间件 A:开始
中间件 B:开始
中间件 C
中间件 B:结束
中间件 A:结束
自定义中间件
public class HttpMethodCheckMiddleware
{
// 在管道中的下一个中间件
private readonly RequestDelegate _next;
/// <summary>
/// 构造函数中可以得到下一个中间件,并且还可以注入需要的服务,比如 IHostEnvironment
/// </summary>
/// <param name="requestDelegate"></param>
/// <param name="environment"></param>
public HttpMethodCheckMiddleware(RequestDelegate requestDelegate, IHostEnvironment environment)
{
this._next = requestDelegate;
}
/// <summary>
/// 对 HTTP 请求方法进行判断,如果符合条件则继续执行下一个中间件
/// 否则返回 400 Bad Request 错误,并在响应中添加自定义消息头用于说明错误原因
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public Task Invoke(HttpContext context)
{
var requestMethod = context.Request.Method.ToUpper();
if (requestMethod == HttpMethods.Get || requestMethod == HttpMethods.Head)
{
return _next(context);
}
else
{
context.Response.StatusCode = 400;
context.Response.Headers.Add("X-AllowHTTPWeb", new[] {"GET,HEAD"});
context.Response.WriteAsync("只支持 GET、HEAD 方法");
return Task.CompletedTask;
}
}
}
添加自定义中间件
app.UseMiddleware<HttpMethodCheckMiddleware>();
创建扩展方法
public static class CustomMiddlewareExtensions
{
public static IApplicationBuilder UseHttpMethodCheckMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<HttpMethodCheckMiddleware>();
}
}
调用扩展方法添加中间件
app.UseHttpMethodCheckMiddleware();
参考资料
《ASP.ENT Core 与 RESTful API 开发实战》
如果阅读文章后有所收获,希望您可以点一个推荐,感觉不尽!!!

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
ASP.NET Core 核心特性--宿主、启动、中间件的更多相关文章
- Asp.Net Core 第06局:中间件
总目录 前言 本文介绍Asp.Net Core 中间件. 环境 1.Visual Studio 2017 2.Asp.Net Core 2.2 开局 第一手:中间件概述 1.中间件:添加到应用 ...
- ASP.NET Core管道详解[6]: ASP.NET Core应用是如何启动的?[下篇]
要承载一个ASP.NET Core应用,只需要将GenericWebHostService服务注册到承载系统中即可.但GenericWebHostService服务具有针对其他一系列服务的依赖,所以在 ...
- asp.net core 核心对象解析
首先声明这篇文章的所有内容均来自https://www.cnblogs.com/artech/p/inside-asp-net-core-framework.html ----感谢大内老A(artec ...
- Asp.Net Core 3.1 的启动过程5
前言 本文主要讲的是Asp.Net Core的启动过程,帮助大家掌握应用程序的关键配置点. 1.创建项目 1.1.用Visual Studio 2019 创建WebApi项目. 这里面可以看到有两个关 ...
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- [转]ASP.NET Core 中的那些认证中间件及一些重要知识点
本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...
- asp.net core mvc剖析:启动流程
asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghelper,viewcomponent,D ...
- asp.net core 教程(六)-中间件
Asp.Net Core-中间件 在这一章,我们将了解如何设置中间件.中间件技术在 ASP.NET Core中控制我们的应用程序如何响应 HTTP 请求.它还可以控制应用程序的异常错误,这是一个在如何 ...
- Asp .Net core 2 学习笔记(2) —— 中间件
这个系列的初衷是便于自己总结与回顾,把笔记本上面的东西转移到这里,态度不由得谨慎许多,下面是我参考的资源: ASP.NET Core 中文文档目录 官方文档 记在这里的东西我会不断的完善丰满,对于文章 ...
随机推荐
- http2.0与WebSocket的关系是怎么样的
按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP是应用层的协议.在这三者之间,SPDY和WebSocket都是与HTTP相关的协议,而TCP是HTTP底层的协议.WebSock ...
- [PyTorch入门之60分钟入门闪击战]之神经网络
神经网络 来源于这里. 神经网络可以使用torch.nn包构建. 现在你对autograd已经有了初步的了解,nn依赖于autograd定义模型并区分它们.一个nn.Module包含了层(layers ...
- LaunchImage的设置及对应图片尺寸
2017-10-12 设置APP的LaunchImage 按照如下步骤设置app的LaunchImage: In Assets.xcassets click + button -> App Ic ...
- windows dnsrecon
缺了两个模块 第一个:https://pypi.python.org/pypi/netaddr 第二个:dnspython 找到下载后setup.py install就OK了,话说GFW真***了,用 ...
- 【转载】Java for循环
转载只为个人学习,阅读请前往原地址:Java for循环的几种用法详解 本文主要是来了解一下Java中的几种for循环用法,分析得十分详细,一起来看看. J2SE 1.5提供了另一种形式的for循环. ...
- 生鲜电商的两极战:巨头VS地头
"九月蟹黄满,十月蟹肉香",螃蟹年年相似,总是美味无边,但购买渠道却随着互联网普及而变得愈发多样起来.此前,大闸蟹礼券风靡就是最佳代表之一.虽然也引发诸多问题,但消费者也越 ...
- C++走向远洋——49(项目一2、复数类中的运算符重载、类的友元函数)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- 压力测试(四)-Mysql数据库压测实操
1.Jmeter压测实战之JDBC request压测Mysql讲解 简介:讲解jdbc压测mysql相关准备工作,jar包添加,配置讲解 1.Thread Group -> add -> ...
- pyteeseract使用报错Error: one input ui-file must be specified解决
Python在图像识别有天然的优势,今天使用pytesseract模块时遇到一个报错:“Error: one input ui-file must be specified”. 环境:windows ...
- 如何使用API提交转码任务?
摘要: 当常规的转码工作流无法满足用户的场景时,需用户自己判断业务逻辑,并使用API提交转码任务.例如:并不是所有的视频都需要转码,不同视频需要设置不同的转码配置.本文将介绍API提交转码任务的方法. ...