《ASP.ENT Core 与 RESTful API 开发实战》(第3章)-- 读书笔记(上)
第 3 章 ASP.NET Core 核心特性
3.1 启动与宿主
ASP.NET Core 应用程序启动时,它首先会配置并运行其宿主,宿主主要用来启动、初始化应用程序,并管理其生命周期
ASP.NET Core 应用程序本质上就是控制台应用程序
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
由 CreateDefaultBuilder 方法创建 IWebHostBuilder 对象时所包含的主要默认选项如下:
- 配置 Kestrel 服务器作为默认的 Web 服务器来负责处理 Web 请求与响应
- 使用当前目录作为应用程序的内容目录,该目录决定了 ASP.NET Core 查找内容文件的位置
- 从以 ASPNETCORE_ 开头的环境变量中以及命令行参数中加载配置项
- 从 appsetting.json、appsettings.{Environment}.json、用户机密(仅开发环境)、环境变量和命令行参数等位置加载应用配置
- 配置日志功能,默认添加控制台输出和调试输出
- 如果应用程序呗托管在 IIS 中,启动 IIS 集成,它会配置应用程序的主机地址和端口,并允许捕获启动错误等
CreateDefaultBuilder 方法中所包含的默认配置能够通过 IWebHostBuilder 接口提供的扩展方法进行修改或增加
如 ConfigureAppConfiguration,ConfigureKestrel,ConfigureLogging,UseContentRoot 和 UseUrls 等
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
})
.UseEnvironment(EnvironmentName.Development)
.UseContentRoot(@"C:\public")
.UseSetting("https_port", "8080")
.UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")
.UseStartup<Startup>();
ASP.NET Core 内置了对程序运行环境的支持,通过设置不同的环境,能够使应用程序在运行时获取相应的配置,从而具有不同的行为和逻辑
内部提供3个环境:
- Development:开发
- Staging:预演
- Production:生产
Kestrel 是轻量级、托管的、开源且跨平台的 Web 服务器,它作为 ASP.NET Core 的组成部分,能够使 ASP.NET Core 应用程序运行在任何平台上
当 Kestrel 作为 ASP.NET Core 的服务器时,它会在 ASP.NET Core 的进程内运行,并负责监听 HTTP 请求以及对每一次的请求返回 HTTP 响应
在实际生产环境部署应用程序时,推荐使用主流的 Web 服务器(如 IIS 和 Apache 等)放在 Kestrel 之前作为反向代理服务器,增加应用程序的安全性,也提供了负载均衡、过滤请求和 URL 重定向等功能
IWebHostBuilder 接口有多个扩展方法,其中有一个很重要的是 UseStartup 方法,它主要向应用程序提供用于配置启动的类,而指定的这个类应具有以下两个方法:
- ConfigureServices:用于向 ASP.NET Core 的依赖注入容器添加服务
- Configure:用于添加中间件,配置请求管道
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
3.2 中间件
所谓中间件,就是处理 HTTP 请求和响应的组件,本质上是一段用来处理请求与响应的代码,多个中间件之间的链式关系使之形成了管道
ASP.NET Core 中内置了多个中间件,它们主要包含 MVC 认证、错误、静态文件、HTTPS 重定向和跨域资源共享(CORS)等,ASP.NET Core 也允许向管道添加自定义中间件
上一节的 Configure 方法中就是添加中间件的地方
中间件的添加顺序将决定 HTTP 请求以及 HTTP 响应遍历它们的顺序
每一个中间件都是通过调用 IApplicationBuilder 接口的 Use 和 Run 方法添加到请求管道中的
下面的例子是使用 Run 方法来添加一个中间件,该中间件会输出与本次请求相关的信息
app.Run(async (context) =>
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("----REQUEST----");
sb.AppendLine($"Host: {context.Request.Host}");
sb.AppendLine($"Method: {context.Request.Method}");
sb.AppendLine($"Path: {context.Request.Path}");
sb.AppendLine($"Protocol: {context.Request.Protocol}");
foreach (var item in context.Request.Headers)
{
sb.AppendLine($" {item.Key}: {item.Value}");
}
await context.Response.WriteAsync(sb.ToString());
});
与 Run 方法不同的是,Use 方法在处理完请求后还会将请求传入下一个中间件,并由它继续处理
app.Use(async (context, next) =>
{
Console.WriteLine("中间件 A:开始");
await next();
Console.WriteLine("中间件 A:结束");
});
除了 Run 和 Use 方法外,IApplicationBuilder 还提供了 Map、MapWhen 以及 UseWhen 方法,它们都可以指定条件,并在条件满足时创建新的分支管道,同时在新的分支上添加并执行中间件
Map 会根据是否配置指定的请求路径来决定是否在一个新分支上继续执行后续的中间件,并且在新分支上执行完后,不再回到原来的管道上
MapWhen 则可以满足更复杂的条件,它会对 HttpContext 对象进行进行更细致的判断,然后决定是否进入新的分支继续执行指定的中间件
UseWhen 创建的分支在执行结束后会继续回到原来的管道上
app.Map(new PathString("/maptest"),
a => a.Use(async (context, next) =>
{
Console.WriteLine("中间件 B:开始");
await next(); // 下一个中间件
Console.WriteLine("中间件 B:结束");
}));
app.UseWhen(context => context.Request.Path.Value == "/maptest",
a => a.Use(async (context, next) =>
{
Console.WriteLine("中间件 B:开始");
await next(); // 下一个中间件
Console.WriteLine("中间件 B:结束");
}));
自定义中间件
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();


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
《ASP.ENT Core 与 RESTful API 开发实战》(第3章)-- 读书笔记(上)的更多相关文章
- 使用ASP.NET Core构建RESTful API的技术指南
译者荐语:利用周末的时间,本人拜读了长沙.NET技术社区翻译的技术标准<微软RESTFul API指南>,打算按照步骤写一个完整的教程,后来无意中看到了这篇文章,与我要写的主题有不少相似之 ...
- 4类Storage方案(AS开发实战第四章学习笔记)
4.1 共享参数SharedPreferences SharedPreferences按照key-value对的方式把数据保存在配置文件中,该配置文件符合XML规范,文件路径是/data/data/应 ...
- 菜单Menu(AS开发实战第四章学习笔记)
4.5 菜单Menu Android的菜单主要分两种,一种是选项菜单OptionMenu,通过按菜单键或点击事件触发,另一种是上下文菜单ContextMenu,通过长按事件触发.页面的布局文件放在re ...
- [Android]《Android艺术开发探索》第一章读书笔记
1. 典型情况下生命周期分析 (1)一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart方法就会被调用. (2)当用户打开新的Activity或者切换到桌面的时候,回调如下 ...
- 温故知新,使用ASP.NET Core创建Web API,永远第一次
ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...
- 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践
本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主.主要NuGet包:无 一.创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点 1 //定义Person类 ...
- 零基础ASP.NET Core WebAPI团队协作开发
零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ...
- ASP.NET Core WebApi构建API接口服务实战演练
一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...
- 从 0 使用 SpringBoot MyBatis MySQL Redis Elasticsearch打造企业级 RESTful API 项目实战
大家好!这是一门付费视频课程.新课优惠价 699 元,折合每小时 9 元左右,需要朋友的联系爱学啊客服 QQ:3469271680:我们每课程是明码标价的,因为如果售价为现在的 2 倍,然后打 5 折 ...
- Asp.Net Core 5 REST API - Step by Step
翻译自 Mohamad Lawand 2021年1月19日的文章 <Asp.Net Core 5 Rest API Step by Step> [1] 在本文中,我们将创建一个简单的 As ...
随机推荐
- 分享10个高级sql写法
本文主要介绍博主在以往开发过程中,对于不同业务所对应的 sql 写法进行归纳总结而来.进而分享给大家. 本文所讲述 sql 语法都是基于 MySql 8.0+ 博主github地址:http://gi ...
- docker目录迁移流程
概述 在安装测试最新版本的HOMER7的过程中,docker作为基础工具碰到一些问题,针对问题进行总结. docker的默认工作目录在/var目录,而在我们的环境中,/var目录空间预留不足,随着do ...
- java进阶(28)--Map集合
一.Map简介: 1.Map与collection没有继承关系 2.Map集合以key与value的方式存储数据 二.常用方法: 1.void clear():清空Map集合
- [转帖]SecurityProtocolType 枚举
https://learn.microsoft.com/zh-cn/dotnet/api/system.net.securityprotocoltype?view=net-8.0 命名空间: Syst ...
- 通过宿主机查看K8S或者是容器内的Java程序的简单方法
通过宿主机查看K8S或者是容器内的Java程序的简单方法 背景 最近一个项目的环境出现了 cannot create native process 的错误提示 出现这个错误提示时, docker ex ...
- [转帖]Oracle与防火墙
https://www.laoxiong.net/oracle_and_firewall.html 老熊 Oracle数据库管理 2009-04-20 最近有两次Oracle数据库故障与防火墙有关.这 ...
- 银河麒麟安装多版本gcc的方式方法
银河麒麟安装多版本gcc的方式方法 背景 最近想升级一下gcc 但是发现自己编译的话非常麻烦 记得之前CentOS7的时候有一个scl的处理 发现CentOS8 已经没有scl的仓库了 简单验证了一下 ...
- 【转帖】eBay 云计算“网”事:网络超时篇
https://www.infoq.cn/article/JmCbkA0XX9NqrcX6loIo eBay技术荟 2020-06-19 本文字数:5508 字 阅读完需:约 18 分钟 导读 eBa ...
- [转帖]Steam内存测试工具【转】
转自:https://www.cnblogs.com/iouwenbo/p/14377478.html Stream测试是内存测试中业界公认的内存带宽性能测试基准工具. Stream安装 官方源码 ...
- [转帖]解析Linux gcore: 揭示程序内存捕获的秘密(linuxgcore)
https://www.dbs724.com/133618.html Linux gcore 是一种在Linux系统中使用命令行工具捕获进程内存内容的方法.它允许程序员制定程序的一个内存快照,从而帮助 ...