2012-04-17 2 views
0

Json.Net을 사용하여 다른 Json.Net 라이브러리에서 생성 된 Json 데이터를 비 직렬화 할 수 있습니까 (Json.Net의 .Net4 및 windows phone 라이브러리를 사용하고 있습니다) ? 이것은 내가 지금까지 가지고있는 것입니다 :다른 Json.Net 라이브러리에 의해 생성 된 Json 데이터 비 직렬화

저는 Json.Net (.Net 용)을 사용하여 Json 데이터를 직렬화 및 비 직렬화 할 수있는 XNA (.Net 4)로 만든 맵 편집기를 가지고 있습니다. 다음과 같이

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

그리고 노드 클래스는 다음과 같습니다 : 나는 데이터를 저장하고 내가 serizalized 원하는과 같이 어떤 데이터 속성을 지정하는 구조체를 만들

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

    .... 
} 

나는 또한 윈도우 전화 XNA 게임을 Json.Net을 사용하여지도 편집기에서 만든 Json 데이터를 읽습니다 (Windows Phone 용). 이 게임은지도 편집기 구조체 및 클래스와 정확히 동일한 LevelData 및 Node를 가지고 있습니다.

Json.Net은 .Net 4 및 windows phone 용으로 다른 lib를 제공합니다. 그러나, 그들은 동일한 기능을 가지고 있지 않습니다. 가 디버그 창에 인쇄 다음과 같이

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 
윈도우 폰 게임지도 편집기에서 생성 된 JSON 데이터에 읽을 때 다음과 같은 오류와 함께, 데이터를 역 직렬화 실패

이 문제는 개인 변수가 아닌 public으로 멤버 변수를 지정하여 해결할 수 있습니다. 그러나 그것은 Vector2 인식하지 못하는 불평 :

{ 
    "RowCount": 20, 
    "ColCount": 20, 
    "NodeSize": 25, 
    "LevelNodes": [ 
     { 
      "ID": 1, 
      "Position": "12, 12", 
      "Type": 1, 
      "Neighbours": [ 
       2, 
       21 
      ] 
     } 
    ], 
    "Buildings": [] 
} 
:지도 편집기에 의해 생성 된 JSON 데이터입니다

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 

다음은 디버그 창에 인쇄 다음과 같이

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

편집 : 다음은 데이터를 serialize하고 deserialize하는 방법입니다.

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

그냥 참고 : 나는 직렬화 및지도 편집기 (닷넷) 잘, 그것은 개인 JSON 특성과 Vector2 지원에서 JSON을 역 직렬화 할 수 있습니다. 문제는지도 편집기에서 Windows 전화 응용 프로그램에서 생성 된 json 데이터를 deserialize하려고 할 때입니다.

답변

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

나는 그래서 확실히 상자 밖으로 작동합니다 확신 할 수 없습니다 s의 Vector2의 특별한 경우에 이것을 시도하지 않았습니다. ReadJson 구현에없는 경우 JsonReader에서 Value 속성을 사용하기 시작할 수 있습니다. 이렇게하면 object이 반환되며 다른 유형으로 캐스팅하고 데이터를 사용하여 Vector2을 새로 만들 수 있습니다.그래도 문제가 해결되지 않으면 독자의 토큰에 대응하는 JsonConverter을 조사해야 할 수도 있습니다 (TokenType 등)

+0

덕분에, 내가 그 길을 갈 필요가 없습니다 않았다 기대했다 다른 많은 객체 유형과 함께이 문제가 발생합니다. 그들이 .Net 버전을 위해 그것을 할 수있는 이유를 이해하지 마십시오. 어쩌면 실버 라이트일까요? – Benzino

+0

필자는 확실히이 문제가 발생하지 않았고'Vector2'를 보았습니다 (저는 XNA 작업을하지 않았습니다) 그것과 관련된 특별한 것을 볼 수는 없습니다 ('struct'가 아닌,'DateTime '). 살펴볼 또 다른 사항은 데이터를 어떻게 직렬화하는 것입니까? 'TypeNameHandling'과'TypeNameAssemblyFormat' 옵션은'JsonSerializer'를 제공합니까? – MrMDavidson

+0

나는이 문제를보고 있다고 생각한다. 실제로 JsonSerializer 자체가 아니라 JsonConvert를 사용하고 있습니다. 원본 게시물을 편집하여 데이터를 직렬화하는 방법을 보여줍니다. 나는 또한 다음 JsonSettings'Formatting.Indented, TypeNameHandling.All, FormatterAssemblyStyle.Full'을 사용해 보았지만 여전히 Vector2에 대해 불평하고있다. – Benzino

0

Vector2 또는 다른 시리즈를 직렬화 및 비 직렬화하는 데 문제가있는 향후 시청자를위한보다 완벽한 답변 비슷한 대상. WinPhone이 아닌 OP와 같은 문제는 직선적 인 Windows에서 발생합니다.

그것은 직렬화 객체 자체보다는 필요한 각 Vector2 속성에 사용자 정의 Vector2 디시리얼라이저는과 같이, 직렬화되는 설정을 가능 :

모든 Vector2 속성을 장식하는 데에서 우리를 유지
var settings = new JsonSerializerSettings(); 
settings.Converters.Add(new Vector2Converter()); 
YourType yourObj = JsonConvert.DeserializeObject<YourType>(fileContents, settings); 

.

읽기와 또한

, 내가 사용하고 컨버터의 전체 구현 및 구현 쓰기는이다 : 나는 의심으로

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(); 
    } 
} 
관련 문제