2017-01-17 7 views
1

私はJson.netにカスタムコンバータを書く必要があると考え始めています。なぜならこれまでの正規コンバータはそれをカットしていないからです。 私が正しいJSONにシリアル化したクラスのゲームカスタムJson.netシリアライザ/デシリアライザを作成しますか?

class Game 
    { 
     [JsonProperty] 
     public int Edition { get; private set; } 
     [JsonProperty] 
     public string Name 
    { 
     get 
     { 
      return NameType.ToString(); 
     } 
     private set 
     { 
      name = value; 
     } 
    } 

    [JsonProperty] 
    public string Date { get; private set; } 

    [JsonConverter(typeof(StringEnumConverter))] 
    public GameType NameType { get; private set; } //enum 

    public List<Question> Questions { get; private set; } //yes, Question is serializable 

public Game(string Date, GameType t, int num, List<Question> q) 
    { 
     this.Date = Date; 
     this.NameType = t; 
     this.Edition = num; 
     this.Questions = q; 
    } 

を持っていますが、正しくデシリアライズしません。 JSONは次のようになります。

{ 
"Edition": 1, 
    "Name": "Regular", 
    "Date": "2016", 
    "NameType": "Regular", 
    "Questions": [ 
    { 
     "QuestionNumber": "1", 
     "Round": 1, 
     "Body": "1. A couple paragraphs", 
     "Answer": " answers" 
    }, 
    ] 
} 

しかし、デシリアライズするとき、それはのように出てくる:

日、 "2016"、 版 "1"、 名 "なし"、 NAMETYPE "なし"、私はこのようなデシリアライズで何か間違ったことを

ヌル 質問をしました:

Game g = JsonConvert.DeserializeObject<Game>(File.ReadAllText(path)); 

またはこれはカスタムシリアライザの作成を保証する状況ですか?

私はまだこのバグのようなものを扱っていると答えています.Json.netのドキュメントによれば、カスタムシリアライザを必要とする奇妙なケースのほとんどはIEnumerablesとDateTimes以外です。あなたには、いくつかの不変の性質、すなわちEditionDateNameTypeを持つクラスを作成しようとしているかのように

+1

は完全に論理的だ:すべてのあなたのセッターは、プライベート 'プライベート設定されているため、 'と名前はセッターを持っていないので、同じ方法でそれをデシリアライズしようとすると、jsonプロパティとして追加しません。 –

+0

_「これまでの正規のコンバーターはそれをカットしていないので、私はJson.netでカスタムコンバータを書く必要があると思っています」_ [_自分自身を責める](http://wiki.c2.com/ ?BlameYourselfFirst)_ :) – MickyD

+0

@MickyD、うん、それは私がしたことはかなりばかげていた。だから私は本当に1ヶ月前に書いたコードを振り返ってみるべきだった。今私は私の顔に大きな机のプリントを持っています – Alexandre

答えて

1

に見えます。さらに、NameTypeの1つは、JsonConverterがJson.NETによって適切にシリアライズされるために適用される必要があります。そのようなクラスをシリアライズおよびデシリアライズするには、引数名がc#のプロパティ名と同じ場合、モジュロの場合はである必要があり、引数として渡される必要なプロパティを持つ単一のコンストラクタを与えてください。プロパティ[JsonConverter(typeof(StringEnumConverter))]を適切な引数と対応するプロパティに適用できますが、適用されていない場合は、プロパティとパラメータが同じであると宣言されている限り、対応するプロパティのコンバータが使用されます。types

class Game 
{ 
    public Game(int edition, string date, [JsonConverter(typeof(StringEnumConverter))] GameType nameType) 
    { 
     this.Edition = edition; 
     this.Date = date; 
     this.NameType = nameType; 
     this.Questions = new List<Question>(); 
    } 

    public int Edition { get; private set; } 

    [JsonIgnore] 
    public string Name 
    { 
     get 
     { 
      return NameType.ToString(); 
     } 
    } 

    public string Date { get; private set; } 

    [JsonConverter(typeof(StringEnumConverter))] 
    public GameType NameType { get; private set; } //enum 

    public List<Question> Questions { get; private set; } //yes, Question is serializable 
} 

サンプルfiddle

あなたのクラスに複数のコンストラクタを持っている場合は、[JsonConstructor]に必要なすべての不変の性質を持つもの、例えばマーク:これは

public Game(int edition, string date, [JsonConverter(typeof(StringEnumConverter))] GameType nameType) 
     : this(edition, date, nameType, new List<Question>()) 
    { 
    } 

    [JsonConstructor]  
    public Game(int edition, string date, [JsonConverter(typeof(StringEnumConverter))] GameType nameType, List<Question> questions) 
    { 
     this.Edition = edition; 
     this.Date = date; 
     this.NameType = nameType; 
     this.Questions = questions; 
    } 
関連する問題