[Blazor Hybrid / iOS Release] Microsoft.AspNetCore.WebUtilities trimmed out when QueryHelpers is called only from .razor
- 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
Assessment
This issue has not been assessed yet.