0

Maybe this is related c# json.net custom serialization of subobjects. But wasnt helping...

I want to deserialize a List to a data[,] while parsing, but the converter does not want to work. And data[,] is a member of a class. Does i need to add the converter to JsonProperty? Does i really need both converters?

At the moment i got this:
Unexpected token when deserializing multidimensional array: StartObject. Path '[0]', line 2, position 3.
A search wasnt helping :/

My Code:

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;
}

And both converters.

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();
    }
}

and the 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"
        },
    ]
}
2
  • 1
    couple of questions : 1) why are you suing multidimensional array here data[,]? the json looks like it's plain one dimensional array. 2) and are you using "data" & "data2" fields in the json string on purpose or you meant to say "info" & "info2"? Commented Aug 29, 2016 at 14:14
  • 1
    I need to convert it into an 2D array for further using the data. The x and y of the objects in the array will used as index. 2. yes my fault. I correct it. Commented Aug 29, 2016 at 14:26

1 Answer 1

0

Minor changes to DataListJsonConvert might do the trick here :

update the can convert method to check for what you are attempting to deserialize to

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

and in your ReadJson implementation read the json content as JArray instead of 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;
    }

and I think this should give you the multidimensional array structure you are looking for.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.