2011-06-28 5 views
288

Json.NETを使用してクラスをJSONにシリアル化しています。json.netを使用してnullの場合にclassのプロパティを無視する方法

私はこのようなクラスを持っている:

class Test1 
{ 
    [JsonProperty("id")] 
    public string ID { get; set; } 
    [JsonProperty("label")] 
    public string Label { get; set; } 
    [JsonProperty("url")] 
    public string URL { get; set; } 
    [JsonProperty("item")] 
    public List<Test2> Test2List { get; set; } 
} 

私はTest2Listnullある場合にのみTest2ListプロパティにJsonIgnore()属性を追加します。それがnullでない場合、私はそれを私のjsonに含めることにします。

答えて

383

James Newton King氏:JavaScriptConvertを使用するのではなく、シリアライザを自分で作成する場合は、無視するように設定できるNullValueHandling propertyがあります。に見られるように

[JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 
//or 
[JsonProperty("property_name", NullValueHandling=NullValueHandling.Ignore)] 

:@amit

JsonConvert.SerializeObject(myObject, 
          Newtonsoft.Json.Formatting.None, 
          new JsonSerializerSettings { 
           NullValueHandling = NullValueHandling.Ignore 
          }); 
+114

これは動作しますJsonConvert.SerializeObject(myObjectという、Newtonsoft.Json.Formatting.None、新しいJsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore})。 – Amit

+0

詳細:http://goo.gl/c8Bk1 – Amit

+0

それは私のために働いたが、最後の1つについてエラーを示したので、私は 'JsonSerializerSettings'を' JsonSerializerSettings'で使用しなければならなかった。 – Yazan

523

JsonProperty属性を使用して代替ソリューションによって示唆されるように、

JsonSerializer _jsonWriter = new JsonSerializer { 
           NullValueHandling = NullValueHandling.Ignore 
          }; 

あるいは:ここ

は、サンプルのthis online doc

+42

受け入れられた答えよりもはるかに優れています。 –

+11

Json.netの属性を使ってクラスを汚染しないので、受け入れられた答えが優れています。 – Sergey

+25

@Sergeyユースケースによって異なります。あなたが特定のプロパティ(質問に記載されているように)のためだけにしたい場合は、これが正解です。グローバル回答が必要な場合は、JsonSerializerでプロパティを設定する必要があります。 – sibbl

8

自分のサイトのこのリンクからもわかるように(http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size .aspxの)私は[デフォルト()]は@ sirthomasの答えに

public class Invoice 
{ 
    public string Company { get; set; } 
    public decimal Amount { get; set; } 

    // false is default value of bool 
    public bool Paid { get; set; } 
    // null is default value of nullable 
    public DateTime? PaidDate { get; set; } 

    // customize default values 
    [DefaultValue(30)] 
    public int FollowUpDays { get; set; } 
    [DefaultValue("")] 
    public string FollowUpEmailAddress { get; set; } 
} 


Invoice invoice = new Invoice 
{ 
    Company = "Acme Ltd.", 
    Amount = 50.0m, 
    Paid = false, 
    FollowUpDays = 30, 
    FollowUpEmailAddress = string.Empty, 
    PaidDate = null 
}; 

string included = JsonConvert.SerializeObject(invoice, 
    Formatting.Indented, 
    new JsonSerializerSettings { }); 

// { 
// "Company": "Acme Ltd.", 
// "Amount": 50.0, 
// "Paid": false, 
// "PaidDate": null, 
// "FollowUpDays": 30, 
// "FollowUpEmailAddress": "" 
// } 

string ignored = JsonConvert.SerializeObject(invoice, 
    Formatting.Indented, 
    new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); 

// { 
// "Company": "Acme Ltd.", 
// "Amount": 50.0 
// } 
42

同様のリンクから撮影既定値

を指定するために使用をサポートし、JSON.NETも尊重the EmitDefaultValue propertyDataMemberAttribute上:

[DataMember(Name="property_name", EmitDefaultValue=false)] 

モデルタイプに[DataContract][DataMember]を既に使用していて、JSON.NET固有の属性を追加したくない場合は、これが望ましい場合があります。

+1

これはとても役に立ちます!私はカスタムのExceptionクラスを設計していましたが、そこにJson.netのものを追加したくありませんでした。ありがとう! – jpgrassi

+0

これは.NET Coreでは動作しませんでした。 @sirthomasをお勧めします。答え:[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] – Derrick

+0

それは、ニュートンソフト.Json 10.0.2で.Net Coreでうまく動作します。 –

13

あなたがシリアライズしているオブジェクト内のすべてのNULLを無視するようにこれを行うことができ、かつ任意のヌル性質は、その後、@ Mrchiefさん/アミットの回答を@に適応

JsonSerializerSettings settings = new JsonSerializerSettings(); 
settings.NullValueHandling = NullValueHandling.Ignore; 
var myJson = JsonConvert.SerializeObject(myObject, settings); 
0

GlennGの非常に役立つ答え(C#からVB.Netへの構文の翻訳は必ずしも「明白」ではない)を少し説明すると、個々のクラスプロパティを装飾してnull値の扱いを管理することもできます。これを行う場合は、GlennGの提案からグローバルなJsonSerializerSettingsを使用しないでください。そうしないと、個々の装飾がオーバーライドされます。これは、コンシューマが特別な処理を行う必要がないように、null項目をJSONに表示する場合に便利です。例えば、消費者がオプション項目の配列を知る必要がある場合、通常は利用可能であるが、現在空である場合...プロパティ宣言で 装飾は次のようになります。に= NullValueHandling.Include:あなたが持っている必要はありませんこれらのプロパティについては

<JsonPropertyAttribute("MyProperty", DefaultValueHandling:=NullValueHandling.Include)> Public Property MyProperty As New List(of String) 

は、JSONの変更にまったく表示され= NullValueHandling.Ignore 。 ところで、XMLとJSONの両方のシリアル化のプロパティを飾ることができます(ちょうどお互いのすぐ隣に配置してください)。これにより、ドットネットのXMLシリアライザやNewtonSoftシリアライザを自由に呼び出すことができます。どちらも並行して動作し、顧客はXMLまたはJSONで作業することができます。私は両方を必要とする顧客を持っているので、これはドアノブのスヌットとして滑らかです!あなたが書くことができ

0

[JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]

+0

これはsirthomasの答えとまったく同じです、なぜあなたはそれを追加しましたか? – OMGtechy

+0

あなたの種類の情報については、DefaultValueHandlingとNullValueHandlingの間に違いがあります... –

+2

あなたの答えでそれを説明できますか?一見すると、それは同じように見えますが、今言及しましたが、これが他の答えとどのように違うか/それがどのようにそれを補うかは述べられていません。 – OMGtechy

0

ここに似ていますオプションがありますが、別の選択肢を提供します。

public class DefaultJsonSerializer : JsonSerializerSettings 
{ 
    public DefaultJsonSerializer() 
    { 
     NullValueHandling = NullValueHandling.Ignore; 
    } 
} 

その後、私はこのようにそれを使用します。ここ

JsonConvert.SerializeObject(postObj, new DefaultJsonSerializer()); 

差異れますその:

  • JsonSerializerSettingsを使用して、それぞれの場所をインスタンス化して構成することにより、繰り返しコードを減らします。
  • シリアル化するすべてのオブジェクトのすべてのプロパティを設定する時間を節約します。
  • プロパティを再利用可能なオブジェクトに明示的に指定するのではなく、他の開発者にもシリアル化オプションを柔軟に提供します。
  • 私の使用例は、コードが第三者のライブラリであり、クラスを再利用したい開発者に強制的にシリアル化オプションを強制したくないということです。
  • 潜在的な欠点は、他の開発者が知っておく必要がある別のオブジェクト、またはアプリケーションが小さく、このアプローチが単一のシリアライゼーションに関係しないことです。
0
var settings = new JsonSerializerSettings(); 
settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
settings.NullValueHandling = NullValueHandling.Ignore; 
//you can add multiple settings and then use it 
var bodyAsJson = JsonConvert.SerializeObject(body, Formatting.Indented, settings); 
関連する問題