Fix trim/AOT safety for custom event argument deserialization in Blazor - #68113
Fix trim/AOT safety for custom event argument deserialization in Blazor#68113NanthiniMahalingam wants to merge 4 commits into
Conversation
|
Thanks for your PR, @NanthiniMahalingam. Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
There was a problem hiding this comment.
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)throughEventHandlerAttribute,Renderer.GetEventArgsType, andEventArgsTypeCache.GetEventArgsTypeso JSON-required members aren’t trimmed away. - Updates
WebEventData.ParseEventArgsJsonto deserialize viaJsonSerializerOptions.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). |
1346f66 to
c1508a8
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/Components/test/E2ETest/Tests/WebAssemblyTrimmingTest.cs:94
- The test name/comments indicate this is specifically validating behavior in a trimmed/published app, but it currently runs unconditionally (unlike the other trimming tests in this class). This can give a false sense of trimming coverage when
TestTrimmedAppsis false, and it also makes the assertion less strict by usingLastOrDefault()instead of asserting a single log entry.
[Fact]
public void CustomEventArgsAreDeserialized_WhenPublishedWithTrimming()
{
// Regression test for https://github.com/microsoft/fast-blazor/issues/280, where custom
// event args types were trimmed away in assemblies marked IsTrimmable=true, causing
// deserialization to fail at runtime. The members required to deserialize a custom event
// args type are preserved through the [EventHandler] attribute's DynamicallyAccessedMembers
// annotation. This test runs against the trimmed BasicTestApp so it validates that the
// custom event args type (and the members needed to JSON-deserialize it) survive trimming.
var appElement = Browser.MountTestComponent<EventCustomArgsComponent>();
appElement.FindElement(By.Id("register-testevent-with-createventargs-that-supplies-args")).Click();
appElement.FindElement(By.Id("trigger-testevent-directly")).Click();
// If the custom event args type had been trimmed, deserialization would fail and MyProp
// would never be populated. Observing the value confirms the members were preserved.
Browser.Equal(
"Received testevent with args '{ MyProp=Native event target ID=test-event-target-child }'",
() => GetLogLines(appElement).LastOrDefault());
}
|
Thanks, I consider it being risky for .NET 11. Can we push it for .NET 12? |
|
NanthiniMahalingam Let's move it to the backlog and revisit it after .NET 11 GA. |
|
We should track milestone only in the linked issue, not in the PR. |
Bug description
Root cause
Description of code changes
Fixes #45851
Output
Before changes
beforefix-45851.mp4
After changes
afterfix-45851.mp4