22// The .NET Foundation licenses this file to you under the MIT license.
33
44using System . Diagnostics . CodeAnalysis ;
5- using System . Globalization ;
65using System . Text . Json ;
76using System . Text . Json . Serialization ;
8- using System . Text . Json . Serialization . Metadata ;
97using Microsoft . AspNetCore . Components . Web ;
108using Microsoft . AspNetCore . Components . Web . Infrastructure ;
119using Microsoft . AspNetCore . Components . Web . Internal ;
@@ -102,10 +100,19 @@ protected override void Dispose(bool disposing)
102100 base . Dispose ( disposing ) ;
103101 }
104102
103+ [ UnconditionalSuppressMessage ( "Trimming" , "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code" , Justification = "<Pending>" ) ]
105104 private void AttachWebRendererInterop ( IJSRuntime jsRuntime , JsonSerializerOptions jsonOptions , JSComponentInterop jsComponentInterop )
106105 {
107106 const string JSMethodIdentifier = "Blazor._internal.attachWebRendererInterop" ;
108107
108+ // These arguments should be kept in sync with WebRendererSerializerContext
109+ object [ ] args = [
110+ _rendererId ,
111+ _interopMethodsReference ,
112+ jsComponentInterop . Configuration . JSComponentParametersByIdentifier ,
113+ jsComponentInterop . Configuration . JSComponentIdentifiersByInitializer ,
114+ ] ;
115+
109116 if ( jsRuntime is IInternalWebJSInProcessRuntime inProcessRuntime )
110117 {
111118 // Fast path for WebAssembly: Rather than using the JSRuntime to serialize
@@ -117,59 +124,18 @@ private void AttachWebRendererInterop(IJSRuntime jsRuntime, JsonSerializerOption
117124 // a supported type in the JsonSerializerContext generates unnecessary code to produce
118125 // JsonTypeInfo for all the types referenced by both DotNetObjectReference<T> and its
119126 // generic type argument.
120- var interopMethodsReferenceJsonTypeInfo = GetJsonTypeInfoFromJsonConverterFactories < DotNetObjectReference < WebRendererInteropMethods > > (
121- jsonOptions . Converters ,
122- WebRendererSerializerContext . Default . Options ) ;
123-
124- var rendererIdJson = _rendererId . ToString ( CultureInfo . InvariantCulture ) ;
125- var interopMethodsReferenceJson = JsonSerializer . Serialize (
126- _interopMethodsReference ,
127- interopMethodsReferenceJsonTypeInfo ) ;
128- var jsComponentParametersByIdentifierJson = JsonSerializer . Serialize (
129- jsComponentInterop . Configuration . JSComponentParametersByIdentifier ,
130- WebRendererSerializerContext . Default . DictionaryStringJSComponentParameterArray ) ;
131- var jsComponentIdentifiersByInitializerJson = JsonSerializer . Serialize (
132- jsComponentInterop . Configuration . JSComponentIdentifiersByInitializer ,
133- WebRendererSerializerContext . Default . DictionaryStringListString ) ;
134-
135- var argsJson =
136- $ "[{ rendererIdJson } , " +
137- $ "{ interopMethodsReferenceJson } , " +
138- $ "{ jsComponentParametersByIdentifierJson } , " +
139- $ "{ jsComponentIdentifiersByInitializerJson } ]";
127+
128+ var newJsonOptions = new JsonSerializerOptions ( jsonOptions ) ;
129+ newJsonOptions . TypeInfoResolverChain . Clear ( ) ;
130+ newJsonOptions . TypeInfoResolverChain . Add ( WebRendererSerializerContext . Default ) ;
131+ newJsonOptions . TypeInfoResolverChain . Add ( JsonConverterFactoryTypeInfoResolver < DotNetObjectReference < WebRendererInteropMethods > > . Instance ) ;
132+ var argsJson = JsonSerializer . Serialize ( args , newJsonOptions ) ;
140133 inProcessRuntime . InvokeJS ( JSMethodIdentifier , argsJson , JSCallResultType . JSVoidResult , 0 ) ;
141134 }
142135 else
143136 {
144- jsRuntime . InvokeVoidAsync (
145- JSMethodIdentifier ,
146- _rendererId ,
147- _interopMethodsReference ,
148- jsComponentInterop . Configuration . JSComponentParametersByIdentifier ,
149- jsComponentInterop . Configuration . JSComponentIdentifiersByInitializer ) . Preserve ( ) ;
150- }
151- }
152-
153- private static JsonTypeInfo < T > GetJsonTypeInfoFromJsonConverterFactories < T > (
154- IList < JsonConverter > converters ,
155- JsonSerializerOptions optionsToUse )
156- {
157- foreach ( var converter in converters )
158- {
159- if ( converter is not JsonConverterFactory factory || ! factory . CanConvert ( typeof ( T ) ) )
160- {
161- continue ;
162- }
163-
164- if ( factory . CreateConverter ( typeof ( T ) , optionsToUse ) is not { } converterToUse )
165- {
166- continue ;
167- }
168-
169- return JsonMetadataServices . CreateValueInfo < T > ( optionsToUse , converterToUse ) ;
137+ jsRuntime . InvokeVoidAsync ( JSMethodIdentifier , args ) . Preserve ( ) ;
170138 }
171-
172- throw new InvalidOperationException ( $ "Could not create a JsonTypeInfo for type { typeof ( T ) . FullName } ") ;
173139 }
174140
175141 /// <summary>
@@ -215,10 +181,10 @@ public void RemoveRootComponent(int componentId)
215181 }
216182}
217183
218- [ JsonSourceGenerationOptions (
219- GenerationMode = JsonSourceGenerationMode . Serialization ,
220- PropertyNamingPolicy = JsonKnownNamingPolicy . CamelCase ,
221- PropertyNameCaseInsensitive = true ) ]
184+ // This should be kept in sync with the argument types in the call to
185+ // 'Blazor._internal.attachWebRendererInterop'
186+ [ JsonSerializable ( typeof ( object [ ] ) ) ]
187+ [ JsonSerializable ( typeof ( int ) ) ]
222188[ JsonSerializable ( typeof ( Dictionary < string , JSComponentConfigurationStore . JSComponentParameter [ ] > ) ) ]
223189[ JsonSerializable ( typeof ( Dictionary < string , List < string > > ) ) ]
224190internal sealed partial class WebRendererSerializerContext : JsonSerializerContext ;
0 commit comments