原文链接:https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-rc-1/
著者:ダニエル·ロス
砂漠の果ての狼
.NET 7 Release Candidate 1 (RC1) 现已推出,其中包括对 ASP.NET Core 的许多重大新改进。
以下は、このプレビュー版の新機能の概要です。
- Blazor Web Assemblyでの動的認証要求
- 位置変更イベントの処理
- Blazor Web Assemblyデバッグの改善
- NET 6プロジェクト用の. NET Web Assemblyプロジェクトビルドツール
- Web Assemblyでの. NET Java Script相互運用性
- Kestrelの完全な証明書チェーンの改善
- HTTP/2アップロードの高速化
- HTTP/3の改良
- HTTP/3経由のWebTransportの実験的なKestrelサポート
- g RPC JSONトランスコーディングの実験的なOpen APIサポート
- レート制限ミドルウェアの改善
- macOS開発証明書の改善
有关为 .NET 7 计划的 ASP.NET Core 工作的更多详细信息,请参阅 GitHub 上的 .NET 7 的完整 ASP.NET Core 路线图。
使用開始。
要开始使用 .NET 7 Release Candidate 1 中的 ASP.NET Core,请安装 .NET 7 SDK。
如果你在 Windows 上使用 Visual Studio,我们建议安装最新的Visual Studio 2022 预览版。如果您使用的是 macOS,我们建议您安装最新的Visual Studio 2022 for Mac 预览版。
最新の. NET Web Assemblyビルドツールをインストールするには、上位のコマンドプロンプトから次のコマンドを実行します。
dotnet workload install wasm-tools
既存のプロジェクトのアップグレード
既存のASP.NET Coreアプリケーションを. NET 7 Preview 7から. NET 7 RC1にアップグレードするには:
- 将所有 Microsoft.AspNetCore._ 包引用更新为
.7.0.0-rc.1._ - 将所有 Microsoft.Extensions._ 包引用更新为
.7.0.0-rc.1._
另请参阅.NET 7 的 ASP.NET Core 中的重大更改的完整列表。
Blazor Web Assemblyでの動的認証要求
Blazor 为使用 OpenID Connect 和各种身份提供程序(包括 Azure Active Directory (Azure AD) 和 Azure AD B2C)的身份验证提供开箱即用的支持。在 .NET 7 中,Blazor 现在支持在运行时使用自定义参数创建动态身份验证请求,以处理 Blazor WebAssembly 应用中更高级的身份验证方案。要指定其他参数,请使用新的InteractiveRequestOptions类型和NavigateToLogin``辅助方法NavigationManager。
たとえば、IDプロバイダにログインプロンプトを指定して、次のように認証を行うことができます。
InteractiveRequestOptions requestOptions = new()
{
Interaction = InteractionType.SignIn,
ReturnUrl = NavigationManager.Uri,
};
requestOptions.TryAddAdditionalParameter("login_hint", "user@example.com");
NavigationManager.NavigateToLogin("authentication/login", requestOptions);
同样,您可以指定 OpenID Connect prompt 参数,例如当您想要强制交互式登录时:
InteractiveRequestOptions requestOptions = new()
{
Interaction = InteractionType.SignIn,
ReturnUrl = NavigationManager.Uri,
};
requestOptions.TryAddAdditionalParameter("prompt", "login");
NavigationManager.NavigateToLogin("authentication/login", requestOptions);
您可以使用IAccessTokenProvider直接用于请求令牌时指定这些选项:
var accessTokenResult = await AccessTokenProvider.RequestAccessToken(
new AccessTokenRequestOptions
{
Scopes = new[] { "SecondAPI" }
});
if (!accessTokenResult.TryGetToken(out var token))
{
accessTokenResult.InteractiveOptions.AddAdditionalParameter("login_hint", "user@example.com");
NavigationManager.NavigateToLogin(accessTokenResult.InteractiveRequestUrl, accessTokenResult.InteractionOptions);
}
当无法获取令牌时,您还可以通过AuthorizationMessageHandler指定身份验证请求选项:
try
{
await httpclient.Get("/orders");
}
catch (AccessTokenNotAvailableException ex)
{
ex.Redirect(requestOptions =>
{
requestOptions.AddAdditionalParameter("login_hint", "user@example.com");
});
}
認証要求に指定されたその他のパラメータは、基盤となる認証ライブラリに渡され、そこで処理されます。
注:msal.jsへの追加パラメータの指定は完全には実装されていませんが、今後のリリースで完了する予定です。
位置変更イベントの処理
NET 7のBlazorが位置変更イベントの処理をサポートしました。これにより、ユーザがページナビゲーションを実行するときに、保存されていない作業について警告したり、関連するアクションを実行したりできます。
使用NavigationManager服务的RegisterLocationChangingHandler方法注册处理程序用于处理位置更改事件。然后,您的处理程序可以在导航时执行异步工作,或者通过调用LocationChangingContext的PreventNavigation取消导航。RegisterLocationChangingHandler返回一个IDisposable实例,该实例在释放时会删除相应的位置更改处理程序。
たとえば、次のハンドラはカウンタページへのナビゲーションをブロックします。
var registration = NavigationManager.RegisterLocationChangingHandler(async context =>
{
if (context.TargetLocation.EndsWith("counter"))
{
context.PreventNavigation();
}
});
请注意,您的处理程序只会被用于应用程序内的内部导航调用。外部导航只能使用 JavaScript 中的beforeunload 事件同步处理。
新NavigationLock组件使处理位置变化事件的常见场景更容易。NavigationLock公开一个OnBeforeInternalNavigation回调,您可以使用它来拦截和处理内部位置更改事件。如果您希望用户也确认外部导航,您可以使用该ConfirmExternalNavigations属性,它将拦截beforeunload事件并触发浏览器特定提示。
<EditForm EditContext="editContext" OnValidSubmit="Submit">
...
</EditForm>
<NavigationLock OnBeforeInternalNavigation="ConfirmNavigation" ConfirmExternalNavigation />
@code {
private readonly EditContext editContext;
...
// Called only for internal navigations
// External navigations will trigger a browser specific prompt
async Task ConfirmNavigation(LocationChangingContext context)
{
if (editContext.IsModified())
{
var isConfirmed = await JS.InvokeAsync<bool>("window.confirm", "Are you sure you want to leave this page?");
if (!isConfirmed)
{
context.PreventNavigation();
}
}
}
}
Blazor Web Assemblyデバッグの改善
NET 7のBlazor Web Assemblyデバッグには以下の改善が含まれます。
- ユーザーコードにない型メンバーを表示または非表示にするJust My Code設定のサポート
- 多次元配列のチェックのサポート
- コールスタックに非同期メソッドの正しい名前が表示されるようになった
- 表現評価の改善
- 正确处理派生成员的
new关键字 - 在
System.Diagnostics中支持调试器相关的属性
NET 6プロジェクトのための. NET Web Assemblyビルドツール
现在,在使用 .NET 7 SDK 时,您可以将 .NET WebAssembly 构建工具用于 .NET 6 项目。新的wasm-tools-net6工作负载包括用于 .NET 6 项目的 .NET WebAssembly 构建工具,以便它们可以与 .NET 7 SDK 一起使用。要安装新wasm-tools-net6工作负载,请从提升的命令提示符运行以下命令:
dotnet workload install wasm-tools-net6
安装 .NET WebAssembly 构建工具带来的wasm-tools工作负载是为 .NET 7 项目准备的(翻译有点拗口,这句可能翻译错了,原文是:The existing wasm-tools workload installs the .NET WebAssembly build tools for .NET 7 projects.)。但是,.NET 7 版本的 .NET WebAssembly 构建工具与使用 .NET 6 构建的现有项目不兼容。需要同时支持 .NET 6 和 .NET 7 使用 .NET WebAssembly 构建工具的项目将需要使用 multi-targeting。
Web Assemblyでの. NET Java Script相互運用性
NET 7では、JavaScriptベースのアプリケーションで. NETを使用するための新しい低レベルのメカニズムが導入されました。この新しいJava Script相互運用機能により、Blazor UIコンポーネントモデルに依存することなく、. NET Web Assemblyランタイムを使用してJava Scriptから. NETコードを呼び出すことも、. NETからJava Script機能を呼び出すこともできます。
查看新的 JavaScript 互操作功能的最简单方法是在wasm-experimental工作负载中使用新的实验模板:
dotnet workload install wasm-experimental
このワークロードには、Web Assembly Browser AppとWeb Assembly Console Appの2つのプロジェクトテンプレートが含まれます。これらのテンプレートは実験的なものであるため、開発者ワークフローはまだ完全に整理されていません(たとえば、テンプレートはVisual Studioで実行されていません)。しかし、. NET 7はこれらのテンプレートで使用される. NET APIとJava Script APIをサポートし、Java Script経由でWeb Assemblyで. NETを使用するための基盤を提供します。
Web Assemblyブラウザアプリケーションは、次のコマンドを実行して作成できます。
dotnet new wasmbrowser
このテンプレートは、ブラウザで. NETとJava Scriptの両方を使用する方法を示すシンプルなWebアプリケーションを作成します。Web Assemblyコンソールアプリケーションは似ていますが、ブラウザベースのWebアプリケーションではなくNode.jsコンソールアプリケーションとして実行されます。
创建的示例项目中的 main.js 中的 JavaScript 模块演示了如何从 JavaScript 运行 .NET 代码。相关 API 是从 dotnet.js 导入的。这些 API 使您能够设置可以导入到 C# 代码中的命名模块,以及调用 .NET 代码公开的方法,包括Program.Main:
import { dotnet } from "./dotnet.js";
const is_browser = typeof window != "undefined";
if (!is_browser) throw new Error(`Expected to be running in a browser`);
// Setup the .NET WebAssembly runtime
const { setModuleImports, getAssemblyExports, getConfig, runMainAndExit } =
await dotnet
.withDiagnosticTracing(false)
.withApplicationArgumentsFromQuery()
.create();
// Set module imports that can be called from .NET
setModuleImports("main.js", {
window: {
location: {
href: () => globalThis.window.location.href,
},
},
});
const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
const text = exports.MyClass.Greeting(); // Call into .NET from JavaScript
console.log(text);
document.getElementById("out").innerHTML = `${text}`;
await runMainAndExit(config.mainAssemblyName, ["dotnet", "is", "great!"]); // Run Program.Main
要导入 JavaScript 函数以便可以从 C# 调用它,请在匹配的方法签名上使用新的JSImportAttribute:
[JSImport("window.location.href", "main.js")]
internal static partial string GetHRef();
JSImportAttribute的第一个参数是要导入的 JavaScript 函数的名称,第二个参数是模块的名称,这两个参数都是由 main.js 中的setModuleImports调用设置的。
在导入的方法签名中,您可以对参数和返回值使用 .NET 类型,这些类型将为您编组。使用JSMarshalAsAttribute<T>控制导入的方法参数的编组方式。例如,您可以选择将一个long 编组为JSType.Number或JSType.BigInt。您可以将Action/Func回调作为参数传递,这些参数将被编组为可调用的 JavaScript 函数。您可以同时传递 JavaScript 和托管对象引用,它们将被编组为代理对象,使对象在边界上保持活动状态,直到代理被垃圾回收。您还可以导入和导出带Task返回值的异步方法,它将作为 JavaScript promises 进行编组。在导入和导出的方法上,大多数封装类型作为参数和返回值双向工作,。
使用JSExportAttribute导出 .NET 方法以便可以从 JavaScript 调用:
[JSExport]
internal static string Greeting()
{
var text = $"Hello, World! Greetings from {GetHRef()}";
Console.WriteLine(text);
return text;
}
Blazor 提供了自己的基于 IJSRuntime 接口的 JavaScript 互操作机制,该机制在所有 Blazor 托管模型中得到统一支持。这种常见的异步抽象使库作者能够构建可在 Blazor 生态系统中共享的 JavaScript 互操作库,并且仍然是在 Blazor 中执行 JavaScript 互操作的推荐方式。但是,在 Blazor WebAssembly 应用程序中,您还可以选择IJSInProcessRuntime进行同步 JavaScript 互操作调用,甚至使用IJSUnmarshalledRuntime进行解组调用。 IJSUnmarshalledRuntime使用起来很棘手,仅部分支持。在 .NET 7 中IJSUnmarshalledRuntime现在已经过时,应该用[JSImport]/[JSExport]机制替换。Blazor 不直接公开从 JavaScript 使用的dotnet运行时实例,但仍然可以通过.getDotnetRuntime(0)调用。您还可以通过在 C#代码中调用JSHost.ImportAsync导入 JavaScript 模块,这可以使模块导出对 [JSImport]可见。
Kestrelの完全な証明書チェーンの改善
类型X509Certificate2Collection的HttpsConnectionAdapterOptions具有新属性ServerCertificateChaintype ,通过允许指定包含中间证书的完整链,可以更轻松地验证证书链。有关详细信息,请参阅dotnet/aspnetcore#21513。
HTTP/2アップロードの高速化
KestrelのデフォルトHTTP/2アップロード接続ウィンドウサイズを128 KBから1 MBに増やし、Kestrelのデフォルト設定を使用した高遅延接続のHTTP/2アップロード速度を大幅に向上させました。
わずか10ミリ秒の人工レイテンシを導入した後、local host上の単一ストリームを使用して108 MBのファイルアップロードをアップロードして、この制限を増やす効果をテストしたところ、アップロード速度が約6 倍向上しました。
以下のスクリーンショットは、Edgeの開発ツールネットワークタブで108 MBをアップロードするのにかかる時間を比較しています。

- 約数の和は26.9。
- その後4.3 秒
HTTP/3の改良
NET 7 RC1はKestrelのHTTP/3サポートを改善し続けている。主な改善点は、HTTP/1.1およびHTTP/2との機能的な同等性とパフォーマンスです。
此版本最大的特点是完全支持ListenOptions.UseHttps使用 HTTP/3。Kestrel 提供了用于配置连接证书的高级选项,例如拦截到Server Name Indication (SNI)。
次の例では、SNIコールバックを使用してTLSオプションを解決する方法を示します。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(8080, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
var options = new SslServerAuthenticationOptions
{
ServerCertificate = ResolveCertForHost(context.ClientHelloInfo.ServerName)
};
return new ValueTask<SslServerAuthenticationOptions>(options);
},
});
});
});
また、. NET 7 RC1でHTTP/3の割り当てを減らすために多くの作業を行いました。改善点の一部はこちらからご覧いただけます:
- HTTP/3: Avoid per-request cancellation token allocations
- HTTP/3: Avoid ConnectionAbortedException allocations
- HTTP/3: ValueTask pooling
HTTP/3経由のWebTransportの実験的なKestrelサポート
我们很高兴地宣布在 Kestrel 中对基于 HTTP/3 的 WebTransport 的内置实验性支持。此功能是由我们优秀的实习生 Daniel 编写的!WebTransport 对于类似于 WebSockets 的传输协议是一个新的草案规范,它允许每个连接使用多个流。这对于拆分通信通道并因此避免线头阻塞很有用。例如,考虑一个基于网络的在线游戏,其中游戏状态在一个双向流上传输,玩家对游戏语音聊天功能的语音在另一个双向流上传输,而玩家的控制在单向流上传输。使用 WebSockets,这一切都需要放在单独的连接上或压缩到单个流中。使用 WebTransport,您可以将所有流量保留在一个连接上,但将它们分成自己的流,如果一个流阻塞,其他流将继续不间断。
詳細については、別のブログ記事でご紹介します。
g RPC JSONトランスコーディングの実験的なOpen APIサポート
gRPC JSON 转码是 .NET 7 中的一项新功能,用于将 gRPC API 转换为 RESTful API。
NET 7 RC1では、g RPCトランスコードRESTful APIからOpen APIを生成する実験的サポートが追加された。g RPC JSONトランスコーディングを備えたOpen APIは非常に需要のある機能であり、これらの素晴らしいテクノロジーを組み合わせる方法を提供できることを嬉しく思います。NuGetパッケージは. NET 7では実験的なものであり、これらの機能を統合する最良の方法を探索する時間を与えてくれます。
g RPC JSONトランスコードでOpen APIを有効にするには:
- 添加对Microsoft.AspNetCore.Grpc.Swagger的包引用。版本必须为 0.3.0-xxx 或更高版本。
- 在启动时配置 Swashbuckle。该
AddGrpcSwagger方法将 Swashbuckle 配置为包含 gRPC 端点。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc().AddJsonTranscoding();
builder.Services.AddGrpcSwagger();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1",
new OpenApiInfo { Title = "gRPC transcoding", Version = "v1" });
});
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.MapGrpcService<GreeterService>();
app.Run();
SwashbuckleがRESTful g RPCサービス用にSwaggerを生成していることを確認するには、アプリケーションを起動し、Swagger UIページに移動します。

制限フローミドルウェアの改善
NET 7 RC1のストリーム制限ミドルウェアに多くの機能を追加し、より強力で使いやすくしました。
我们添加了可用于启用或禁用给定端点上的速率限制的属性。例如,以下是如何将命名策略应用MyControllerPolicy到控制器:
public class MyController : Controller
{
[EnableRateLimitingAttribute("MyControllerPolicy")]
public IActionResult Index()
{
return View();
}
}
特定のエンドポイントまたはエンドポイントのセットでレート制限を完全に無効にすることもできます。一連のエンドポイントでレート制限を有効にしているとします。
app.MapGroup("/public/todos").RequireRateLimiting("MyGroupPolicy");
次に、以下のように、グループ内の特定のエンドポイントのレート制限を無効にできます。
app.MapGroup("/public/todos/donothing").DisableRateLimiting();
您现在还可以将策略直接应用于端点。与命名策略不同,以这种方式添加的策略不需要在RateLimiterOptions. 假设您已经定义了一个策略类型:
public class MyRateLimiterPolicy : IRateLimiterPolicy<string>
{
...
}
次のように、インスタンスをエンドポイントに直接追加できます。
app.MapGet("/", () => "Hello World!").RequireRateLimiting(new MyRateLimiterPolicy());
最后,我们更新了RateLimiterOptions便捷方法以采用Action<Options>而不是Options实例,还添加了IServiceCollection使用速率限制的扩展方法。因此,要在您的应用中启用上述所有速率限制策略,您可以执行以下操作:
builder.Services.AddRateLimiter(options =>
{
options.AddTokenBucketLimiter("MyControllerPolicy", options =>
{
options.TokenLimit = 1;
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
options.QueueLimit = 1;
options.ReplenishmentPeriod = TimeSpan.FromSeconds(10);
options.TokensPerPeriod = 1;
})
.AddPolicy<string>("MyGroupPolicy", new MyRateLimiterPolicy());
});
这会将 TokenBucketLimiter应用于您的控制器,将您的自定义MyRateLimiterPolicy应用于匹配端点./public/todos(除了/public/todos/donothing),并将您的自定义MyRateLimiterPolicy应用于/。
macOS開発証明書の改善
今回のリリースでは、macOSユーザーがHTTPSを使用して証明書を開発する際のエクスペリエンスにいくつかの大幅な品質改善が加えられ、ASP.NET Core HTTPS開発時に表示される認証プロンプトの証明書の作成、信頼、読み取り、削除が大幅に削減されました。macOS 上のASP.NET Core開発者がワークフローで開発証明書を使用しようとすると、これは常に頭痛の種でした。
在此版本中,通过dotnet dev-certs工具在 macOS 上生成的开发证书具有更窄的信任范围,现在将设置添加到每个用户的信任设置中而不是系统范围内,并且 Kestrel 将能够绑定到这些新证书而无需访问系统钥匙串。作为这项工作的一部分,还对质量进行了一些改进,例如重新处理一些面向用户的消息以提高清晰度和准确性。
macOSで開発中にHTTPSを使用する場合、これらの変更を組み合わせることで、よりスムーズなエクスペリエンスとパスワードプロンプトの削減が可能になります。
新しいBlazorアップデートの実際のアプリケーションをチェック!
有关 Blazor WebAssembly 中的动态身份验证请求、Blazor WebAssembly 调试改进以及 WebAssembly 上的 .NET JavaScript 互操作的实时演示,请参阅我们最近的Blazor 社区站会:

フィードバックを与えること
我们希望您喜欢 .NET 7 中的 ASP.NET Core 预览版。通过在GitHub 上提交问题,让我们知道您对这些新改进的看法。
ASP.NET Coreをお試しください。