使用JsonConverter的Json.NET自定义序列化-如何获取“默认"序列行为 [英] Json.NET custom serialization with JsonConverter - how to get the "default" behavior

查看:155
本文介绍了使用JsonConverter的Json.NET自定义序列化-如何获取“默认"序列行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的类DataType有一个JsonConverter. 当在Json中将纯字符串用作DataType类型的属性的值时,我想做一些特殊的处理.在值是完整"对象的情况下,我想进行常规"反序列化.

I have a JsonConverter for my class DataType. I would like to do some special handling when plain string used in Json as the value of a property of type DataType. In the case where the value is a "full" object, I would like to do the "normal" deserialization.

这是我的尝试

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.Value != null && reader.ValueType == typeof (string))
    {
        return someSpecialDataTypeInstance;
    }
    else if (reader.TokenType == JsonToken.StartObject)
    {
        DataType dataType = serializer.Deserialize<DataType>(reader);
        return dataType;
    }
    else
    {
        throw new JsonSerializationException();
    }
}

但是这行不通,因为这一行: DataType dataType = serializer.Deserialize(reader); 导致无限递归.

But this doesn't work, because this line: DataType dataType = serializer.Deserialize(reader); causes infinite recursion.

这可以很容易地做到吗? (无需手动逐属性)

Could this be done somehow easily? (without the need to manually go property-by-property)

推荐答案

一种简单的方法是分配您的类的实例,然后使用

One easy way to do it is to allocate an instance of your class then use JsonSerializer.Populate(JsonReader, Object). This is the way it is done in the standard CustomCreationConverter<T>:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.Value != null && reader.ValueType == typeof(string))
    {
        return someSpecialDataTypeInstance;
    }
    else if (reader.TokenType == JsonToken.StartObject)
    {
        existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
        serializer.Populate(reader, existingValue);
        return existingValue;
    }
    else if (reader.TokenType == JsonToken.Null)
    {
        return null;
    }
    else
    {
        throw new JsonSerializationException();
    }
}

限制:

  • This does not handle situations when TypeNameHandling has been enabled and a "$type" property is present specifying a polymorphic subtype.

在这种情况下,您需要在 带有接口的JsonConverter中做JsonDerivedTypeConverer<T>使用的一些技巧. a> .

In this case you'll need to do some of the tricks use by JsonDerivedTypeConverer<T> in JsonConverter with Interface.

要反序列化的类型必须具有无参数构造函数 Json.NET可以访问.如果不是,并且existingValue为空,则必须通过new DataType(arg1, arg2, ...)手动构造它.

The type to be deserialized must have a parameterless constructor accessible to Json.NET. If not, and existingValue is null, it will be necessary to construct it manually, via new DataType(arg1, arg2, ...).

通过

Reference preservation via PreserveReferencesHandling is not supported.

有关处理这种情况的一种方法,请参见 如何根据运行时结构来选择要在运行时反序列化的类型json? .

For one approach to handle this situation see How can I choose what type to deserialize at runtime based on the structure of the json?.

示例小提琴.

这篇关于使用JsonConverter的Json.NET自定义序列化-如何获取“默认"序列行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆