Skip to content

Fix trim/AOT safety for custom event argument deserialization in Blazor - #68113

Open
NanthiniMahalingam wants to merge 4 commits into
dotnet:mainfrom
NanthiniMahalingam:fix-45851
Open

Fix trim/AOT safety for custom event argument deserialization in Blazor#68113
NanthiniMahalingam wants to merge 4 commits into
dotnet:mainfrom
NanthiniMahalingam:fix-45851

Conversation

@NanthiniMahalingam

@NanthiniMahalingam NanthiniMahalingam commented Jul 30, 2026

Copy link
Copy Markdown

Bug description

  • When a Blazor component uses a custom event (registered via [EventHandler]) whose event-args type is deserialized from JSON, the members of that type could be trimmed away in trimmed/AOT-published apps. The deserialization path in WebEventData relied on JsonSerializer.Deserialize(string, Type, options), which is annotated RequiresUnreferencedCode.
  • That warning was being hidden with an UnconditionalSuppressMessage rather than actually being made trim-safe, so custom event args could fail to deserialize at runtime after trimming.

Root cause

  • The custom event-args Type flows from [EventHandler(..., Type eventArgsType)] → Renderer.GetEventArgsType(...) → JSON deserialization, but the Type was not annotated with [DynamicallyAccessedMembers]. The trimmer therefore had no signal to preserve the JSON-required members.
  • WebEventData.ParseEventArgsJson used the reflection-based JsonSerializer.Deserialize overload (RequiresUnreferencedCode) and merely suppressed the IL2026 warning, masking the real trimming hole instead of closing it.

Description of code changes

  • Annotated the eventArgsType constructor parameters and the EventArgsType property on EventHandlerAttribute.cs with DynamicallyAccessedMembers(LinkerFlags.JsonSerialized), so the members needed for JSON (de)serialization are preserved through trimming.
  • Annotated the return value of EventArgsTypeCache.GetEventArgsType with [return: DynamicallyAccessedMembers(JsonSerialized)] and added a justified IL2073 suppression (the type originates from the annotated EventHandlerAttribute).
  • Annotated the return value of the public Renderer.GetEventArgsType(ulong) so the annotation propagates to callers.
  • In WebEventData.cs, switched to the trim-safe API: resolve JsonTypeInfo via jsonSerializerOptions.GetTypeInfo(eventArgsType) and deserialize with that, removing the now-unnecessary UnconditionalSuppressMessage suppression.

Fixes #45851

Output

Before changes

beforefix-45851.mp4

After changes

afterfix-45851.mp4

@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Jul 30, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Thanks for your PR, @NanthiniMahalingam. Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@NanthiniMahalingam
NanthiniMahalingam marked this pull request as ready for review August 4, 2026 11:24
@NanthiniMahalingam
NanthiniMahalingam requested a review from a team as a code owner August 4, 2026 11:24
Copilot AI review requested due to automatic review settings August 4, 2026 11:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a trimming/AOT reliability issue in Blazor’s custom browser-event argument deserialization by ensuring the event-args Type carries the correct linker annotations and by switching the deserialization path to the JsonTypeInfo-based API.

Changes:

  • Propagates DynamicallyAccessedMembers(JsonSerialized) through EventHandlerAttribute, Renderer.GetEventArgsType, and EventArgsTypeCache.GetEventArgsType so JSON-required members aren’t trimmed away.
  • Updates WebEventData.ParseEventArgsJson to deserialize via JsonSerializerOptions.GetTypeInfo(...) + JsonSerializer.Deserialize(..., JsonTypeInfo) and removes the previous IL2026 suppression.
  • Adds coverage: a focused unit test for the custom-event deserialization path and an E2E regression test validating behavior in trimmed WASM publishes.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Components/Web/test/WebEventData/WebEventDataTest.cs Adds unit tests for custom event-args deserialization behavior (typed handler vs parameterless).
src/Components/Web/src/WebEventData/WebEventData.cs Removes the IL2026 suppression and switches to JsonTypeInfo-based deserialization for trim safety.
src/Components/test/E2ETest/Tests/WebAssemblyTrimmingTest.cs Adds a trimmed-WASM regression test for custom event args surviving trimming.
src/Components/Components/src/RenderTree/Renderer.cs Annotates GetEventArgsType return value to propagate linker requirements to callers.
src/Components/Components/src/RenderTree/EventArgsTypeCache.cs Annotates return value and adds an IL2073 suppression for the reflection-derived parameter type.
src/Components/Components/src/EventHandlerAttribute.cs Annotates eventArgsType parameters and EventArgsType property with DynamicallyAccessedMembers(JsonSerialized).

Comment thread src/Components/Components/src/RenderTree/EventArgsTypeCache.cs Outdated
Comment thread src/Components/Web/src/WebEventData/WebEventData.cs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WebEventData.ParseEventArgsJson has invalid UnconditionalSuppressMessage for JsonSerializer.Deserialize

2 participants