子对象的Json.net自定义转换器

时间:2016-08-29 13:53:33

标签: c# json converter

也许这与c# json.net custom serialization of subobjects有关。但没有帮助...

我希望在解析时将List反序列化为数据[,],但转换器不想工作。数据[,]是一个类的成员。 我需要将转换器添加到JsonProperty吗?我真的需要两个转换器吗?

此刻我得到了这个:
反序列化多维数组时出现意外的标记:StartObject。路径'[0]',第2行,位置3.
搜索没有帮助:/

我的代码:

Program.cs的

using System;
using Newtonsoft.Json;
using System.IO;

public class Program {
    static void Main(string[] args) {
        JsonSerializerSettings jss = new JsonSerializerSettings();
        jss.Converters.Add(new MyObjectJsonConverter());
        MyObject field = JsonConvert.DeserializeObject<MyObject>(File.ReadAllText("data.json").ToString(), jss);
        Console.ReadLine();
    }
}

MyObject.cs

using Newtonsoft.Json;

public class MyObject {
    [JsonProperty(PropertyName = "area", Required = Required.Always)]
    public area m_area;
    [JsonProperty(PropertyName = "datalist", Required = Required.Always)]
    public data[,] m_datalist;
}

data.cs

using Newtonsoft.Json;

    public class data {
        [JsonProperty(PropertyName = "info", Required = Required.Always)]
        public string m_info;
        [JsonProperty(PropertyName = "info2", Required = Required.Always)]
        public string m_info2;
    }

area.cs

using Newtonsoft.Json;

public class area {
    [JsonProperty(PropertyName = "x", Required = Required.Always)]
    public int m_x;
    [JsonProperty(PropertyName = "y", Required = Required.Always)]
    public int m_y;
}

两个转换器。

MyObjectJsonConverter.cs

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class MyObjectJsonConverter : JsonConverter {

    public override bool CanConvert(Type objectType) {
        return objectType == typeof(MyObject);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        JObject jObject = JObject.Load(reader);
        MyObject result = new MyObject();

        result.m_area = JsonConvert.DeserializeObject<area>(jObject["area"].ToString());

        JsonSerializerSettings jss = new JsonSerializerSettings();
        jss.Converters.Add(new DataListJsonConverter(result.m_area.m_x, result.m_area.m_y));
        result.m_datalist = JsonConvert.DeserializeObject<data[,]>(jObject["datalist"].ToString(), jss);

        return result;
    }

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

DataListJsonConverter.cs

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

public class DataListJsonConverter : JsonConverter {
    private readonly int m_x;
    private readonly int m_y;

    public DataListJsonConverter(int x, int y) {
        m_x = x;
        m_y = y;
    }

    public override bool CanConvert(Type objectType) {
        return objectType == typeof(List<data>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        JObject jObject = JObject.Load(reader);

        data[,] tilesArray = new data[m_x, m_y];

        foreach (JToken token in jObject["datalist"]) {
            data curTile = JsonConvert.DeserializeObject<data>(token.ToString());
            tilesArray[(int) token["x"], (int) token["y"]] = curTile;
        }

        return tilesArray;
    }

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

和data.json

{
    "area": {
        "x": 10,
        "y": 10
    },
    "datalist": [
        {
            "x": 1,
            "y": 2, 
            "info": "test1",
            "info2": "test1"
        },
        {
            "x": 3,
            "y": 5, 
            "info": "test2",
            "info2": "test2"
        },
        {
            "x": 5,
            "y": 7, 
            "info": "test3",
            "info2": "test3"
        },
        {
            "x": 6,
            "y": 4, 
            "info": "test4",
            "info2": "test4"
        },
    ]
}

1 个答案:

答案 0 :(得分:0)

对DataListJsonConvert进行微小更改可能会解决这个问题:

更新can convert方法以检查您尝试反序列化的内容

public override bool CanConvert( Type objectType )
    {
        return objectType == typeof( data[,] );
    }

并在您的ReadJson实现中读取json内容为JArray而不是JObject

public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
    {
        JArray jArray = JArray.Load( reader );

        data[,] tilesArray = new data[m_x, m_y];

        foreach( JToken token in jArray )
        {
            data curTile = JsonConvert.DeserializeObject<data>( token.ToString() );
            tilesArray[(int) token["x"], (int) token["y"]] = curTile;
        }

        return tilesArray;
    }

我认为这应该为您提供您正在寻找的多维数组结构。