配置适用于 ASP.NET Core Blazor 的裁边器

注意

此版本不是本文的最新版本。 对于当前版本,请参阅本文的 .NET 9 版本

警告

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 NET Core 支持策略。 对于当前版本,请参阅本文的 .NET 9 版本

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

对于当前版本,请参阅本文的 .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 永远不会裁剪自定义类型,所以在应用程序发布后,该组件将按预期工作。

其他资源