Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
This isn't the latest version of this article. For the current release, see the .NET 9 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see the .NET and .NET Core Support Policy. For the current release, see the .NET 9 version of this article.
Important
This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
For the current release, see the .NET 9 version of this article.
This article explains how to control the Intermediate Language (IL) Trimmer when building a Blazor app.
Blazor WebAssembly performs Intermediate Language (IL) trimming to reduce the size of the published output. Trimming occurs when publishing an app.
To configure the IL Trimmer, see the Trimming options article in the .NET Fundamentals documentation, which includes guidance on the following subjects:
<PublishTrimmed>
property in the project file.<SuppressTrimAnalysisWarnings>
property to false
in the project file.The default trimmer granularity for Blazor apps is partial
. To trim all assemblies, change the granularity to full
in the app's project file:
<ItemGroup>
<TrimMode>full</TrimMode>
</ItemGroup>
For more information, see Trimming options (.NET documentation).
Trimming may have detrimental effects for a published app leading to runtime errors. In apps that use reflection, the IL Trimmer often can't determine the required types for runtime reflection and trims them away or trims away parameter names from methods. This can happen with complex framework types used for JS interop, JSON serialization/deserialization, and other operations.
The IL Trimmer is also unable to react to an app's dynamic behavior at runtime. To ensure the trimmed app works correctly once deployed, test published output frequently while developing.
Consider the following client-side component in a Blazor Web App (ASP.NET Core 8.0 or later) that deserializes a KeyValuePair collection (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)!;
}
}
The preceding component executes normally when the app is run locally and produces the following rendered definition list (<dl>
):
key 1
value 1
key 2
value 2
When the app is published, KeyValuePair is trimmed from the app, even in spite of setting the <PublishTrimmed>
property to false
in the project file. Accessing the component throws the following exception:
Unhandled exception rendering component: ConstructorContainsNullParameterNames, System.Collections.Generic.KeyValuePair`2[System.String,System.String]
To address lost types, consider the following approaches.
We recommend creating a dynamic dependency to preserve the type with the [DynamicDependency]
attribute.
If not already present, add an @using
directive for System.Diagnostics.CodeAnalysis:
@using System.Diagnostics.CodeAnalysis
Add a [DynamicDependency]
attribute to preserve the KeyValuePair:
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(KeyValuePair<string, string>))]
private List<KeyValuePair<string, string>> items = [];
The following modifications create a StringKeyValuePair
type for use by the component.
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;
}
The component is modified to use the StringKeyValuePair
type:
- 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)!;
Because custom types are never trimmed by Blazor when an app is published, the component works as designed after the app is published.
ASP.NET Core feedback
ASP.NET Core is an open source project. Select a link to provide feedback:
Events
Power BI DataViz World Championships
Feb 14, 4 PM - Mar 31, 4 PM
With 4 chances to enter, you could win a conference package and make it to the LIVE Grand Finale in Las Vegas
Learn moreTraining
Module
Build rich interactive components with Blazor web apps - Training
Learn how to interoperate Blazor apps with JavaScript code, use templated components, and handle component lifecycle events.
Documentation
ASP.NET Core Blazor WebAssembly native dependencies
Learn how to build Blazor WebAssembly apps with native dependencies built to run on WebAssembly in the browser.
ASP.NET Core Blazor performance best practices
Tips for increasing performance in ASP.NET Core Blazor apps and avoiding common performance problems.
Lazy load assemblies in ASP.NET Core Blazor WebAssembly
Discover how to lazy load assemblies in Blazor WebAssembly apps.