66using System ;
77using System . Diagnostics . CodeAnalysis ;
88using System . Text . Json ;
9+ using System . Text . Json . Serialization ;
10+ using System . Text . Json . Serialization . Metadata ;
911using Microsoft . AspNetCore . Components . RenderTree ;
10- using static Microsoft . AspNetCore . Internal . LinkerFlags ;
1112
1213namespace Microsoft . AspNetCore . Components . Web
1314{
1415 internal class WebEventData
1516 {
1617 // This class represents the second half of parsing incoming event data,
1718 // once the event ID (and possibly the type of the eventArgs) becomes known.
18- public static WebEventData Parse ( Renderer renderer , JsonSerializerOptions jsonSerializerOptions , string eventDescriptorJson , string eventArgsJson )
19+ public static WebEventData Parse (
20+ Renderer renderer ,
21+ WebEventJsonContext jsonSerializerContext ,
22+ string eventDescriptorJson ,
23+ string eventArgsJson )
1924 {
2025 WebEventDescriptor eventDescriptor ;
2126 try
2227 {
23- eventDescriptor = Deserialize < WebEventDescriptor > ( eventDescriptorJson ) ;
28+ eventDescriptor = Deserialize ( eventDescriptorJson , jsonSerializerContext . WebEventDescriptor ) ;
2429 }
2530 catch ( Exception e )
2631 {
@@ -29,14 +34,18 @@ public static WebEventData Parse(Renderer renderer, JsonSerializerOptions jsonSe
2934
3035 return Parse (
3136 renderer ,
32- jsonSerializerOptions ,
37+ jsonSerializerContext ,
3338 eventDescriptor ,
3439 eventArgsJson ) ;
3540 }
3641
37- public static WebEventData Parse ( Renderer renderer , JsonSerializerOptions jsonSerializerOptions , WebEventDescriptor eventDescriptor , string eventArgsJson )
42+ public static WebEventData Parse (
43+ Renderer renderer ,
44+ WebEventJsonContext jsonSerializerContext ,
45+ WebEventDescriptor eventDescriptor ,
46+ string eventArgsJson )
3847 {
39- var parsedEventArgs = ParseEventArgsJson ( renderer , jsonSerializerOptions , eventDescriptor . EventHandlerId , eventDescriptor . EventName , eventArgsJson ) ;
48+ var parsedEventArgs = ParseEventArgsJson ( renderer , jsonSerializerContext , eventDescriptor . EventHandlerId , eventDescriptor . EventName , eventArgsJson ) ;
4049 return new WebEventData (
4150 eventDescriptor . BrowserRendererId ,
4251 eventDescriptor . EventHandlerId ,
@@ -60,29 +69,35 @@ private WebEventData(int browserRendererId, ulong eventHandlerId, EventFieldInfo
6069
6170 public EventArgs EventArgs { get ; }
6271
63- private static EventArgs ParseEventArgsJson ( Renderer renderer , JsonSerializerOptions jsonSerializerOptions , ulong eventHandlerId , string eventName , string eventArgsJson )
72+ private static EventArgs ParseEventArgsJson (
73+ Renderer renderer ,
74+ WebEventJsonContext jsonSerializerContext ,
75+ ulong eventHandlerId ,
76+ string eventName ,
77+ string eventArgsJson )
6478 {
6579 try
6680 {
67- if ( TryDeserializeStandardWebEventArgs ( eventName , eventArgsJson , out var eventArgs ) )
81+ if ( TryDeserializeStandardWebEventArgs ( eventName , eventArgsJson , jsonSerializerContext , out var eventArgs ) )
6882 {
6983 return eventArgs ;
7084 }
7185
7286 // For custom events, the args type is determined from the associated delegate
7387 var eventArgsType = renderer . GetEventArgsType ( eventHandlerId ) ;
74- return ( EventArgs ) JsonSerializer . Deserialize ( eventArgsJson , eventArgsType , jsonSerializerOptions ) ! ;
88+ return ( EventArgs ) JsonSerializer . Deserialize ( eventArgsJson , eventArgsType , jsonSerializerContext . Options ) ! ;
7589 }
7690 catch ( Exception e )
7791 {
7892 throw new InvalidOperationException ( $ "There was an error parsing the event arguments. EventId: '{ eventHandlerId } '.", e ) ;
7993 }
8094 }
8195
82- [ DynamicDependency ( JsonSerialized , typeof ( DataTransfer ) ) ]
83- [ DynamicDependency ( JsonSerialized , typeof ( DataTransferItem ) ) ]
84- [ DynamicDependency ( JsonSerialized , typeof ( TouchPoint ) ) ]
85- private static bool TryDeserializeStandardWebEventArgs ( string eventName , string eventArgsJson , [ NotNullWhen ( true ) ] out EventArgs ? eventArgs )
96+ private static bool TryDeserializeStandardWebEventArgs (
97+ string eventName ,
98+ string eventArgsJson ,
99+ WebEventJsonContext jsonSerializerContext ,
100+ [ NotNullWhen ( true ) ] out EventArgs ? eventArgs )
86101 {
87102 // For back-compatibility, we recognize the built-in list of web event names and hard-code
88103 // rules about the deserialization type for their eventargs. This makes it possible to declare
@@ -97,13 +112,13 @@ private static bool TryDeserializeStandardWebEventArgs(string eventName, string
97112 case "change" :
98113 // Special case for ChangeEventArgs because its value type can be one of
99114 // several types, and System.Text.Json doesn't pick types dynamically
100- eventArgs = DeserializeChangeEventArgs ( eventArgsJson ) ;
115+ eventArgs = DeserializeChangeEventArgs ( eventArgsJson , jsonSerializerContext ) ;
101116 return true ;
102117
103118 case "copy" :
104119 case "cut" :
105120 case "paste" :
106- eventArgs = Deserialize < ClipboardEventArgs > ( eventArgsJson ) ;
121+ eventArgs = Deserialize < ClipboardEventArgs > ( eventArgsJson , jsonSerializerContext . ClipboardEventArgs ) ;
107122 return true ;
108123
109124 case "drag" :
@@ -113,20 +128,20 @@ private static bool TryDeserializeStandardWebEventArgs(string eventName, string
113128 case "dragover" :
114129 case "dragstart" :
115130 case "drop" :
116- eventArgs = Deserialize < DragEventArgs > ( eventArgsJson ) ;
131+ eventArgs = Deserialize < DragEventArgs > ( eventArgsJson , jsonSerializerContext . DragEventArgs ) ;
117132 return true ;
118133
119134 case "focus" :
120135 case "blur" :
121136 case "focusin" :
122137 case "focusout" :
123- eventArgs = Deserialize < FocusEventArgs > ( eventArgsJson ) ;
138+ eventArgs = Deserialize < FocusEventArgs > ( eventArgsJson , jsonSerializerContext . FocusEventArgs ) ;
124139 return true ;
125140
126141 case "keydown" :
127142 case "keyup" :
128143 case "keypress" :
129- eventArgs = Deserialize < KeyboardEventArgs > ( eventArgsJson ) ;
144+ eventArgs = Deserialize < KeyboardEventArgs > ( eventArgsJson , jsonSerializerContext . KeyboardEventArgs ) ;
130145 return true ;
131146
132147 case "contextmenu" :
@@ -137,11 +152,11 @@ private static bool TryDeserializeStandardWebEventArgs(string eventName, string
137152 case "mousedown" :
138153 case "mouseup" :
139154 case "dblclick" :
140- eventArgs = Deserialize < MouseEventArgs > ( eventArgsJson ) ;
155+ eventArgs = Deserialize < MouseEventArgs > ( eventArgsJson , jsonSerializerContext . MouseEventArgs ) ;
141156 return true ;
142157
143158 case "error" :
144- eventArgs = Deserialize < ErrorEventArgs > ( eventArgsJson ) ;
159+ eventArgs = Deserialize < ErrorEventArgs > ( eventArgsJson , jsonSerializerContext . ErrorEventArgs ) ;
145160 return true ;
146161
147162 case "loadstart" :
@@ -150,7 +165,7 @@ private static bool TryDeserializeStandardWebEventArgs(string eventName, string
150165 case "load" :
151166 case "loadend" :
152167 case "progress" :
153- eventArgs = Deserialize < ProgressEventArgs > ( eventArgsJson ) ;
168+ eventArgs = Deserialize < ProgressEventArgs > ( eventArgsJson , jsonSerializerContext . ProgressEventArgs ) ;
154169 return true ;
155170
156171 case "touchcancel" :
@@ -159,7 +174,7 @@ private static bool TryDeserializeStandardWebEventArgs(string eventName, string
159174 case "touchenter" :
160175 case "touchleave" :
161176 case "touchstart" :
162- eventArgs = Deserialize < TouchEventArgs > ( eventArgsJson ) ;
177+ eventArgs = Deserialize < TouchEventArgs > ( eventArgsJson , jsonSerializerContext . TouchEventArgs ) ;
163178 return true ;
164179
165180 case "gotpointercapture" :
@@ -172,16 +187,16 @@ private static bool TryDeserializeStandardWebEventArgs(string eventName, string
172187 case "pointerout" :
173188 case "pointerover" :
174189 case "pointerup" :
175- eventArgs = Deserialize < PointerEventArgs > ( eventArgsJson ) ;
190+ eventArgs = Deserialize < PointerEventArgs > ( eventArgsJson , jsonSerializerContext . PointerEventArgs ) ;
176191 return true ;
177192
178193 case "wheel" :
179194 case "mousewheel" :
180- eventArgs = Deserialize < WheelEventArgs > ( eventArgsJson ) ;
195+ eventArgs = Deserialize < WheelEventArgs > ( eventArgsJson , jsonSerializerContext . WheelEventArgs ) ;
181196 return true ;
182197
183198 case "toggle" :
184- eventArgs = Deserialize < EventArgs > ( eventArgsJson ) ;
199+ eventArgs = Deserialize < EventArgs > ( eventArgsJson , jsonSerializerContext . EventArgs ) ;
185200 return true ;
186201
187202 default :
@@ -219,13 +234,11 @@ private static bool TryDeserializeStandardWebEventArgs(string eventName, string
219234 return null ;
220235 }
221236
222- [ UnconditionalSuppressMessage ( "ReflectionAnalysis" , "IL2026:RequiresUnreferencedCode" , Justification = "The correct members are preserved by DynamicDependencies." ) ]
223- // This should use JSON source generation
224- static T Deserialize < [ DynamicallyAccessedMembers ( JsonSerialized ) ] T > ( string json ) => JsonSerializer . Deserialize < T > ( json , JsonSerializerOptionsProvider . Options ) ! ;
237+ static T Deserialize < T > ( string json , JsonTypeInfo < T ? > jsonTypeInfo ) => JsonSerializer . Deserialize ( json , jsonTypeInfo ) ! ;
225238
226- private static ChangeEventArgs DeserializeChangeEventArgs ( string eventArgsJson )
239+ private static ChangeEventArgs DeserializeChangeEventArgs ( string eventArgsJson , WebEventJsonContext jsonSerializerContext )
227240 {
228- var changeArgs = Deserialize < ChangeEventArgs > ( eventArgsJson ) ;
241+ var changeArgs = Deserialize ( eventArgsJson , jsonSerializerContext . ChangeEventArgs ) ;
229242 var jsonElement = ( JsonElement ) changeArgs . Value ! ;
230243 switch ( jsonElement . ValueKind )
231244 {
@@ -245,4 +258,22 @@ private static ChangeEventArgs DeserializeChangeEventArgs(string eventArgsJson)
245258 return changeArgs ;
246259 }
247260 }
261+
262+ [ JsonSerializable ( typeof ( WebEventDescriptor ) ) ]
263+ [ JsonSerializable ( typeof ( WebEventDescriptor ) ) ]
264+ [ JsonSerializable ( typeof ( EventArgs ) ) ]
265+ [ JsonSerializable ( typeof ( ChangeEventArgs ) ) ]
266+ [ JsonSerializable ( typeof ( ClipboardEventArgs ) ) ]
267+ [ JsonSerializable ( typeof ( DragEventArgs ) ) ]
268+ [ JsonSerializable ( typeof ( ErrorEventArgs ) ) ]
269+ [ JsonSerializable ( typeof ( FocusEventArgs ) ) ]
270+ [ JsonSerializable ( typeof ( KeyboardEventArgs ) ) ]
271+ [ JsonSerializable ( typeof ( MouseEventArgs ) ) ]
272+ [ JsonSerializable ( typeof ( PointerEventArgs ) ) ]
273+ [ JsonSerializable ( typeof ( ProgressEventArgs ) ) ]
274+ [ JsonSerializable ( typeof ( TouchEventArgs ) ) ]
275+ [ JsonSerializable ( typeof ( WheelEventArgs ) ) ]
276+ internal sealed partial class WebEventJsonContext : JsonSerializerContext
277+ {
278+ }
248279}
0 commit comments