Skip to content

Bad interaction between the linker and System.Text.Json #74141

@javiercn

Description

@javiercn

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

private 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 type

private 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 stack

crit: 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()

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Text.JsonquestionAnswer questions and provide assistance, not an issue with source code or documentation.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions