You can apply a custom JsonConverter<T>
similar to the one shown in the documentation to AttributeValue
to deserialize to an Int32
or a string
depending on the incoming JSON value:
public class a
{
[JsonConverter(typeof(ObjectPrimitiveConverter))]
public object AttributeValue {get; set;}
}
public class ObjectPrimitiveConverter : JsonConverter<object>
{
public override object Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options) =>
reader.TokenType switch
{
JsonTokenType.String => reader.GetString(),
JsonTokenType.Number when reader.TryGetInt32(out var i) => i,
//Add other cases as needed:
//JsonTokenType.Number when reader.TryGetInt64(out var l) => l,
//JsonTokenType.Number when reader.TryGetDouble(out var d) => d,
//JsonTokenType.True => true,
//JsonTokenType.False => false,
_ => throw new JsonException(), // StartObject, StartArray, Null
};
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, value, value.GetType() /*, options */); // Passing options when ObjectPrimitiveConverter has been added to options.Converters will cause a stack overflow
}
Notes:
- While the JSON standard does distinguish between strings and numbers, it does not distinguish between integers and decimals that happen to have integer values. Thus if your
AttributeValue
might contain an integer of value 1
or a double of value 1D
, System.Text.Json will serialize both as 1
and, when read back in, you will not be able to distinguish the type.
Demo fiddle here.