dotnet / dotnet/aspnetcore

[Blazor Hybrid / iOS Release] Microsoft.AspNetCore.WebUtilities trimmed out when QueryHelpers is called only from .razor

Open
#67,184 1 comment 0 reactions 1 assignee Claimed by @mattleibow View on GitHub
area-blazor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

> **2026-06-12 update (filer self-correction)**: The original title and "transitive v10 pin" diagnosis below were wrong. `Microsoft.AspNetCore.Components.Web` does not reference `Microsoft.AspNetCore.WebUtilities` at all (verified against the P4 and P5 nuspecs and the `Components.Web.dll` assembly references). The real issue is that `WebUtilities` is part of the `Microsoft.AspNetCore.App` shared framework on the server, but Blazor Hybrid on iOS has no shared framework — and nothing in the consuming app's compiled IL references it (the only usage is from Razor markup), so the trimmer removes it from the bundle. Revised summary follows; original body kept below for trail.

## Revised summary (2026-06-12)

A Blazor Hybrid app targeting `net11.0-ios` that calls `Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(...)` **only from `.razor` markup** crashes at runtime in iOS Release sideloads with:

```
FileNotFoundException: Could not load file or assembly 'Microsoft.AspNetCore.WebUtilities, Version=11.0.0.0, ...'
```

`WebUtilities` is not referenced by `Components.Web`, `Components.WebView`, or `Components.WebView.Maui`. It is normally bundled because:
- on the server it is part of the `Microsoft.AspNetCore.App` shared framework, and
- on the client it is brought in by the workload's framework reference set.

In a `net11.0-ios` Release build, the iOS trimmer strips `Microsoft.AspNetCore.WebUtilities.dll` from the bundle because no compiled IL in any referenced assembly directly references it — the only call site is in Razor markup (`Index.razor`), and the trimmer cannot statically root through Razor compilation in this configuration. The result is a silent runtime failure: `@onclick` handler aborts mid-call, no toast, no popup, button looks dead.

## Verified non-bug paths

- `dotnet nuget why src/SentenceStudio.iOS/SentenceStudio.iOS.csproj Microsoft.AspNetCore.WebUtilities --framework net11.0-ios` before workaround → "Project 'SentenceStudio.iOS' does not have a dependency on 'Microsoft.AspNetCore.WebUtilities'" (so it's not a NuGet version-resolution problem)
- `Microsoft.AspNetCore.Components.Web` 11.0.0-preview.4.26230.115 nuspec: deps are `Components, Components.Forms, JSInterop, DependencyInjection` only. No `WebUtilities` (same for Preview 5).
- `Microsoft.AspNetCore.Components.Web.dll` assembly references (P4): no `WebUtilities`.
- Same shape verified on Preview 5 packages — same bug surface.

## Reproduction

1. `net11.0-ios` MAUI + Blazor Hybrid app.
2. `.razor` page calls `@using Microsoft.AspNetCore.WebUtilities` and `QueryHelpers.AddQueryString("/foo", new Dictionary { ... })` from an `@onclick` handler.
3. `dotnet build -f net11.0-ios -c Release -p:RuntimeIdentifier=ios-arm64`.
4. Sideload + tap → button does nothing. Device log shows `FileNotFoundException` for `Microsoft.AspNetCore.WebUtilities, Version=11.0.0.0`.

## Workaround

Add an explicit `PackageReference` to `Microsoft.AspNetCore.WebUtilities` at the matching v11 preview. This is what we shipped in [davidortinau/SentenceStudio@f6d94398](https://github.com/davidortinau/SentenceStudio/commit/f6d94398):

```xml

```

An explicit `PackageReference` roots the assembly for the trimmer.

## Suggested fixes (one of)

- Make `Components.Web` (or `Components.WebView`) reference `WebUtilities` so it's automatically rooted for Blazor Hybrid apps that use Razor helpers from it.
- Add a trimmer descriptor in the MAUI / Blazor Hybrid workload that keeps `Microsoft.AspNetCore.WebUtilities` when Razor compilation is enabled.
- Document the explicit-reference workaround in the .NET MAUI / Blazor Hybrid trimming guidance.

## Affected versions

Verified on both `Microsoft.AspNetCore.Components.Web` `11.0.0-preview.4.26230.115` and `11.0.0-preview.5.26302.115` (Preview 4 build of `Components.Web.dll`; Preview 5 nuspec shows the same dependency shape, so the bug should also reproduce on P5).

Why the original title says "P4": the SentenceStudio repo pins all `Components.*` packages to P4 in `Directory.Packages.props`, so that's the version we hit the bug on. The bug is **not** specific to P4 — it's structural.

---

Original (incorrect) issue body, for trail

## Summary

`Microsoft.AspNetCore.Components.Web` 11.0.0-preview.4.26230.115 carries a transitive **upper-bound** constraint on `Microsoft.AspNetCore.WebUtilities` of `(, 10.0.32767]`. In a Blazor Hybrid app targeting `net11.0-ios` (.NET MAUI) built in `Release` with the default iOS trimmer settings, this causes `WebUtilities.dll` to be removed from the app bundle, even though `QueryHelpers.AddQueryString` is called at runtime.

[... rest of original body ...]

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.