-
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
System.Text.Json should allow any JSON type to be able to deserialzie to string
type.
#106245
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis |
For special cases like these use a JsonConverter. Something like this example converter, which reads any kind of json value as a string, except the json class ReadAsStringConverter : JsonConverter<string>
{
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> JsonElement.ParseValue(ref reader).ToString();
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
=> _defaultConverter.Write(writer, value, options);
private static readonly JsonConverter<string> _defaultConverter = (JsonConverter<string>) JsonSerializerOptions.Default.GetConverter(typeof(string));
} (Side note: Using the default converter like demonstrated here currently doesn't work with collection converters, until issue #50205 is resolved.) |
Or if you prefer to avoid the intermediate class ReadAsStringConverter : JsonConverter<string>
{
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.TokenType switch
{
JsonTokenType.Null => null,
JsonTokenType.String => reader.GetString(),
JsonTokenType.False => "false",
JsonTokenType.True => "true",
JsonTokenType.Number =>
reader.TryGetDouble(out double number)
? number.ToString()
: JsonElement.ParseValue(ref reader).ToString(),
_ => throw new JsonException(),
};
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
}
else
{
writer.WriteStringValue(value);
}
}
} |
That's giving inaccurate/incorrect results because of converting the json number into an inherent imprecise binary floating point type. As a result, large integers with very large absolute values (including such that would be otherwise readable as The conversion can be made in a way to preserve the the original json number accurately (i guess): ...
JsonTokenType.Number =>
Encoding.UTF8.GetString(reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan),
... |
user case
json from a API
the mode class
current System.Text.Json doesn't allow this deserialzation, and it throw on "jsonb" ,
to deserialze this , the model should change the type from
string
to "JsonNode/JsonElement" . but the "JsonNode/JsonElement" is for dynamic complex type, and for this json model , the best type for the property isstring
, which means the number version json is wrong (may be because the api is using a dynamic type language like javascript)suggestion
refence
The text was updated successfully, but these errors were encountered: