首先创建一个空的ASP.NET Core Web应用程序。第一个应用程序是一个简单的主机,它只响应来自主机的请求。从一个新的ASP.NET Core Web应用程序开始,并选择空模板(参见下图)。但是对于第一个示例,空模板空得还不够。从模板中删除Startup.cx文件和wwwroot目录。
Main()方法简化为调用WebHost类的Start()方法。此方法具有RequestDelegate参数。RequestDelegate是一个委托,把HttpContext接收为参数并返回一个Task。可以使用HttpContext从客户端读取请求并发送返回的内容。使用示例代码,返回包含HTML字符串的响应:
public class Program
{
public static void Main(string[] args)
{
WebHost.Start(async context=>
{
await context.Response.WriteAsync("A Simple Host!");
}).WaitForShutdown();
}
}
运行应用程序时,可以在浏览器中看到HTML内容。
使用ASP.NET Core 创建Web主机非常简单,但是现在进入一个更复杂的场景来看看这些特性。下一个应用程序名为WebSampleApp,使用相同的Empty模板创建。
创建项目之后,会得到一个名为WebSampleApp的解决方案和一个项目文件,其中包括一些文件和文件夹。
在项目结构中,有一个ependencies文件夹。其中的NuGet子文件夹包含NuGet包。在ASP.NET Core,包列表已经简化,只能看到Microsoft.AspNetCore.All引用包。这是一个包含大量ASP.NET Core包的引用包。这是一个包含大量ASP.NET Core包的引用包。在Solution Explorer中打开Microsoft.AspNetCore.All时引用的包列表。
在项目文件中,还可以看到对这个包的引用。项目文件列出了项目SDK(软件开发工具包)和Microsoft.NET.Sdk.Web。这利用了安装在系统上的SDK。这个条目不同于控制台应用程序,其中SDK是Microsoft.NET.Sdk。在Web SDK中,可以使用其他Web开发工具:
在Project设置中使用Debug选项,可以配置提供Visual Studio开发时使用的Web服务器(参见下图)。在默认情况下,IIS Express配置为使用Debug设置指定的端口号。IIS Express源自Internet Information Server(IIS),提供了IIS的所有核心特性。所以非常易于在于稍后托管应用程序的环境(如果IIS用于托管)几乎相同的环境中开发Web应用程序。
要使用Kestrel服务器运行应用程序,可以使用Debug Project设置选择项目名称的概要文件。使用Visual Studio项目设置更改的设置将影响launchSettings.json文件的配置。通过这个文件,可以定义一些附加的配置,比如命令行参数:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:30963",
"sslPort": 44332
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebSampleApp": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
注意:
Kestrel服务器是由ASP.NET Core团队开发,通过ASP.NET Core提供简单的主机。当使用IIS托管Web应用程序时,IIS将请求转发给Ketrel服务器。这就像Web应用程序在Linux上由Apache服务器托管一样——将请求转发到Kestrel服务器。首先是对于ASP.NET Core,Kestrel服务器支持面向公众的使用,因此可以直接在Kestrel服务器上托管Web应用程序,并且在端口80上访问它。
Solution Explorer的项目结构中的Dependencies文件夹显示了对JavaScript库的依赖。创建空项目时,这个文件夹是空的。第5小节"添加静态内容"会添加依赖项。
wwwroot文件夹包含了需要发布的服务器的静态文件。目前,这个文件夹是空的,但是将添加HTML、CSS文件和JavaScript库。
C#源文件Startup.cs也包含在一个空项目中。接下来讨论这个文件。
项项目的创建过程中,需要如下名称空间:
Microsoft.AspNetCore.Builder
Microsoft.AspNetCore.Hosting
Microsoft.AspNetCore.Http
Microsoft.Extensions.Configuraion
Microsoft.Extensions.DepedencyInjection
Microsoft.Extensions.Logging
Microsoft.Extensions.PlatformAbstractions
Newtonsoft.Json
System
System.Collections.Generic
System.Globalization
System.Linq
System.Text
System.Text.Encoding.Web
System.Threading.Tasks
1. 启动
下面开始建立Web应用程序的一些功能。为了获得有关客户端的信息并返回一个响应,需要编写对HttpContext的响应。
使用空的ASP.NET Web应用程序模板在Program类中创建一个Main()方法,其中包含以下代码:
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();
});
}
CreateDefaultBuilder返回一个实现IWebHostBuilder的对象,该对象设置了以下功能:
- 配置Kestrel作为要使用的Web服务器。
- 内容的根路径设置为当前目录
- 将配置定以为从appsettings.json文件中加载的配置。
- 基于环境,用不同的名称添加一个附加的JSON配置文件
appsettings.{environmentname}.json
- 环境名称是Development时,将读取来自user secrets的配置。
- 将配置设置提供程序配置为从环境变量和命令行中加载设置。
- 将记录器工厂配置为记录到控制台和调试输出窗口上。
- 启用IIS集成。
使用从CreateDefaultBuilder返回的IWebHostBuilder时,将调用UseStartup方法。该方法定义要实例化的Startup类和运行Web主机时将调用的方法。
UseStartup方法实现为一个流利API,并再次返回IWebHostBuilder。可以在Startup类之前使用IWebHostBuilder来配置需要的其他服务,并定义其他配置提供程序。
Build方法是设置Web主机时的链中的最后一个方法。此方法构建主机来运行应用程序,并返回IWebHost接口。使用此接口,可以使用Services属性访问依赖注入容器,也可以从ServerFeatures属性中访问托管服务器特性。IServerAddressFeature是一个可以用来检索主机地址的服务器特性。调用Start方法将启动对已配置端口的套接字的监听。
空的ASP.NET Web应用程序模板创建一个Startup类,它包含以下代码:
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// 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.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
}
}
由于使用泛型模板参数将Startup类传递给UseStartup方法,因此将调用ConfigureServices和Configure方法。
可以使用ConfigureServices方法在依赖注入容器中配置服务。此方法具有IServiceCollection参数,该参数包含Main()方法中已注册的所有服务,并允许添加其他服务。IServiceCollection派生自基接口IList
Configure()方法通过依赖注入接收参数。模板中定义的参数是IApplicationBuilder类型和IHostingEnvironment类型。
接口IHostingEnviroment允许访问环境的名称(EnvironmentName)、内容的根路径(源代码的目录)和Web内容文件的根路径(子目录wwwroot)。访问这些目录的默认提供程序是PhysicalileProvider。对于不同的提供程序,可以从其他数据源(例如数据库)中提供内容。在Configure方法的实现中,使用IHostingEnvironment通过调用扩展方法IsDevelopment来检查当前环境是否是Development。只有这个环境中才显示异常。由于安全问题,在生产环境中,用户看不到异常的详细信息。
IApplicationBuilder接口用于向HTTP请求管道添加中间件。调用这个接口的Use方法时,可以构建HTTP请求管道,来定义响应请求时应该做什么。Use方法是使用流利API实现的,它再次返回IApplicationBuilder。这样,可以很容易地将多个中间件对象添加到管道中。有几种扩展方法可以使添加中间件更加容易。在本章后面可以创建自定义中间件并将其添加到管道中。
Run方法是接口IApplicationBuilder的扩展方法,并返回void。因此,它在请求管道中注册注册最后一个中间件。Run方法的参数是RequestDelegate类型的委托。该类型接收HttpContext作为参数,并返回一个Task。使用HttpContext(代码片段中的context变量),可以访问来自浏览器的请求信息(HTTP标题、cookie和表单数据),并可以发送响应。生成的代码给客户端返回一个简单的字符串-Hello World!,如下图所示。
2. 示例应用程序
示例应用程序包含一个入口页面,在该页面中,可以使用HTML链接轻松访问应用程序显示的所有特性:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
string[] lines = new[]
{
"",
@"Static Files - requires UseStaticFiles ",
"Request and Response",
"",
@"Request and Response ",
@"Header ",
@"Add ",
" ",
" ",
" "
};
var builder = new StringBuilder();
foreach (var line in lines)
{
builder.Append(line);
}
string html = builder.ToString().HtmlDocument("Web Sample App");
await context.Response.WriteAsync(html);
});
});
}
定义HTMLExtensions类是为了创建特定的HTML并减少需要编写的HTML代码。这个类定义扩展方法来创建div、span和li元素:
public static class HTMLExtensions
{
public static string Div(this string value) =>
$"{value}";
public static string Span(this string value) =>
$"{value}";
public static string Div(this string key, string value) =>
$"{key.Span()}: {value.Span()}".Div();
public static string Li(this string value) =>
$"



