I have different backends giving back almost the same JSON data model except for a nested json object with the id
field which sometimes can be a pure number such as:
{ "something": { "id": 1 } }
or a string, such as:
{ "something": { "id": "ex.GUID" } }
plus the model is made of nullables, different System
types and custom classes. And I would like those json numbers 1
to be set as"1"
always(so the C# class model has the this property as public string Id { get; set; }
), possibly for that precise property.
Is there any JsonConverter<T>
or property [Attribute]
that could handle carefully such parsing/deserialization?
ps: the current JsonConverter<object>
answers don't seem to handle well(exceptions) such scenario as described above
CodePudding user response:
I don't think you need to do anything special, just deserialize to your model. Integer will be converted to strings.
void Main()
{
JsonConvert.DeserializeObject("{ \"something\": { \"id\": 1 } }", typeof(Test)).Dump();
JsonConvert.DeserializeObject("{ \"something\": { \"id\": \"1\" } }", typeof(Test)).Dump();
}
public class Test
{
public Something Something { get; set; }
}
public class Something
{
public string Id { get; set; }
}
CodePudding user response:
You have to use a custom JsonConverter<T>
for that.
/// taken from https://www.thecodebuzz.com/system-text-json-create-a-stringconverter-json-serialization/
public class StringConverter : System.Text.Json.Serialization.JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Number)
{
var stringValue = reader.GetInt32();
return stringValue.ToString();
}
else if (reader.TokenType == JsonTokenType.String)
{
return reader.GetString();
}
throw new System.Text.Json.JsonException();
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value);
}
}
and register that in the JsonSerializerOptions
var options = new JsonSerializerOptions
{
Converters = { new StringConverter() },
PropertyNameCaseInsensitive = true,
};
var jsonA = "{ \"something\": { \"id\": \"ex.GUID\" } }";
var a = JsonSerializer.Deserialize<RootObject>(jsonA, options);
var jsonB = "{ \"something\": { \"id\": 1 } }";
var b = JsonSerializer.Deserialize<RootObject>(jsonB, options);
complete example in this fiddle