使用 IIS 和 ASP.NET Core 进行进程内托管
注意
此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本。
进程内托管在与其 IIS 工作进程相同的进程中运行 ASP.NET Core 应用。 进程内承载相较进程外承载提供更优的性能,因为请求并不通过环回适配器进行代理,环回适配器是一个网络接口,用于将传出的网络流量返回给同一计算机。
下图说明了 IIS、ASP.NET Core 模块和进程内托管的应用之间的关系:
启用进程内托管
自 ASP.NET Core 3.0 起,默认情况下已为部署到 IIS 的所有应用启用进程内托管。
若要显式配置进程内托管的应用,请在项目文件 (.csproj
) 中将 <AspNetCoreHostingModel>
属性的值设置为 InProcess
:
<PropertyGroup>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
一般体系结构
请求的常规流程如下:
- 请求从 Web 到达内核模式 HTTP.sys 驱动程序。
- 驱动程序将本机请求路由到网站的配置端口上的 IIS,通常为 80 (HTTP) 或 443 (HTTPS)。
- ASP.NET Core 模块接收本机请求,并将其传递给 IIS HTTP 服务器 (
IISHttpServer
)。 IIS HTTP 服务器是将请求从本机转换为托管的 IIS 进程内服务器实现。
在 IIS HTTP 服务器处理请求后:
- 请求被发送到 ASP.NET Core 中间件管道。
- 中间件管道处理该请求并将其作为
HttpContext
实例传递给应用的逻辑。 - 应用的响应通过 IIS HTTP 服务器传递回 IIS。
- IIS 将响应发送到发起请求的客户端。
CreateDefaultBuilder
添加 IServer 实例的方式是:调用 UseIIS 方法来启动 CoreCLR 和将应用托管在 IIS 工作进程(w3wp.exe
或 iisexpress.exe
)内。 性能测试表明,与在进程外托管应用并将请求代理传入 Kestrel 相比,在进程中托管 .NET Core 应用可提供明显更高的请求吞吐量。
作为单个文件可执行文件发布的应用无法由进程内托管模型加载。
应用程序配置
要配置 IIS 选项,请在 Program.cs
中包括 IISServerOptions 的服务配置。 下面的示例将禁用 AutomaticAuthentication:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.Configure<IISServerOptions>(options =>
{
options.AutomaticAuthentication = false;
});
builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
builder.Services.AddRazorPages();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
选项 | 默认 | 设置 |
---|---|---|
AutomaticAuthentication |
true |
若为 true ,IIS 服务器将设置经过 Windows 身份验证进行身份验证的 HttpContext.User 。 若为 false ,则服务器仅提供 HttpContext.User 的 identity 并在 AuthenticationScheme 显式请求时响应质询。 必须在 IIS 中启用 Windows 身份验证使 AutomaticAuthentication 得以运行。 有关详细信息,请参阅 Windows 身份验证。 |
AuthenticationDisplayName |
null |
设置在登录页上向用户显示的显示名。 |
AllowSynchronousIO |
false |
HttpContext.Request 和 HttpContext.Response 是否允许同步 I/O。 |
MaxRequestBodySize |
30000000 |
获取或设置 HttpRequest 的最大请求正文大小。 请注意,IIS 本身有限制 maxAllowedContentLength ,这一限制将在 IISServerOptions 中设置 MaxRequestBodySize 之前进行处理。 更改 MaxRequestBodySize 不会影响 maxAllowedContentLength 。 若要增加 maxAllowedContentLength ,请在 web.config 中添加一个将 maxAllowedContentLength 设置为更高值的项。 有关更多详细信息,请参阅配置。 |
进程内和进程外托管之间的差异
在进程内托管时,将应用以下特征:
使用 IIS HTTP 服务器 (
IISHttpServer
),而不是 Kestrel 服务器。 对于进程内托管,CreateDefaultBuilder
会调用 UseIIS 来进行以下操作:- 注册
IISHttpServer
。 - 在 ASP.NET Core 模块后运行时,配置服务器应侦听的端口和基本路径。
- 配置主机以捕获启动错误。
- 注册
requestTimeout
属性不适用于进程内托管。不支持在应用之间共享应用池。 每个应用使用一个应用池。
应用和已安装的运行时(x64 或 x86)的体系结构(位数)必须与应用池的体系结构匹配。 例如,为 32 位 (x86) 发布的应用必须已为其 IIS 应用程序池启用 32 位。 有关详细信息,请参阅创建 IIS 站点部分。
检测到客户端连接断开。 客户端断开连接时,将取消
HttpContext.RequestAborted
取消标记。在进程内托管时,不会在内部调用 AuthenticateAsync 来初始化用户。 因此,默认情况下不激活每次身份验证后用于转换声明的 IClaimsTransformation 实现。 使用 IClaimsTransformation 实现转换声明时,请调用 AddAuthentication 以添加身份验证服务:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Server.IIS;
using Microsoft.EntityFrameworkCore;
using RPauth.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.Configure<IISServerOptions>(options =>
{
options.AutomaticAuthentication = false;
});
builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
builder.Services.AddAuthentication(IISServerDefaults.AuthenticationScheme);
builder.Services.AddRazorPages();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
- 不支持 Web 包(单文件)部署。
进程内托管在与其 IIS 工作进程相同的进程中运行 ASP.NET Core 应用。 进程内承载相较进程外承载提供更优的性能,因为请求并不通过环回适配器进行代理,环回适配器是一个网络接口,用于将传出的网络流量返回给同一计算机。
下图说明了 IIS、ASP.NET Core 模块和进程内托管的应用之间的关系:
启用进程内托管
自 ASP.NET Core 3.0 起,默认情况下已为部署到 IIS 的所有应用启用进程内托管。
若要显式配置进程内托管的应用,请在项目文件 (.csproj
) 中将 <AspNetCoreHostingModel>
属性的值设置为 InProcess
:
<PropertyGroup>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
一般体系结构
请求的常规流程如下:
- 请求从 Web 到达内核模式 HTTP.sys 驱动程序。
- 驱动程序将本机请求路由到网站的配置端口上的 IIS,通常为 80 (HTTP) 或 443 (HTTPS)。
- ASP.NET Core 模块接收本机请求,并将其传递给 IIS HTTP 服务器 (
IISHttpServer
)。 IIS HTTP 服务器是将请求从本机转换为托管的 IIS 进程内服务器实现。
在 IIS HTTP 服务器处理请求后:
- 请求被发送到 ASP.NET Core 中间件管道。
- 中间件管道处理该请求并将其作为
HttpContext
实例传递给应用的逻辑。 - 应用的响应通过 IIS HTTP 服务器传递回 IIS。
- IIS 将响应发送到发起请求的客户端。
CreateDefaultBuilder
添加 IServer 实例的方式是:调用 UseIIS 方法来启动 CoreCLR 和将应用托管在 IIS 工作进程(w3wp.exe
或 iisexpress.exe
)内。 性能测试表明,与在进程外托管应用并将请求代理传入 Kestrel 相比,在进程中托管 .NET Core 应用可提供明显更高的请求吞吐量。
作为单个文件可执行文件发布的应用无法由进程内托管模型加载。
应用程序配置
要配置 IIS 选项,请在 ConfigureServices 中包括 IISServerOptions 的服务配置。 下面的示例禁用 AutomaticAuthentication:
services.Configure<IISServerOptions>(options =>
{
options.AutomaticAuthentication = false;
});
选项 | 默认 | 设置 |
---|---|---|
AutomaticAuthentication |
true |
若为 true ,IIS 服务器将设置经过 Windows 身份验证进行身份验证的 HttpContext.User 。 若为 false ,则服务器仅提供 HttpContext.User 的 identity 并在 AuthenticationScheme 显式请求时响应质询。 必须在 IIS 中启用 Windows 身份验证使 AutomaticAuthentication 得以运行。 有关详细信息,请参阅 Windows 身份验证。 |
AuthenticationDisplayName |
null |
设置在登录页上向用户显示的显示名。 |
AllowSynchronousIO |
false |
HttpContext.Request 和 HttpContext.Response 是否允许同步 I/O。 |
MaxRequestBodySize |
30000000 |
获取或设置 HttpRequest 的最大请求正文大小。 请注意,IIS 本身有限制 maxAllowedContentLength ,这一限制将在 IISServerOptions 中设置 MaxRequestBodySize 之前进行处理。 更改 MaxRequestBodySize 不会影响 maxAllowedContentLength 。 若要增加 maxAllowedContentLength ,请在 web.config 中添加一个将 maxAllowedContentLength 设置为更高值的项。 有关更多详细信息,请参阅配置。 |
进程内和进程外托管之间的差异
在进程内托管时,将应用以下特征:
使用 IIS HTTP 服务器 (
IISHttpServer
),而不是 Kestrel 服务器。 对于进程内托管,CreateDefaultBuilder
会调用 UseIIS 来进行以下操作:- 注册
IISHttpServer
。 - 在 ASP.NET Core 模块后运行时,配置服务器应侦听的端口和基本路径。
- 配置主机以捕获启动错误。
- 注册
requestTimeout
属性不适用于进程内托管。不支持在应用之间共享应用池。 每个应用使用一个应用池。
应用和已安装的运行时(x64 或 x86)的体系结构(位数)必须与应用池的体系结构匹配。 例如,为 32 位 (x86) 发布的应用必须已为其 IIS 应用程序池启用 32 位。 有关详细信息,请参阅创建 IIS 站点部分。
检测到客户端连接断开。 客户端断开连接时,将取消
HttpContext.RequestAborted
取消标记。在进程内托管时,不会在内部调用 AuthenticateAsync 来初始化用户。 因此,默认情况下不激活每次身份验证后用于转换声明的 IClaimsTransformation 实现。 使用 IClaimsTransformation 实现转换声明时,请调用 AddAuthentication 以添加身份验证服务:
public void ConfigureServices(IServiceCollection services) { services.AddTransient<IClaimsTransformation, ClaimsTransformer>(); services.AddAuthentication(IISServerDefaults.AuthenticationScheme); } public void Configure(IApplicationBuilder app) { app.UseAuthentication(); }
不支持 Web 包(单文件)部署。