JsonConvert
JsonSerializer
, , , . , , JSON.NET , , , , , - , JSON.NET , .
:
public readonly struct UserId
{
public static readonly UserId Empty = new UserId();
public UserId(int value)
{
Value = value;
HasValue = true;
}
public int Value { get; }
public bool HasValue { get; }
}
, int
. number
JSON int
→ UserId
. , :
public class MyStringConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(UserId);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
int? id = serializer.Deserialize<int?>(reader);
if (!id.HasValue)
{
return UserId.Empty;
}
return new UserId(id.Value);
}
}
WriteJson
, .
:
[Fact]
public void UserIdJsonConverter_CanConvertFromJsonNumber()
{
var serialiser = new JsonSerializer();
var reader = CreateJsonReader("10");
var converter = new UserId.UserIdJsonConverter();
var result = converter.ReadJson(reader, typeof(UserId), null, serialiser);
Assert.NotNull(result);
Assert.IsType<UserId>(result);
var id = (UserId)result;
Assert.True(id.HasValue);
Assert.Equal(10, id.Value);
}
private JsonTextReader CreateJsonReader(string json)
=> new JsonTextReader(new StringReader(json));
ReadJson
, , . , JsonReader
, JsonReader
JsonSerializer
, .
The problem with using JsonConvert
or JsonSerializer
to start the full deserialization process is that you introduce other logic that is largely outside your control. That is, if during deserialization, JSON.NET actually makes a different decision and your custom converter is never used, your test is not responsible for testing JSON.NET itself, but for what your custom converter actually does.