-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bad interaction between the linker and System.Text.Json #74141
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsThere seems to be an awkward interaction between records and the Linker, I am not sure, but I believe the linker might be stripping some metadata that System.Text.Json might need. When I declare the record as If I look at the two types (unlinked and linked) in ILSpy, I get the following: (Note the parameter names on the constructor) Unlinked typeprivate class JavaScriptLoggingOptions : IEquatable<JavaScriptLoggingOptions>
{
[CompilerGenerated]
protected virtual Type EqualityContract
{
[CompilerGenerated]
get
{
return typeof(JavaScriptLoggingOptions);
}
}
public bool DebugEnabled { get; set/*init*/; }
public bool TraceEnabled { get; set/*init*/; }
public JavaScriptLoggingOptions(bool DebugEnabled, bool TraceEnabled)
{
this.DebugEnabled = DebugEnabled;
this.TraceEnabled = TraceEnabled;
base..ctor();
}
[CompilerGenerated]
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("JavaScriptLoggingOptions");
stringBuilder.Append(" { ");
if (PrintMembers(stringBuilder))
{
stringBuilder.Append(' ');
}
stringBuilder.Append('}');
return stringBuilder.ToString();
}
[CompilerGenerated]
protected virtual bool PrintMembers(StringBuilder builder)
{
RuntimeHelpers.EnsureSufficientExecutionStack();
builder.Append("DebugEnabled = ");
builder.Append(DebugEnabled.ToString());
builder.Append(", TraceEnabled = ");
builder.Append(TraceEnabled.ToString());
return true;
}
[CompilerGenerated]
public static bool operator !=(JavaScriptLoggingOptions left, JavaScriptLoggingOptions right)
{
return !(left == right);
}
[CompilerGenerated]
public static bool operator ==(JavaScriptLoggingOptions left, JavaScriptLoggingOptions right)
{
if ((object)left != right)
{
return left?.Equals(right) ?? false;
}
return true;
}
[CompilerGenerated]
public override int GetHashCode()
{
return (EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(DebugEnabled)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(TraceEnabled);
}
[CompilerGenerated]
public override bool Equals(object obj)
{
return Equals(obj as JavaScriptLoggingOptions);
}
[CompilerGenerated]
public virtual bool Equals(JavaScriptLoggingOptions other)
{
if ((object)this != other)
{
if ((object)other != null && EqualityContract == other.EqualityContract && EqualityComparer<bool>.Default.Equals(DebugEnabled, other.DebugEnabled))
{
return EqualityComparer<bool>.Default.Equals(TraceEnabled, other.TraceEnabled);
}
return false;
}
return true;
}
[CompilerGenerated]
protected JavaScriptLoggingOptions(JavaScriptLoggingOptions original)
{
DebugEnabled = original.DebugEnabled;
TraceEnabled = original.TraceEnabled;
}
[CompilerGenerated]
public void Deconstruct(out bool DebugEnabled, out bool TraceEnabled)
{
DebugEnabled = this.DebugEnabled;
TraceEnabled = this.TraceEnabled;
}
} Linked out typeprivate class JavaScriptLoggingOptions : IEquatable<JavaScriptLoggingOptions>
{
[CompilerGenerated]
protected virtual Type EqualityContract
{
[CompilerGenerated]
get
{
return typeof(JavaScriptLoggingOptions);
}
}
public bool DebugEnabled { get; }
public bool TraceEnabled { get; }
public JavaScriptLoggingOptions(bool P_0, bool P_1)
{
DebugEnabled = P_0;
TraceEnabled = P_1;
base..ctor();
}
[CompilerGenerated]
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("JavaScriptLoggingOptions");
stringBuilder.Append(" { ");
if (PrintMembers(stringBuilder))
{
stringBuilder.Append(' ');
}
stringBuilder.Append('}');
return stringBuilder.ToString();
}
[CompilerGenerated]
protected virtual bool PrintMembers(StringBuilder P_0)
{
RuntimeHelpers.EnsureSufficientExecutionStack();
P_0.Append("DebugEnabled = ");
P_0.Append(DebugEnabled.ToString());
P_0.Append(", TraceEnabled = ");
P_0.Append(TraceEnabled.ToString());
return true;
}
[CompilerGenerated]
public static bool operator !=(JavaScriptLoggingOptions P_0, JavaScriptLoggingOptions P_1)
{
return !(P_0 == P_1);
}
[CompilerGenerated]
public static bool operator ==(JavaScriptLoggingOptions P_0, JavaScriptLoggingOptions P_1)
{
if ((object)P_0 != P_1)
{
return P_0?.Equals(P_1) ?? false;
}
return true;
}
[CompilerGenerated]
public override int GetHashCode()
{
return (EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(DebugEnabled)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(TraceEnabled);
}
[CompilerGenerated]
public override bool Equals(object P_0)
{
return Equals(P_0 as JavaScriptLoggingOptions);
}
[CompilerGenerated]
public virtual bool Equals(JavaScriptLoggingOptions P_0)
{
if ((object)this != P_0)
{
if ((object)P_0 != null && EqualityContract == P_0.EqualityContract && EqualityComparer<bool>.Default.Equals(DebugEnabled, P_0.DebugEnabled))
{
return EqualityComparer<bool>.Default.Equals(TraceEnabled, P_0.TraceEnabled);
}
return false;
}
return true;
} Call stackcrit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: ConstructorContainsNullParameterNames, Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3+JavaScriptLoggingOptions[Wasm.Authentication.Client.RemoteAppState,Wasm.Authentication.Client.OidcAccount,Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions] SerializationNotSupportedParentType, System.Object Path: $.
System.NotSupportedException: ConstructorContainsNullParameterNames, Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3+JavaScriptLoggingOptions[Wasm.Authentication.Client.RemoteAppState,Wasm.Authentication.Client.OidcAccount,Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions] SerializationNotSupportedParentType, System.Object Path: $.
---> System.NotSupportedException: ConstructorContainsNullParameterNames, Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3+JavaScriptLoggingOptions[Wasm.Authentication.Client.RemoteAppState,Wasm.Authentication.Client.OidcAccount,Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions]
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_ConstructorContainsNullParameterNames(Type )
at System.Text.Json.Serialization.Metadata.ReflectionJsonTypeInfo`1[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3.JavaScriptLoggingOptions[[Wasm.Authentication.Client.RemoteAppState, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Wasm.Authentication.Client.OidcAccount, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60]], Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60]].GetParameterInfoValues()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.<EnsureConfigured>g__ConfigureLocked|138_0()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.EnsureConfigured()
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type , Boolean , Boolean )
at System.Text.Json.WriteStackFrame.InitializePolymorphicReEntry(Type , JsonSerializerOptions )
at System.Text.Json.Serialization.JsonConverter.ResolvePolymorphicConverter(Object , JsonTypeInfo , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Object& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.Converters.ArrayConverter`2[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnWriteResume(Utf8JsonWriter , Object[] , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonCollectionConverter`2[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnTryWrite(Utf8JsonWriter , Object[] , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].WriteCore(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
Exception_EndOfInnerExceptionStack
at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& , NotSupportedException )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].WriteCore(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.JsonSerializer.WriteCore[Object[]](Utf8JsonWriter , Object[]& , JsonTypeInfo`1 )
at System.Text.Json.JsonSerializer.WriteString[Object[]](Object[]& , JsonTypeInfo`1 )
at System.Text.Json.JsonSerializer.Serialize[Object[]](Object[] , JsonSerializerOptions )
at Microsoft.JSInterop.JSRuntime.InvokeAsync[IJSVoidResult](Int64 , String , CancellationToken , Object[] )
at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[Microsoft.JSInterop.Infrastructure.IJSVoidResult, Microsoft.JSInterop, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime , String , Object[] )
at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3.<EnsureAuthService>d__29[[Wasm.Authentication.Client.RemoteAppState, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Wasm.Authentication.Client.OidcAccount, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3.<GetAuthenticatedUser>d__28[[Wasm.Authentication.Client.RemoteAppState, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Wasm.Authentication.Client.OidcAccount, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3.<GetUser>d__27[[Wasm.Authentication.Client.RemoteAppState, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Wasm.Authentication.Client.OidcAccount, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3.<GetAuthenticationStateAsync>d__19[[Wasm.Authentication.Client.RemoteAppState, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Wasm.Authentication.Client.OidcAccount, Wasm.Authentication.Client, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.ApiAuthorizationProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
at Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore.OnParametersSetAsync()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
|
This seems like deliberate behavior: can you try using source-gen APIs? [JsonSerializable(typeof(JavaScriptLoggingOptions))]
partial class MyContext : JsonSerializerContext {}
// JsonSerializer.Serialize(someObj, MyContext.Default.Options); If you want to try to make reflection APIs work, can you try following https://devblogs.microsoft.com/dotnet/customizing-trimming-in-net-core-5/ |
Unfortunately, the trim warnings are disabled by default for Blazor wasm apps. If you would like to be warned about all places that are problematic with trimming in your app, you can enable the warnings by specifying The source generators are the only reliable option with trimming. |
This is by-design behavior, related to #58690. |
There seems to be an awkward interaction between records and the Linker, I am not sure, but I believe the linker might be stripping some metadata that System.Text.Json might need.
When I declare the record as
private record JavaScriptLoggingOptions(bool DebugEnabled, bool TraceEnabled);
and later on serialize it using an API that is linker friendly (it is "correctly annotated" to make sure type members are preserved) I get the error below:If I look at the two types (unlinked and linked) in ILSpy, I get the following: (Note the parameter names on the constructor)
Unlinked type
Linked out type
Call stack
The text was updated successfully, but these errors were encountered: