2016-02-19 3 views
5

とオブジェクトプロパティの条件シリアライズ/デシリアライズ私は以下のように定義されたクラスとのシナリオを持っている:json.net

class MyObject 
{ 
    public DataDictionary MyObjectData { get; set; } 

    public bool ShouldSerializeMyObjectData() { return true; } 
    public bool ShouldDeserializeMyObjectData() { return false; } 
} 

IはJSON.netと、そのクラスを逆シリアル化/シリアル化しようとすると、それはShouldSerializeを取りますただし、ShouldDeserializeは考慮しません。

ドキュメントによると、どちらも同じように動作するはずです。私が知るべきことは何か特別ですか?より一般的には、プロパティをシリアル化して逆シリアル化しないシナリオをどのように扱うべきですか?

私はJson.NET 8.0を使用しています。

ありがとうございました。

+0

[documentation](http://www.newtonsoft.com/json/help/html/ConditionalProperties.htm)の 'ShouldDeserialize'については何も言いません。なぜあなたは何かをシリアル化したいのですが、それを逆シリアル化しないでしょうか? – kjbartel

+0

@kjbartelシリアライゼーション/デシリアライゼーションと同じモデルですが、デシリアライズするときは、その特定のプロパティにアクセスするための中間リンク(hateoas)があります。 –

+2

参照[Serializeプロパティ、Json.Netのプロパティをデシリアライズしない](http:// stackoverflow。com/q/31731320/10263) –

答えて

6

ShouldDeserialize{PropertyName}()の自動チェックはShouldSerialize{PropertyName}()であっても実装されていません。より長い回答と回避策が続きます。

クラスJsonPropertyは、JSONプロパティを.NETメンバーまたはコンストラクタパラメータにマップする方法の契約を定義するために、Json.NETによって内部的に使用されます。 ShouldSerializeShouldDeserializeの2つの述語プロパティがあり、nullでない場合はプロパティの直列化と逆シリアル化がそれぞれ防止されます。各JsonPropertyの初期化はContractResolverの仕事です。各プロパティ{PropertyName}に対して、Json.NETのdefault contract resolverは、public bool ShouldSerialize{PropertyName}()メソッドの存在を自動的にチェックします。このようなメソッドが存在する場合は、ShouldSerialize述語にそのメソッドを呼び出し、メソッドがfalseを返したときにシリアライゼーションを抑制します。これは、メソッドShouldSerialize{PropertyName}()によるプロパティ直列化の制御が、例えばXmlSerializerによってサポートされる標準パターンであるために実装された。詳細については、Json.NET release notesを参照してください。例えば

は、次のクラスでは、MyObjectDataのシリアライズがMyObjectData.Count > 0ない限り抑制されます。

class MyObject 
{ 
    public DataDictionary MyObjectData { get; set; } 

    public bool ShouldSerializeMyObjectData() { return MyObjectData != null && MyObjectData.Count > 0; } 
} 

JsonProperty.ShouldDeserialize、しかし、は、それはデフォルト契約リゾルバによって設定されることはありません。これは、ShouldSerialize{PropertyName}()に相当する逆シリアル化の標準パターンがないため、Newtonsoftはそのようなパターンを実装する要求を決して受けていないことが原因である可能性があります。それにもかかわらず、あなたが気づいたように、このようなパターンをサポートするインフラストラクチャが存在するため、アプリケーションはそれを行うcustom contract resolversを作成できます。実際には、Json.NETは独自のtest suiteで、このような契約のレゾルバの例があります。

public class ShouldDeserializeContractResolver : DefaultContractResolver 
{ 
    public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver(); 

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     JsonProperty property = base.CreateProperty(member, memberSerialization); 

     MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name); 

     if (shouldDeserializeMethodInfo != null) 
     { 
      property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o, null); }; 
     } 

     return property; 
    } 
} 

public class ShouldDeserializeTestClass 
{ 
    [JsonExtensionData] 
    public IDictionary<string, JToken> ExtensionData { get; set; } 

    public bool HasName { get; set; } 
    public string Name { get; set; } 

    public bool ShouldDeserializeName() 
    { 
     return HasName; 
    } 
} 

あなたは条件付き場合でも、JSONに存在するプロパティの直列化復元を抑制したい場合は、使用して(とcaching)検討することもできこの契約レゾルバ。

+0

これは、重複している質問に関する[他の回答](http://stackoverflow.com/a/31732029/1730559)とほぼ同じです。なぜ、この質問に重複しているのではないのですか? – kjbartel