2016-09-30 13 views
1

デフォルトでnull値が割り当てられていても、Newtonsoft Json.NETデシリアライザによって割り当てられるJson文字列内の値のみを持つことはできますか?Newtonsoft Json.NET Json Stringの値のみを逆シリアル化する

以下の例を使用して、プロパティが設定されているときに_valuesディクショナリに追加される値を見つけようとしています。 Json 1では、すべての値が設定され、データベースに保存されます。 Json 2では、識別子が設定され、Valueがnullに更新されます。デシリアライズ後、私はデータベース内の値を見つけて、フィールドのみを辞書の値で更新したいと思う。この問題は、デフォルト値であるため、nullを割り当てることで値が実際に設定されることはありません。

今のところ、私はデフォルトを無視することができますが、Value:nullは無視されます。または、デフォルトをインクルードすることができ、NameがJsonにない場合でもNameにnullが割り当てられます。

私は

[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)] 

が、シリアライズに...私は追加することができます知っている、私はデフォルトを無視したいと思います。

デシリアライザコード

var jsonSerializer = new JsonSerializer(); 
var widget = jsonSerializer.Deserialize<Widget>(jsonString); 

シリアライザコード

var serializer = new JsonSerializer 
{ 
    DefaultValueHandling = DefaultValueHandling.Ignore 
}; 
var jsonString = serializer.Serialize(widget); 

例クラス

public class Widget 
{ 
    [JsonProperty] 
    public int Id { get { return Get<int>("Id"); } set { Set("Id", value); } } 

    [JsonProperty] 
    public string Name { get { return Get<string>("Name"); } set { Set("Name", value); } } 

    [JsonProperty] 
    public string Value { get { return Get<string>("Value"); } set { Set("Value", value); } } 

    private Dictionary<sting, object> _values = new Dictionary<sting, object>(); 
    private object Get<T>(string name) 
    { 
     if (_values.TryGetValue(name, out value)) 
      return (T)value; 
     else 
      return default(T); 
    } 
    private void Set(string name, object value) 
    { 
     _values[name] = value; 
    } 
} 

例JSON 1

{ 
    "Id": 6, 
    "Name": "Widget 1", 
    "Value": "Blue" 
} 

例JSON 2

{ 
    "Id": 6 
    "Value": null 
} 
+1

最初にJSONをどのようにデシリアライズしていますか?私は本当にあなたがやろうとしていることに従わない。 –

+0

[Json.NETを使用して新しい部分JSONデータで既存のオブジェクトを変更する](http://stackoverflow.com/q/27511675/10263)を参照してください。これはあなたが解決しようとしているのと同じ問題のようです。これは 'serializer.PopulateObject'を使って部分的な更新を行います。つまり、既存のオブジェクトをロードし、PopulateObjectを使用してパッチを適用し、オブジェクトをデータストアに保存し直します。 –

答えて

1

あなたは、例えば、ShouldSerializeメソッドを利用することができます

bool ShouldSerializeName() { 
    return _values.ContainsKey("Name"); 
} 

bool ShouldSerializeValue() { 
    return _values.ContainsKey("Value"); 
} 

これはうまくいかないが動作するはずです。別のオプションは、カスタムシリアライザです。

+0

私はあなたがこれで行くところを見ます。デシリアライズのために[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]を追加する必要があります。私のプロジェクトには500以上のプロパティがあります。 IContractResolverでこれを行う必要があるかもしれません。 –

関連する問題