代码之家  ›  专栏  ›  技术社区  ›  asgerhallas

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

  •  0
  • asgerhallas  · 技术社区  · 7 年前

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

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

    是否有办法更改此行为,使其反序列化为实际请求的类型?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Brian Rogers    7 年前

    这里有一个退化的测试用例。如果您指示Json.Net反序列化为 object ,您告诉它JSON可以表示任何可能的对象。所以它会选择使用 JObject 在这种情况下,因为你没有具体的 可以处理任何JSON对象。您不希望反序列化为文本空 对象 例如,因为这不是一件非常有用的事情。如果JSON包含任何数据,则在反序列化之后您将无法访问该数据: 没有属性!

    Foo 用它来代替 对象

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

    如果您确实需要强制Json.Net反序列化为空 无论何时 对象 指定为类型,您可以使用自定义 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