如何使用json.net反序列化对象(而不是JObject)

时间:2018-11-16 15:00:14

标签: c# json.net

默认情况下,使用json.net测试失败:

JsonConvert.DeserializeObject(
    JsonConvert.SerializeObject(new object()), typeof(object)
).ShouldBeOfType<object>(); // actual type is JObject

是否可以更改此行为,以便将其反序列化为实际的请求类型?

1 个答案:

答案 0 :(得分:1)

您那里有一个退化的测试用例。如果您指示Json.Net反序列化为类型object,则说明JSON可以表示任何可能的对象。因此,在这种情况下,它将选择使用JObject,因为您不是特定的,并且JObject可以处理任何JSON对象。并不期望您要反序列化为一个空的object实例,因为这样做并不是一件非常有用的事情。如果JSON完全包含任何数据,则在反序列化之后您将无法访问该数据:object没有属性!

您可以通过创建一个空的类Foo并使用它代替object来修正测试:

JsonConvert.DeserializeObject(
    JsonConvert.SerializeObject(new Foo()), typeof(Foo)
).ShouldBeOfType<Foo>();

如果确实需要强制Json.Net在将object指定为类型时将其反序列化为空的object实例,则可以使用这样的自定义JsonConverter来做到这一点:

public class EmptyObjectConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(object);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);  // consume the JSON object from the reader 
        return token.Type == JTokenType.Null ? null : new object();
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后将转换器的实例传递给JsonConvert.DeserializeObject()

JsonConvert.DeserializeObject(
    JsonConvert.SerializeObject(new object()), 
    typeof(object),
    new EmptyObjectConverter()
).ShouldBeOfType<object>();

提琴:https://dotnetfiddle.net/7xZ7tm