2012-04-17 102 views
0

使用Json.Net,您是否可以反序列化在不同的Json.Net库中生成的Json数据(我使用的是Json.Net的.Net4和windows手机库) ?这是我到目前为止:反序列化由不同的Json.Net生成的Json数据lib

我有一个在XNA(.Net 4)中创建的地图编辑器,可以使用Json.Net(对于.Net)对Json数据进行序列化和反序列化。我创建了一个结构来存储数据,并指定哪些数据的属性我想serizalized,就像这样:

[JsonObject(MemberSerialization.OptIn)] 
public struct LevelData 
{ 
    [JsonProperty(PropertyName = "RowCount")] 
    private int RowCount; 

    [JsonProperty(PropertyName = "ColCount")] 
    private int ColCount; 

    [JsonProperty(PropertyName = "NodeSize")] 
    private int NodeSize; 

    [JsonProperty(PropertyName = "LevelNodes")] 
    private List<Node> LevelNodes; 

    public LevelData(int rowCount, int colCount, int nodeSize, List<Node> nodes) 
    { 
     RowCount = rowCount; 
     ColCount = colCount; 
     NodeSize = nodeSize; 
     LevelNodes = nodes; 
    } 
} 

和节点类如下:

[JsonObject(MemberSerialization.OptIn)] 
public class Node 
{ 
    [JsonProperty(PropertyName = "ID")] 
    private int mId; 

    [JsonProperty(PropertyName = "Position")] 
    private Vector2 mPosition; 

    [JsonProperty(PropertyName = "Type")] 
    private NodeType mType; 

    [JsonProperty(PropertyName = "Neighbours")] 
    private List<int> mNeighbours; 

    .... 
} 

我也有一个Windows Phone的XNA游戏,它读入从地图编辑器创建的Json数据,也使用Json.Net(用于Windows Phone)。这个游戏有LevelData和Node,它们和Map Editor结构和类完全一样。

Json.Net为.Net 4和windows phone提供了一个不同的库。但是,它们似乎没有相同的功能。当Windows手机游戏从地图编辑器创建的JSON数据读取,它未能反序列化数据,并显示以下错误:

Error getting value from 'mRowCount' on 'LevelData'. 

随着调试窗口中的以下打印出来:

A first chance exception of type 'System.FieldAccessException' occurred in mscorlib.dll 
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll 
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll 

我可以通过使成员变量公开而不是私有来解决这个问题。但随后抱怨说,它不承认Vector2:

Error converting value "12, 12" to type 'Microsoft.Xna.Framework.Vector2'. Line 8, position 27. 

随着调试窗口中的以下打印出来:

A first chance exception of type 'System.Exception' occurred in Newtonsoft.Json.dll 
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll 

,其中,通过地图编辑器创建的JSON数据:

{ 
    "RowCount": 20, 
    "ColCount": 20, 
    "NodeSize": 25, 
    "LevelNodes": [ 
     { 
      "ID": 1, 
      "Position": "12, 12", 
      "Type": 1, 
      "Neighbours": [ 
       2, 
       21 
      ] 
     } 
    ], 
    "Buildings": [] 
} 

编辑:这是我如何序列化和反序列化的数据。

String json = Json.ConvertToJson<LevelData>(levelData); 

public static class Json 
{ 
    // Serialize Object to Json 
    public static string ConvertToJson<T>(T obj) 
    { 
     return JsonConvert.SerializeObject(obj, Formatting.Indented); 
    } 

    public static T ConvertFromJson<T>(string json) 
    { 
     T result = JsonConvert.DeserializeObject<T>(json); 

     return result; 
    } 
} 

刚一说明:我可以序列化和反序列化的地图编辑器(.NET)就好了,它支持私人JSON属性和Vector2的JSON。问题是当我去反序列化在Windows Phone应用程序中在地图编辑器中生成的json数据时。

回答

1

你可以尝试的是为Vector2类型引入你自己的转换器;

[JsonObject(MemberSerialization.OptIn)] 
public class Node { 
    ... 

    [JsonConverter(typeof(Vector2Converter))] 
    public Vector2 Position { get; set; } 

    ... 
} 

Vector2Converter是一种从Json.Net的JsonConverter获得。

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
    return serializer.Deserialize<Vector2>(reader); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { 
    // Implement this if you're serialising back into JSON 
    throw new NotImplementedException(); 
    } 
} 

我没有在Vector2特定情况下尝试这个S因此无法确认它肯定会工作的开箱。如果它不在您的ReadJson实施中,您可以开始考虑使用JsonReader上的Value属性。这会返回一个object,您可以将其转换为其他类型,并可能使用其中的数据创建新的Vector2。如果不工作,你可能需要寻找到更多地参与JsonConverter,你的令牌反应的读者(TokenType等)

+0

谢谢,我希望我没有走这条路线,因为我怀疑我会遇到许多其他对象类型的问题。不明白他们为什么可以为.Net版本做,但没有Windows手机。也许这是为了silverlight? – Benzino 2012-04-18 13:19:28

+0

我以前从来没有遇到过这个问题,并且看过'Vector2'(我没有做过任何XNA工作),我看不到任何特殊的东西(除了是'struct',但是'DateTime' ')。另一件要看的是你如何序​​列化数据?你在给'JsonSerializer'选择什么'TypeNameHandling'和'TypeNameAssemblyFormat'选项? – MrMDavidson 2012-04-18 14:43:25

+0

我想我看到了这个问题。我实际上使用JsonConvert,而不是JsonSerializer本身。我编辑了我的原始帖子,以显示如何序列化数据。我也试过使用下面的JsonSettings'Formatting.Indented,TypeNameHandling.All,FormatterAssemblyStyle.Full',但它仍然抱怨Vector2。 – Benzino 2012-04-18 21:00:32

0

更完整的答案有问题序列化和反序列化未来的观众Vector2的或其他类似的物体。我在直接Windows中遇到问题,而不是像OP那样的WinPhone。

这是可能的设置序列化对象本身,而不是需要每个Vector2财产上的自定义Vector2解串器被序列化,像这样:

var settings = new JsonSerializerSettings(); 
settings.Converters.Add(new Vector2Converter()); 
YourType yourObj = JsonConvert.DeserializeObject<YourType>(fileContents, settings); 

这使我们不必装点每一个Vector2财产。

此外,全面落实我使用的转换器,具有读取和写操作实现,方法是:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
     JObject jsonObject = JObject.Load(reader); 
     var properties = jsonObject.Properties().ToList(); 
     return new Vector2 
     { 
      X = (float)properties[0].Value, 
      Y = (float)properties[1].Value 
     }; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { 
     Vector2 v = (Vector2)value; 
     writer.WriteStartObject(); 
     writer.WritePropertyName("X"); 
     serializer.Serialize(writer, v.X); 
     writer.WritePropertyName("Y"); 
     serializer.Serialize(writer, v.Y); 
     writer.WriteEndObject(); 
    } 
}