某些类别的自定义反序列化?

时间:2019-02-23 18:36:32

标签: c# json serialization

我正在一个项目中,该项目在JSON中具有一些非常复杂的配置文件。这样的一个例子(只是一个较大的齿轮中的属性)

"Visuals": {
  "UseAnimation": [
    {
      "Name": "idle",
      "RunConditions": {
        "cur_processed_inv": "IsZero"
      }
    },
    {
      "Name": "running",
      "RunConditions": {
        "cur_processed_inv": "IsGreaterThanZero"
      }
    }
  ]
}

该项目已决定使用Newtonsoft.Json进行转换。当前的结构方式是一系列类。在这种情况下,VisualsUseAnimation是类。 RunConditions由名为“条件”的类管理,当前该类如下:

[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class Conditions
{
    public List<ParameterCondition> ParamConditions { get; set; }
}

问题是json数据与类结构不匹配。原因很复杂,但简短的版本是用于基于XML的代码,并且似乎在转换为JSON时从未进行过适当的测试。如果可能的话,我既不想更改数据文件,也不想更改将最终保存数据的结构。理想的解决方案是制作一些可以自定义仅解析此类的代码,该类由正在运行的JSON反序列化代码调用,如下所示:

public static Conditions Deserialize(JToken jtoken)
{
    Conditions condition = new Conditions();
    condition.ParamConditions = new List<ParameterCondition>();
    foreach (JProperty prop in jtoken)
    {
        ConditionType type = (ConditionType)Enum.Parse(typeof(ConditionType), prop.Value.ToString(), true);
        condition.ParamConditions.Add(new ParameterCondition()
        {
            Condition = type,
            ParameterName = prop.Name
        });
    }

    return condition;
}

在环顾四周时,我看到了可以完全自定义反序列化所有内容的解决方案,但是我只想对这一部分进行反序列化。

这是针对名为Project Porcuipine的开源游戏。一些可能有帮助的地方:

1 个答案:

答案 0 :(得分:0)

步骤1。编写一个类来对此进行解析,以扩展JsonConverter。

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        Conditions condition = new Conditions();
        condition.ParamConditions = new List<ParameterCondition>();
        JToken jtoken = JToken.ReadFrom(reader);
        foreach (JProperty prop in jtoken)
        {
            ConditionType type = (ConditionType)Enum.Parse(typeof(ConditionType), prop.Value.ToString(), true);
            condition.ParamConditions.Add(new ParameterCondition()
            {
                Condition = type,
                ParameterName = prop.Name
            });
        }

        return condition;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Conditions conditions = (Conditions)value;
        JObject jObjs = new JObject();
        foreach (ParameterCondition pCondition in conditions.ParamConditions)
        {
            JProperty prop = new JProperty(pCondition.ParameterName, pCondition.Condition.ToString());
            jObjs.Add(prop);
        }
        jObjs.WriteTo(writer);
    }
}

步骤2:在代码中,当引用解析条件时,让其知道要使用哪个JsonConverter。

    [JsonConverter(typeof(ConditionsJsonConvertor))]
    public Conditions RunConditions { get; set; }