注意
此版本不是本文的最新版本。 对于当前版本,请参阅本文的 .NET 9 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 NET Core 支持策略。 对于当前版本,请参阅本文的 .NET 9 版本。
本文介绍在构建 Blazor 应用时如何控制中间语言 (IL) 裁边器。
Blazor WebAssembly 执行中间语言 (IL) 裁剪以减小发布输出的大小。 裁剪操作在发布应用程序时进行。
配置
若要配置 IL 裁剪器,请参阅 .NET 基础知识文档中的裁剪选项一文,其中包括有关以下主题的指导:
- 通过项目文件中的
<PublishTrimmed>
属性对整个应用禁用裁剪。 - 控制 IL 裁剪器如何放弃未充分利用的 IL。
- 阻止 IL 裁剪器裁剪特定程序集。
- 要裁剪的“根”程序集。
- 通过在项目文件中将
<SuppressTrimAnalysisWarnings>
属性设置为false
来显示关于反射的类型的警告。 - 控制符号裁剪和调试程序支持。
- 设置 IL 裁剪器功能以裁剪框架库功能。
默认裁剪器粒度
Blazor 应用的默认裁剪器粒度为 partial
。 若要裁剪所有程序集,请在应用的项目文件中将粒度更改为 full
:
<PropertyGroup>
<TrimMode>full</TrimMode>
</PropertyGroup>
有关详细信息,请参阅《裁剪选项》(.NET 文档)。
未能保留已发布应用程序所使用的类型
裁剪操作可能会对已发布的应用程序产生不利影响,从而导致运行时错误。 在使用反射的应用程序中,IL 裁剪器通常无法确定运行时反射所需的类型,进而会将这些类型裁剪掉,或者从方法中裁剪掉参数名称。 对于用于 JS 互操作、JSON 序列化/反序列化以及其他操作的复杂框架类型,可能出现这种情况。
IL 裁剪器也无法在运行时对应用的动态行为作出响应。 若要确保裁剪后的应用在部署后正常工作,请在开发时经常对已发布的输出进行测试。
考虑使用以下客户端组件Blazor Web App,在 (.NET 8 或更高版本) 反序列化KeyValuePair集合 (List<KeyValuePair<string, string>>
) 时:
@rendermode @(new InteractiveWebAssemblyRenderMode(false))
@using System.Diagnostics.CodeAnalysis
@using System.Text.Json
<dl>
@foreach (var item in @items)
{
<dt>@item.Key</dt>
<dd>@item.Value</dd>
}
</dl>
@code {
private List<KeyValuePair<string, string>> items = [];
[StringSyntax(StringSyntaxAttribute.Json)]
private const string data =
"""[{"key":"key 1","value":"value 1"},{"key":"key 2","value":"value 2"}]""";
protected override void OnInitialized()
{
JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };
items = JsonSerializer
.Deserialize<List<KeyValuePair<string, string>>>(data, options)!;
}
}
当在本地运行该应用程序时,上述组件会正常执行,并生成以下呈现的定义列表 (<dl>
):
key 1
value 1
key 2
value 2
当发布该应用程序时,即使在项目文件中将 KeyValuePair设置为 <PublishTrimmed>
, 仍会从应用程序中被裁剪掉。 访问该组件会引发以下异常:
Unhandled exception rendering component: ConstructorContainsNullParameterNames, System.Collections.Generic.KeyValuePair`2[System.String,System.String]
为了解决类型丢失的问题,可以考虑以下方法。
将类型保留为动态依赖项
建议使用 [DynamicDependency]
特性创建一个动态依赖项,以保留该类型。
如果 @using
指令尚不存在,请添加该指令用于 System.Diagnostics.CodeAnalysis:
@using System.Diagnostics.CodeAnalysis
添加 [DynamicDependency]
属性以保留 KeyValuePair:
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(KeyValuePair<string, string>))]
private List<KeyValuePair<string, string>> items = [];
自定义类型
以下修改会创建一个 StringKeyValuePair
类型供该组件使用。
StringKeyValuePair.cs
:
[method: SetsRequiredMembers]
public sealed class StringKeyValuePair(string key, string value)
{
public required string Key { get; init; } = key;
public required string Value { get; init; } = value;
}
对该组件进行修改,使其使用 StringKeyValuePair
类型:
- private List<KeyValuePair<string, string>> items = [];
+ private List<StringKeyValuePair> items = [];
- items = JsonSerializer.Deserialize<List<KeyValuePair<string, string>>>(data, options)!;
+ items = JsonSerializer.Deserialize<List<StringKeyValuePair>>(data, options)!;
由于在发布应用程序时,Blazor 永远不会裁剪自定义类型,所以在应用程序发布后,该组件将按预期工作。