1.前言

ASP.NET Core应用程序可以配置和启动主机(Host)。主机负责应用程序启动和生命周期管理,配置服务器和请求处理管道。主机还可以设置日志记录、依赖关系注入和配置。而Host主机又包括Web主机(IWebHostBuilder)和通用主机(IHostBuilder)。该章节主要介绍了用于托管Web应用的Web主机。对于其他类型的应用,请使用通用主机。

2.设置主机

创建使用IWebHostBuilder实例的主机。通常在应用程序的入口点来执行Main方法。在项目模板中,Main位于Program.cs。典型应用默认调用CreateDefaultBuilder来开始创建主机:

public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}

2.1执行下列任务

调用CreateDefaultBuilder的代码位于名为CreateWebHostBuilder的方法中,这让它区分于 Main中对生成器对象调用Run的代码。CreateDefaultBuilder执行下列任务:
●使用应用程序的托管配置提供应用程序将Kestrel服务器配置为Web服务器。
●将内容根设置为由 Directory.GetCurrentDirectory返回的路径。
●通过以下对象加载主机配置:
  ○前缀为ASPNETCORE_的环境变量(例如,ASPNETCORE_ENVIRONMENT)。
  ○命令行参数。
●按以下顺序加载应用程序配置:
  ○appsettings.json。
  ○appsettings.{Environment}.json。
  ○应用在使用入口程序集的Development环境中运行时的机密管理器。
  ○环境变量。
  ○命令行参数。
●配置控制台和调试输出的日志记录。日志记录包含appsettings.json或appsettings.{Environment}.json文件的日志记录配置部分中指定的日志筛选规则。
●使用ASP.NET Core模块在IIS后面运行时,CreateDefaultBuilder会启用IIS集成,这会配置应用程序的基址和端口。IIS集成还配置应用程序以捕获启动错误。
●如果应用环境为“开发(Development)”,请将ServiceProviderOptions.ValidateScopes设为true。

2.2重写和增强定义的配置

ConfigureAppConfiguration、ConfigureLogging以及IWebHostBuilder的其他方法和扩展方法可重写和增强CreateDefaultBuilder定义的配置。下面是一些示例:
ConfigureAppConfiguration:用于指定应用程序的其他IConfiguration。下面的ConfigureAppConfiguration调用添加委托,以在appsettings.xml文件中添加应用程序配置,该示例在Core系列第11章节有演示。可多次调用ConfigureAppConfiguration。请注意,此配置不适用于主机(例如,服务器URL或环境)。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
});

ConfigureLogging:ConfigureLogging调用添加委托,将最小日志记录级别 (SetMinimumLevel)配置为LogLevel.Warning。此设置重写CreateDefaultBuilder在appsettings.Development.json和appsettings.Production.json中配置,分别为LogLevel.Debug和LogLevel.Error。可多次调用 ConfigureLogging。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Warning);
});

ConfigureKestrel:调用ConfigureKestrel来重写CreateDefaultBuilder在配置Kestrel时建立的30,000,000字节默认Limits.MaxRequestBodySize:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureKestrel((context, options) =>
{
options.Limits.MaxRequestBodySize = ;
});

设置主机时,可以提供配置和ConfigureServices方法。如果指定Startup类,必须定义Configure方法。

3.主机配置值

WebHostBuilder依赖于以下的方法设置主机配置值:
●主机生成器配置,其中包括格式ASPNETCORE_{configurationKey}的环境变量。例如 ASPNETCORE_ENVIRONMENT。
●UseContentRoot和UseConfiguration等扩展。
●UseSetting和关联键。使用UseSetting设置值时,该值设置为无论何种类型的字符串。

3.1应用程序键(名称)

在主机构造期间调用UseStartup或Configure时,会自动设置 IHostingEnvironment.ApplicationName属性。该值设置为包含应用入口点的程序集的名称。要显式设置值,请使用WebHostDefaults.ApplicationKey(环境变量:ASPNETCORE_APPLICATIONNAME):

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//应用程序默认名称为:CoreWeb (也就是项目名称)
  string an = env.ApplicationName;
  ...
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args).UseStartup<Startup>()
.UseSetting(WebHostDefaults.ApplicationKey, "CoreWeb");

3.2捕获启动错误

此设置控制启动错误的捕获。当false时,启动期间出错导致主机退出。当true时,主机在启动期间捕获异常并尝试启动服务器(环境变量:ASPNETCORE_CAPTURESTARTUPERRORS)。

WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)

3.3内容根

此设置确定ASP.NET Core开始搜索内容文件,如MVC视图等。内容根也用作Web根设置的基路径。如果路径不存在,主机将无法启动(环境变量:ASPNETCORE_CONTENTROOT)。

WebHost.CreateDefaultBuilder(args)
.UseContentRoot("c:\\<content-root>")

3.4详细错误

确定是否应捕获详细错误。启用(或当环境设置为Development)时,应用捕获详细的异常(环境变量:ASPNETCORE_DETAILEDERRORS)。

WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.DetailedErrorsKey, "true")

3.5环境

设置应用程序的环境。环境可以设置为任何值。框架定义的值包括Development、Staging和Production。值不区分大小写。默认情况下,从ASPNETCORE_ENVIRONMENT环境变量读取环境。使用Visual Studio时,可能会在launchSettings.json文件中设置环境变量。有关于环境详情信息,可以移步到Core系列第10章节有参阅(环境变量:ASPNETCORE_ENVIRONMENT)。

WebHost.CreateDefaultBuilder(args)
.UseEnvironment(EnvironmentName.Development)

3.6HTTPS端口

设置HTTPS重定向端口。用于强制实施HTTPS(环境变量:ASPNETCORE_HTTPS_PORT)。

WebHost.CreateDefaultBuilder(args)
.UseSetting("https_port", "")

3.7服务器(Kestrel) URL

指示IP地址或主机地址,其中包含服务器应针对请求侦听的端口和协议。设置为服务器应响应的以分号分隔 (;) 的URL前缀列表。例如 http://localhost:123。使用“*”指示服务器应针对请求侦听的使用特定端口和协议(例如 http://*:5000)的IP地址或主机名。协议(http://或https://)必须包含每个URL。不同的服务器支持的格式有所不同(环境变量:ASPNETCORE_URLS)。

WebHost.CreateDefaultBuilder(args)
.UseUrls("https://*:5000;https://localhost:5001;https://hostname:5002")

4.重写配置

使用配置可以配置Web主机。在下面的示例中,主机配置是根据需要在hostsettings.json文件中指定。命令行参数可能会重写从hostsettings.json文件加载的任何配置。生成的配置(在config中)用于通过UseConfiguration配置主机。
新建一个hostsettings.json文件,内容如下:

{
"urls": "https://*:5005"
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
//IConfigurationBuilder的配置主机
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
//主机配置在hostsettings.json文件中指定
.AddJsonFile("hostsettings.json", optional: true)
//输入的命令行参数可能会重写从hostsettings.json文件加载的任何配置
.AddCommandLine(args)
.Build(); return WebHost.CreateDefaultBuilder(args)
.UseUrls("https://*:5001")
.UseConfiguration(config)
.Configure(app =>
{
//生成的配置委托函数
app.Run(context =>
context.Response.WriteAsync("Hello, World!"));
});
}

上述代码描述意思是若要指定在特定的URL上运行的主机,所需的值可以在执行dotnet运行时从命令提示符传入。命令行参数重写hostsettings.json文件中的urls值,且服务器侦听端口8080:

dotnet run --urls "http://*:8080"

主机启动时,先用hostsettings.json config重写UseUrls提供的urls参数配置,然后再用命令行参数config重写hostsettings.json config的urls参数配置。

5.管理主机

管理主机启动方式有Run和Start两种。Run方法启动Web应用程序并阻止调用线程,直到关闭主机。Start方法通过调用自身以非阻止方式运行主机。

//Run
CreateWebHostBuilder(args).Build().Run();
//Start:非阻止方式,所有必须加上ReadLine
CreateWebHostBuilder(args).Build().Start();
Console.ReadLine();

6.IHostingEnvironment接口

IHostingEnvironment接口提供有关应用的Web承载环境的信息。使用构造函数注入获取 IHostingEnvironment以使用其属性和扩展方法:

//示例1:
public class CustomFileReader
{
private readonly IHostingEnvironment _env; public CustomFileReader(IHostingEnvironment env)
{
_env = env;
}
public string ReadFile(string filePath)
{
var fileProvider = _env.WebRootFileProvider;
// Process the file here
}
}

可以用于在启动时基于环境配置应用程序或者将IHostingEnvironment注入到Startup构造函数,用于ConfigureServices:

//示例2:
public class Startup
{
public Startup(IHostingEnvironment env)
{
HostingEnvironment = env;
}
public IHostingEnvironment HostingEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
if (HostingEnvironment.IsDevelopment())
{
// Development configuration
}
else
{
// Staging/Production configuration
}
var contentRootPath = HostingEnvironment.ContentRootPath;
}
}

IHostingEnvironment服务还可以直接注入到Configure方法以设置处理管道:

//示例3:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
// In Development, use the Developer Exception Page
app.UseDeveloperExceptionPage();
}
else
{
// In Staging/Production, route exceptions to /error
app.UseExceptionHandler("/error");
}
var contentRootPath = env.ContentRootPath;
}

创建自定义中间件(要了解中间件的同学们,可以移步到第四章节学习)时可以将IHostingEnvironment 注入Invoke方法:

public async Task Invoke(HttpContext context, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
// Configure middleware for Development
}
else
{
// Configure middleware for Staging/Production
}
var contentRootPath = env.ContentRootPath;
}

7.IApplicationLifetime接口

IApplicationLifetime允许后启动和关闭活动。接口上的三个属性是用于注册Action方法(用于定义启动和关闭事件)的取消标记。

取消标记

触发条件

ApplicationStarted

主机已完全启动。

ApplicationStopped

主机正在完成正常关闭。应处理所有请求。 关闭受到阻止,直到完成此事件。

ApplicationStopping

主机正在执行正常关闭。仍在处理请求。关闭受到阻止,直到完成此事件。

public class Startup
{
public void Configure(IApplicationBuilder app, IApplicationLifetime appLifetime)
{
appLifetime.ApplicationStarted.Register(OnStarted);
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
Console.CancelKeyPress += (sender, eventArgs) =>
{
appLifetime.StopApplication();
// Don't terminate the process immediately, wait for the Main thread to exit gracefully.
eventArgs.Cancel = true;
};
}
private void OnStarted()
{
// Perform post-startup activities here
}
private void OnStopping()
{
// Perform on-stopping activities here
}
private void OnStopped()
{
// Perform post-stopped activities here
}
}

StopApplication是请求应用终止的意思。以下类在调用类的Shutdown方法时使用StopApplication正常关闭应用:

public class MyClass
{
private readonly IApplicationLifetime _appLifetime;
public MyClass(IApplicationLifetime appLifetime)
{
_appLifetime = appLifetime;
}
public void Shutdown()
{
_appLifetime.StopApplication();
}
}

8.作用域验证

如果应用环境为“开发(Development)”,则CreateDefaultBuilder将ServiceProviderOptions.ValidateScopes设为true。若将ValidateScopes设为true,默认服务提供应用程序会执行检查来验证以下内容:
●作用域服务不能直接或间接地从根服务提供者解析。
●作用域服务不会直接或间接地注入到单例中(服务的生命周期)。
若要始终验证作用域(包括在生命周期环境中验证),请使用主机生成器上的 UseDefaultServiceProvider配置ServiceProviderOptions:

WebHost.CreateDefaultBuilder(args)
.UseDefaultServiceProvider((context, options) => {
options.ValidateScopes = true;
})

参考文献:
ASP.NET Core Web主机

(15)ASP.NET Core Web主机(IWebHostBuilder)的更多相关文章

  1. asp.net core 系列 16 Web主机 IWebHostBuilder

    一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...

  2. ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试

    想必大家之前在进行ASP.NET Web 应用程序开发期间都有用到过将我们的网站部署到IIS自定义主机域名并附加到进程进行调试. 那我们的ASP.NET Core Web 应用程序又是如何部署到我们的 ...

  3. docker中运行ASP.NET Core Web API

    在docker中运行ASP.NET Core Web API应用程序 本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过 ...

  4. 使用JWT创建安全的ASP.NET Core Web API

    在本文中,你将学习如何在ASP.NET Core Web API中使用JWT身份验证.我将在编写代码时逐步简化.我们将构建两个终结点,一个用于客户登录,另一个用于获取客户订单.这些api将连接到在本地 ...

  5. Docker容器环境下ASP.NET Core Web API应用程序的调试

    本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...

  6. 在docker中运行ASP.NET Core Web API应用程序

    本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过程中,也会对docker的使用进行一些简单的描述.对于.NET Cor ...

  7. Docker容器环境下ASP.NET Core Web API

    Docker容器环境下ASP.NET Core Web API应用程序的调试 本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Dock ...

  8. ASP.NET Core Web API下事件驱动型架构的实现(一):一个简单的实现

    很长一段时间以来,我都在思考如何在ASP.NET Core的框架下,实现一套完整的事件驱动型架构.这个问题看上去有点大,其实主要目标是为了实现一个基于ASP.NET Core的微服务,它能够非常简单地 ...

  9. ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入支付宝-电脑网页支付接口及同步跳转及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET ...

随机推荐

  1. 5分钟快速部署PESCMS TEAM 团队任务管理系统开发版

    所在的公司也经历过小团队的发展,为了高效率,通常都是面对面交流,很多时候事情谈论过后不久就已经淡忘了.而且工作任务不能全局观察,成员之间基本上都要主动去询问,效率反而低下.所以今天就介绍一款中小团队的 ...

  2. Python爬虫入门:爬取豆瓣电影TOP250

    一个很简单的爬虫. 从这里学习的,解释的挺好的:https://xlzd.me/2015/12/16/python-crawler-03 分享写这个代码用到了的学习的链接: BeautifulSoup ...

  3. 56. Merge Interval

    56. Merge Interval 0. 参考文献 序号 文献 1 花花酱 LeetCode 56. Merge Intervals 2 [LeetCode] Merge Intervals 合并区 ...

  4. 基于 MySQL Binlog 的 Elasticsearch 数据同步实践 原

    一.背景 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数据可以 ...

  5. Golang 受欢迎的原因:大道至简

    前言 Golang自2009年发布第一个版本,2012年发布1.0版本.在这10年的时间里,不断有开发者加入Golang的阵营中,不断共建Golang生态.其中比较有代表性的Golang编写软件作品是 ...

  6. idea中向pom.xml添加依赖时显示”not found dependency“

    总结: 起因:再输入hibernate-core的version时,开始写的是对的,就是 5.0.11.Final(这个也是跟着教程来的),直接就报错了,左等右等没用,也点过maven的reimpor ...

  7. GitHub使用整理——从开始到上传项目

    前期准备 首先是github官网: https://github.com/ 下载github工具: https://git-for-windows.github.io/ 进入github创建一个新的项 ...

  8. dockerfile 制作镜像

    # Set the base image to UbuntuFROM ubuntu # File Author chenghanMAINTAINER chenghan ################ ...

  9. Excel催化剂开源第13波-VSTO开发之DataGridView控件几个小坑

    Excel催化剂内部大量使用了DataGridView,这其中有一些小坑,花了力气才解决的,在此给广大开发者作简单分享. 为何要使用DataGridView而不是其他控件如ListBox.ListVi ...

  10. C#7.1 新增功能

    连载目录    [已更新最新开发文章,点击查看详细] C# 7.1 是 C# 语言的第一个点版本(更新版本). 它标志着该语言发布节奏的加速. 理想情况下,可以在每个新功能准备就绪时更快推出新功能.  ...