0

Json.Netを使用して、別のJson.Netライブラリで生成されたJsonデータを逆シリアル化できますか(私はJson.Netの.Net4およびWindows Phoneライブラリを使用しています)?これは私がこれまでに持っているものです:

XNA(.Net 4)で作成されたマップエディターがあり、Json.Net(.Net用)を使用してJsonデータをシリアル化および逆シリアル化できます。データを格納する構造体を作成し、次のようにセリザライズするデータプロパティを指定します。

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

また、Nodeクラスは次のとおりです。

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

    ....
}

また、Json.Net(Windows Phone用)を使用して、マップエディターから作成されたJsonデータを読み込むWindowsPhoneXNAゲームもあります。このゲームにはLevelDataとNodeがあり、これらはMapEditorの構造体とクラスとまったく同じです。

Json.Netは、.Net4とWindowsPhoneに異なるライブラリを提供します。ただし、それらは同じ機能を持っていないようです。Windows Phoneゲームがマップエディターから作成された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をシリアル化および逆シリアル化できます。これは、プライベートjsonプロパティとVector2をサポートします。問題は、WindowsPhoneアプリケーションでマップエディターで生成されたjsonデータを逆シリアル化する場合です。

4

2 に答える 2

1

試してみることができるのは、Vector2タイプ用の独自のコンバーターを導入することです。

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

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

  ...
}

Vector2ConverterJson.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の使用を検討し始めることができます。これにより、他のタイプにキャストして、からのデータを使用して新しいデータを作成できる可能性のあるが返されます。それがうまくいかない場合は、リーダーのトークンに反応するさらに複雑なものを調べる必要があるかもしれません(など)ValueJsonReaderobjectVector2JsonConverterTokenType

于 2012-04-17T23:16:52.647 に答える
0

Vector2 またはその他の同様のオブジェクトのシリアル化と逆シリアル化で問題が発生する将来の視聴者に対する、より完全な回答です。OPのようなWinPhoneではなく、ストレートなWindowsで問題が発生しています。

次のように、シリアル化する必要がある各 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();
    }
}
于 2013-02-16T16:25:16.227 に答える