2011-06-28 133 views
288

我正在使用Json.NET將類序列化爲JSON。如何忽略類中的屬性如果爲null,使用json.net

我有類是這樣的:

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

我想添加一個JsonIgnore()屬性Test2List財產只有當Test2Listnull。如果它不是null,那麼我想把它包含在我的json中。

回答

383

按照James Newton King的說法:如果您自己創建序列化程序,而不是使用JavaScriptConvert,則可以設置爲忽略的NullValueHandling property

這裏的一個示例:

JsonSerializer _jsonWriter = new JsonSerializer { 
           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

它爲我工作,但我不得不使用'JsonSerializerSettings'而不是'JsonSerializer',因爲它顯示最後一個錯誤 – Yazan

523

使用JsonProperty屬性的替代的解決方案的建議:

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

如圖中所看到的this online doc

+42

比接受的答案好得多。 –

+11

接受的答案更好,因爲它不會污染您的類與Json.net屬性。 – Sergey

+25

@謝謝它取決於你的用例。如果你只想要它具有特定的屬性(如問題中提到的),那麼這是正確的答案。如果你想要一個全局的答案,你應該在JsonSerializer中設置屬性。 – sibbl

8

正如可以在他們的網站上的這個鏈接看到的(http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size的.aspx)我支持使用[默認()]指定從鏈接採取默認值

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

類似@ sirthomas的回答,也JSON.NET尊重the EmitDefaultValue propertyDataMemberAttribute

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

如果您的模型類型中已經使用[DataContract][DataMember],並且不想添加JSON.NET特定的屬性,則可能需要這樣做。

+1

這非常有幫助!我正在設計一個自定義的Exception類,我不想在那裏添加Json.net的東西。謝謝! – jpgrassi

+0

這不是在.Net核心工作。 Recomend @sirthomas答案:使用[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] – Derrick

+0

它適用於我在.Net核心與Newtonsoft.Json 10.0.2。 –

13

你可以做到這一點忽略你序列化對象的所有空值,任何空屬性將不會再出現在JSON

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

要對GlennG非常有用的答案(將C#語法轉換爲VB.Net並不總是「顯而易見」)稍作闡述,您還可以修飾各個類的屬性以管理空值的處理方式。如果您這樣做,請勿使用GlennG建議中的全局JsonSerializerSettings,否則將覆蓋個別裝飾。如果您希望在JSON中出現空項目,則此功能非常方便,因此用戶無需執行任何特殊處理。例如,如果消費者需要知道一系列可選項目通常可用,但目前爲空...... 在財產申報的裝修看起來是這樣的:

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

這些屬性你不希望有出現在JSON變化都:= NullValueHandling.Include:= NullValueHandling.Ignore 。 順便說一句 - 我發現你可以爲XML和JSON序列化裝飾一個屬性就好(只要把它們放在彼此的旁邊)。這使我可以選擇在dotnet或NewtonSoft序列化程序中隨意調用XML序列化程序 - 兩者並行工作,我的客戶可以選擇使用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); 
相關問題