-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Json serialize when use custom nullable JsonConverter always thrown AccessViolationException #55135
Comments
Tagging subscribers to this area: @eiriktsarpalis, @layomia Issue DetailsDescriptionWhen use nullable JsonConverter to custom serialize double? and double, always thrown AccessViolationException. Configuration
Regression?Never normal Other information
|
I can reproduce the issue in both .NET 5 and 6. Transcribing the minimal repro: using System;
using System.Text.Json;
using System.Text.Json.Serialization;
JsonSerializer.Serialize(new NullableD(), new JsonSerializerOptions { Converters = { new NullableDouble() } });
public class NullableD
{
public double B { get; set; }
}
public class NullableDouble : JsonConverter<double?>
{
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(double);
public override double? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => 0;
public override void Write(Utf8JsonWriter writer, double? value, JsonSerializerOptions options) => writer.WriteNullValue();
} which throws
I believe the issue is caused by invalid IL emitted by the Reflection.Emit member accessor. The converter implementation is incorrect, however we should detecting this error earlier and fail gracefully with a helpful error message. |
Should this be an Lines 253 to 257 in 90b8ddd
|
I think that this check is intentional, apparently it is meant to support "covariant" and "contravariant" converters and will only fail if there is no subtype relationship between the two types. Here are some tests that validate this: Lines 46 to 57 in a8dacd5
I find that this mode is flawed since serialization is contravariant and deserialization is covariant, meaning that covariant serialization and contravariant deserialization will necessarily manifest as various kinds of runtime type errors. On top of that, much of the serialization infrastructure is built on the assumption that
and therefore any "contraviariant"/"covariant" converter will necessarily manifest as an Ultimately, that is the root cause for the reported issue: One was of addressing this issue as well as #46522 is to force converter invariance everywhere, namely changing the check in if (converter.TypeToConvert != typeToConvert)
{
ThrowHelper.ThrowInvalidOperationException_SerializationConverterNotCompatible(converter.GetType(), typeToConvert);
} This will ensure consistent behavior across the board (regardless of whether the converter is used as a root-level object or collection element) and any type mismatches will manifest as the same user-friendly error messages occurring early in the serialization process. Perhaps something to consider for .NET 7. @layomia @steveharter @ericstj thoughts? |
We should not be causing AccessViolation. Ideally we improve the error detection upfront. If that is not feasible, we could add some The converter model was not intended to be covariant - the JsonConverterFactory should be used to instantiate the correct converter. |
This could be moved to 7.0; I don't believe the semantics changed in 6.0. |
I already have a PR open that fixes this: #56577 |
Description
When use nullable JsonConverter to custom serialize double? and double, always thrown AccessViolationException.
Configuration
Regression?
Never normal
Other information
The text was updated successfully, but these errors were encountered: