[转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [中篇]
我们在《上篇》利用dotnet new命令创建了一个简单的控制台程序,接下来我们将它改造成一个ASP.NET Core应用。一个ASP.NET Core应用构建在ASP.NET Core框架之上,ASP.NET Core框架利用一个消息处理管道完成对HTTP请求的监听、接收、处理和最终的响应。ASP.NET Core管道由一个服务器(Server)和若干中间件(Middleware)构成,当宿主(Host)程序启动之后,管道被构建出来,作为管道“龙头”的服务器开始监听来自客户端的HTTP请求。
一、添加引用
接下来我们直接利用Visual Studio 打开前面这个helloworld.csproj项目文件。为了能够使用ASP.NET Core 框架提供的程序集,我们可以通过修改项目文件(.csproj)添加针对“Microsoft.AspNetCore.App”的框架引用(FrameworkReference)。在Visual Studio中修改项目文件非常方便,我们只需要右键选择目标项目,并从弹出的菜单中选择“Edit Project File”就可以了。如下所示的是修改后的项目文件,针对“Microsoft.AspNetCore.App”的框架引用被添加到<ItemGroup/>节点下。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
</ItemGroup>
</Project>
二、注册服务器与中间件
从应用承载或者寄宿(Hosting)方面来看,.NET Core具有一个以IHost/IHostBuilder为核心的服务承载系统,任何需要长时间运行的操作都可以定义成IHostedService服务并通过该系统来承载。IHost对象可以视为所有承载服务的宿主(Host),而IHostBuilder对象则是它的构建者(Builder)。一个ASP.NET Core应用本质上就是一个用来监听、接收和处理HTTP请求的后台服务,所以它被定义成一个GenericWebHostService(实现了IHostedService接口),我们将它注册到承载系统中进而实现了针对ASP.NET Core应用的承载。
一个运行的ASP.NET Core应用本质上体现为由一个服务器和若干中间件构成的消息处理管道,服务器解决针对HTTP请求的监听、接收和最终的响应,具体针对请求的处理则由它递交给后续的中间件来完成。这个管道是由前面提到的GenericWebHostService服务构建出来的。
ASP.NET Core提供了几种原生的服务类型,比较常用的是KestrelServer和HTTP.sys。KestrelServer是一款跨平台的Web服务器,可以在Windows、Mac OS和Linux上使用。它不仅可以作为独立的Web服务器直接对外提供服务,也可以结合传统的Web服务器(比如IIS、Apache和NGinx)并将它们作为反向代理来使用。HTTP.sys则是一种只能在Windows平台使用的Web服务器,由于它本质上是一个在操作系统内核模式运行的驱动,所以能够提供非常好的性能。
在对项目文件helloworld.csproj作了上述修改之后,我们对定义在Program.cs中的Main方法做了如下的改造。我们调用了静态类型Host的CreateDefaultBuilder方法创建了一个IHostBuilder对象,并最终调用该对象的Build方法构建出作为服务宿主的IHost对象。当我们调用IHost对象的Run扩展方法的时候,ASP.NET Core应用程序将会被启动。
在调用Build方法构建IHost对象之前,我们调用IHostBuilder接口的ConfigureWebHost扩展方法,并利用指定的Action<IWebHostBuilder>委托对象构建出ASP.NET Core应用的请求处理管道。具体来说,我们调用IWebHostBuilder接口的UseKestrel扩展方法将KestrelServer注册为服务器,调用Configure扩展方法注册了用来处理请求的中间件。Configure方法的输入参数是一个Action<IApplicationBuilder>对象,所需的中间件就注册在IApplicationBuilder对象上。演示程序注册的唯一中间件是通过调用IApplicationBuilder接口的Run扩展方法注册的,该中间件利用指定的Func<HttpContext,Task>对象将响应的主体内容设置为“Hello World”。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting; namespace helloworld
{
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHost(webHostBuilder => webHostBuilder
.UseKestrel()
.Configure(app => app.Run(
context => context.Response.WriteAsync("Hello World."))))
.Build()
.Run();
}
}
}
我们可以按照上面演示的那样通过执行dotnet命令行来启动该程序,也可以直接在Visual Studio中按F5或者Ctrl+F5启动该程序。下图所示的是执行dotnet run命令后控制台的输出结果,这些输出其实是通过日志的形式输出的。我们从这些输出可以看出ASP.NET Core应用采用的默认监听地址(http//localhost:5000和https//localhost:5001)和承载环境(Production)。如果需要关闭应用程序,只需要按Ctrl+C组合键就可以了。
注册的KestrelServer服务器会绑定到http//localhost:5000和https//localhost:5001这两个地址监听请求,如果我们利用浏览器分别对这两个地址发起请求会得到怎样的响应呢?如下图所示,两个请求都会得到主体内容为“Hello World.”的响应(由于证书的问题,Chrome浏览器为HTTPS的请求会显示“Not secure”的警告),毫无疑问该内容就是我们注册的中间件写入的。
三、修改SDK
每个.NET Core应用都针对一种具体的SDK类型。我们在前面展示了项目文件helloworld.csproj的完整定义,这是一个XML文件,根节点的<Project>上通过SDK属性设置了当前项目采用的SDK类型。对于前面这个通过dotnet new命令工具创建出来的控制台应用,它默认采用的SDK类型为“Microsoft.NET.Sdk”。对于一个ASP.NET Core应用,我们一般会采用另一种名为“Microsoft.NET.Sdk.Web”的SDK类型。
如果将SDK设置为“Microsoft.NET.Sdk.Web”,我们甚至可以将针对“Microsoft.AspNetCore.App”的框架引用从项目文件中删除。由于我们并不需要利用生成的.exe文件来启动ASP.NET Core应用,所以我们也应该将XML元素<OutputType>Exe</OutputType>从<PropertyGroup>节点中删除,所以最终的项目文件只需要保留如下的内容就可以了。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
</Project>
四、launchSettings.json
当我们通过修改项目文件helloworld.csproj将SDK改为“Microsoft.NET.Sdk.Web”之后,如果我们使用Visual Studio打开这个文件,一个名为“launchSettings.json”的配置文件将自动生成并被保存在“\Properties”目录下。顾名思义,launchSettings.json是一个在应用启动的时候自动加载的配置文件,该配置文件使我们可以在不同的设置下执行我们的应用程序。如下所示的就是Visual Studio自动创建的launchSettings.json文件的内容。我们可以看出该配置文件默认添加了两个节点,其中“iisSettings”用于设置IIS相关的选项,而“profiles”节点定义了一系列用于表示应用启动场景的Profile。
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51127/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"helloworld": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:51128/"
}
}
}
初始的launchSettings.json文件会默认创建两个Profile,一个被命名为“IIS Express”,另一个则使用当前项目名称来命名(“helloworld”)。每一个Profile相当于定义了应用的启动场景,相关的设置包括应用启动的方式、环境变量和URL等,具体的设置包括:
- commandName:启动当前应用程序的命令类型,有效的选项包括IIS、IISExpress、Executable和Project,前三个选项分别表示采用IIS、IISExpress和指定的可执行文件(.exe)来启动应用程序。如果我们使用dotnet run命令来启动程序,对应Profile的启动命名名称应该设置为Project。
- executablePath:如果commandName属性被设置为Executable,我们需要利用该属性来设置启动可执行文件的路径(绝对路径或者相对路径)。
- environmentVariables:该属性用来设置环境变量。由于launchSettings.json仅仅使用在开发环境,所以默认会添加一个名为“ASPNETCORE_ENVIRONMENT”的环境变量,并将它的值设置为“Development”,ASP.NET Core应用中正是利用这样一个环境变量来表示当前的部署环境。
- commandLineArgs:命令行参数,即传入Main方法的参数列表。
- workingDirectory:启动当前应用运行的工作目录。
- applicationUrl:应用程序采用的URL列表,多个URL之间采用分号(“;”)进行分隔。
- launchBrowser:一个布尔类型的开关,表示应用程序的时候是否自动启动浏览器。
- launchUrl:如果launchBrowser被设置为true,浏览器采用的初始化路径通过该属性进行设置。
- nativeDebugging:是否启动本地代码调试(Native Code Debugging),默认值为false。
- externalUrlConfiguration:如果该属性被设置为true,意味着禁用本地的配置,默认值为false。
- use64Bit:如果commandName属性设置为IIS Express,该属性决定是采用X64版本还是X86版本,默认值为false,意味着ASP.NET Core应用默认会采用X86版本的IIS Express。
launchSettings.json文件中的所有设置仅仅针对开发环境,产品环境下是不需要这个文件的,应用发布后生成的文件列表中也不包含该文件。该文件不需要手工进行编辑,当前项目属性对话框(通过在解决方案对话框中右击选择“属性(Properties)”选项)中“调试(Debug)”选项卡下的所有设置最终都会体现在该文件上。
如果在launchSettings.json文件设置了多个Profile,它们会以如下图所示的形式出现在Visual Studio的工具栏中,我们可以选择任意一个Profile中定义的配置选项来启动当前应用程序。如果Profile中通过设置launchBrowser属性选择启动浏览器,我们还可以选择浏览器的类型。
如果我们在当前项目所在目录下通过执行dotnet run命令来启动应用程序,launchSettings.json文件会默认被加载。我们可以通过命令行参数--launch-profile指定采用的Profile。如果没有对Profile作显式指定,定义在该配置文件中第一个commandName为“Project”的Profile会默认被使用。如下图所示,我们在创建的应用根目录下通过执行dotnet run命令启动我们的应用程序,其中第一次执行dotnet run命令的时候显式设置了Profile名称(--launch-profile helloworld)。从输出的结果可以看出,两次采用的是同一个Profile。
如果在执行dotnet run命令的时候不希望加载launchSettings.json文件,我们可以通过显式指定命令行参数--no-launch-profile来实现。如下图所示,我们在执行dotnet run命令时指定了--no-launch-profile参数,所以应用会采用KestrelServer默认的监听地址(http://localhost:5000和https://localhost:5001)。由于launchSettings.json根本就没有被加载,所以当前执行环境从Development变成了默认的Production。
五、显式指定URL
如果既不想使用launchSettings.json文件中定义的URL,也不想使用KestrelServer默认采用的监听地址,我们可以在应用程序中显式指定应用的URL。如下面的代码片段所示,我们只需要调用IWebHostBuilder的扩展方法UseUrls指定一组以分号分隔的URL即可。
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHost(webHostBuilder => webHostBuilder
.UseKestrel()
.UseUrls("http://0.0.0.0:3721;https://0.0.0.0:9527")
.Configure(app => app.Run(context => context.Response.WriteAsync("Hello World."))))
.Build()
.Run();
}
}
六、ConfigureWebHostDefaults
在上面演示的实例中,我们都是调用IHostBuilder接口的ConfigureWebHost扩展方法借助指定的Action<IWebHostBuilder>委托对象来构建处理请求处理管道,该接口还有另一个ConfigureWebHostDefaults的扩展方法,它会为我们作一些默认设置。如下面的代码片段所示,如果调用这个方法,KestrelServer服务器都不需要进行显式注册。
class Program
{
static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webHostBuilder => webHostBuilder.Configure(app => app.Run(context => context.Response.WriteAsync("Hello World."))))
.Build()
.Run();
}
}
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [中篇]
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Mac OS
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Linux
[ASP.NET Core 3框架揭秘] 跨平台开发体验: Docker
---------------------
作者:
Artech
来源:CNBLOGS
原文:https://www.cnblogs.com/artech/p/inside-asp-net-core-01-02.html
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件
[转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [中篇]的更多相关文章
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [中篇]
我们在<上篇>利用dotnet new命令创建了一个简单的控制台程序,接下来我们将它改造成一个ASP.NET Core应用.一个ASP.NET Core应用构建在ASP.NET Core框 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]
由于ASP.NET Core框架在本质上就是由服务器和中间件构建的消息处理管道,所以在它上面构建的应用开发框架都是建立在某种类型的中间件上,整个ASP.NET Core MVC开发框架就是建立在用来实 ...
- [转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [下篇]
由于ASP.NET Core框架在本质上就是由服务器和中间件构建的消息处理管道,所以在它上面构建的应用开发框架都是建立在某种类型的中间件上,整个ASP.NET Core MVC开发框架就是建立在用来实 ...
- [转][ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Docker
对于一个 .NET Core开发人员,你可能没有使用过Docker,但是你不可能没有听说过Docker.Docker是Github上最受欢迎的开源项目之一,它号称要成为所有云应用的基石,并把互联网升级 ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Linux
如果想体验Linux环境下开发.NET Core应用,我们有多种选择.一种就是在一台物理机上安装原生的Linux,我们可以根据自身的喜好选择某种Linux Distribution,目前来说像RHEL ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Mac OS
除了微软自家的Windows平台, .NET Core针对Mac OS以及各种Linux Distribution(RHEL.Ubuntu.Debian.Fedora.CentOS和SUSE等)都提供 ...
- 《ASP.NET Core 3框架揭秘》博文汇总
在过去一段时间内,写了一系列关于ASP.NET Core 3相关的文章,其中绝大部分来源于即将出版的<ASP.NET Core 3框架揭秘>(博文只能算是"初稿",与书 ...
随机推荐
- Ubuntu上更换163源 - Mars Loo的博客
转载*请注明原始出处:http://blog.csdn.net/a464057216/article/details/50865895 先备份源/etc/apt/sources.list为source ...
- Java IO:字节流与字符流
https://blog.csdn.net/my_truelove/article/details/53758412 字符和字节之间可以互相转化,中间的参照就是编码方式. 相当于给你一个密码本,按照这 ...
- excel之VLOOKUP函数的使用
VLOOKUP 函数是excel中比较常用的一个函数.该函数具有有四个参数: 1.查找值:指本表中的值,需要根据本表中的某一值在本表或其他表中查找我们想要获取的值就称为查找值. 2.数据表:指查找的范 ...
- linux 查看磁盘空间占用情况
工作中有时被分配的测试机空间不大,经常遇到磁盘空间占满的情况.排查过程如下: 一.首先使用df -h 命令查看磁盘剩余空间,通过以下图看出/目录下的磁盘空间已经被占满. 二.进入根目录,因为最近常用的 ...
- Statement对象
Statement 对象 创建 Statement 对象 在你准备使用 Statement 对象执行 SQL 语句之前,你需要使用 Connection 对象的 createStatement() 方 ...
- SQL —— 存储过程
一.什么是存储过程 预先存储好的SQL程序. 保存在SQL Server中(跟视图的存储方式一样) 通过名称和参数执行. 二.存储过程的优点 执行速度更快 允许模块化程序设计 提高系统安全性 减少网络 ...
- Direct2D 第4篇 渐变画刷
原文:Direct2D 第4篇 渐变画刷 #include <windows.h> #include <d2d1.h> #include <d2d1helper.h> ...
- iOS 中的 Deferred Deep Linking(延迟深度链接)
http://www.cocoachina.com/ios/20160105/14871.html Deep Linking 其实 deep linking 并不是一个新名词,在 web 开发领域,区 ...
- ajax多图片上传demo
<!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...
- Leetcode706.Design HashMap设计哈希映射
不使用任何内建的哈希表库设计一个哈希映射 具体地说,你的设计应该包含以下的功能 put(key, value):向哈希映射中插入(键,值)的数值对.如果键对应的值已经存在,更新这个值. get(key ...