Json.net का उपयोग करते हुए, यदि शून्य है, तो क्लास में प्रॉपर्टी की अनदेखी कैसे करें


529

मैं JSON का उपयोग कर रहा हूँ JSON के लिए एक वर्ग को अनुक्रमित करने के लिए।

मेरी कक्षा इस तरह है:

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संपत्ति केवल जब Test2Listहै null। अगर यह अशक्त नहीं है तो मैं इसे अपने जसन में शामिल करना चाहता हूं।

जवाबों:


685

जेम्स न्यूटन किंग के अनुसार: यदि आप JavaScriptConvert का उपयोग करने के बजाए अपने आप को क्रमबद्ध बनाते हैं, तो एक NullValueHandlingसंपत्ति है जिसे आप अनदेखा कर सकते हैं।

यहाँ एक नमूना है:

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

वैकल्पिक रूप से, @amit द्वारा सुझाव दिया गया है

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

159
यह काम करता है: JsonConvert.SerializeObject (myObject, Newtonsoft.Json.Formatting.None, नया JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});
अमित

इसने मेरे लिए काम किया लेकिन मुझे इसका उपयोग JsonSerializerSettingsनहीं करना पड़ा JsonSerializerक्योंकि इसमें पिछले एक के लिए एक त्रुटि दिखाई दी थी
यज़ान

1
एक महत्वपूर्ण बात - यह केवल ठोस वर्गों (व्यक्ति, खाता, आदि) के साथ काम करता है। जब मैंने डिक्शनरी के साथ यह कोशिश की, तो यह काम नहीं किया
chester89

1
मुझे @ chester89 जैसी ही समस्या है। एक ExpandoObject के साथ अशक्त मानों को अनदेखा नहीं किया जाता है। यह एक बग (json.net 9.0.1 का उपयोग करके)
प्रतीत होता है

2
जब उत्तर लिखा गया, तो JSON.Net ने गतिशील वस्तुओं का भी समर्थन नहीं किया। :) फिलहाल, आप अपनी बोली लगाने के लिए एक कस्टम कनवर्टर का उपयोग कर सकते हैं।
मृकफ़ जूल 5'16

922

JsonPropertyविशेषता का उपयोग कर एक वैकल्पिक समाधान :

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

// or for all properties in a class
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]

जैसा कि इस ऑनलाइन डॉक में देखा गया है ।


19
स्वीकृत उत्तर बेहतर है क्योंकि यह Json.net विशेषताओं के साथ आपकी कक्षाओं को प्रदूषित नहीं करता है।
सर्गेई

117
@ सेरी यह आपके उपयोग के मामले पर निर्भर करता है। यदि आप केवल विशिष्ट गुणों के लिए इसे रखना चाहते हैं (जैसा कि प्रश्न में उल्लेख किया गया है), तो यह सही उत्तर है। यदि आप एक वैश्विक उत्तर चाहते हैं, तो आपको संपत्ति को JsonSerializer में सेट करना चाहिए।
सिब्बल

सहमत - यह सरल और सुरुचिपूर्ण है। वर्चस्व बढ़ाने वाला। महान काम करता है - बस एक वस्तु सेट करें जिसे आप वीबी में कुछ भी नहीं करना चाहते हैं और यह जेएसएन का हिस्सा नहीं है। यह केवल स्ट्रिंग्स के साथ काम करेगा। गुण जो एनम या पूर्णांक हैं, वे हमेशा दिखेंगे - "0" के डिफ़ॉल्ट मान पर ध्यान दिए बिना कुछ भी सेट करने की परवाह किए बिना।
डेस्टेक

3
@Destek आपको संदर्भ प्रकार फ़ील्ड को अशक्त बनाने की आवश्यकता है, फिर उन्हें विशेषता या सेटिंग का उपयोग करके क्रमबद्ध नहीं किया जाएगा।
टोनी

1
कई विशेषताओं के साथ अपनी कक्षाओं को 'प्रदूषण' से बचने के लिए आप हैंडलिंग नियम को भी असाइन कर सकते हैं [JsonObject], लेकिन ध्यान दें कि विशेषता नाम अलग है। [संपादित जवाब]
साइमन_वेअर

60

@ Sirthomas के जवाब की तरह, JSON.NET भी सम्मान करता है संपत्ति पर :EmitDefaultValueDataMemberAttribute

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

यह वांछनीय हो सकता है यदि आप पहले से [DataContract]और [DataMember]अपने मॉडल प्रकार में उपयोग कर रहे हैं और JSON.NET- विशिष्ट विशेषताओं को जोड़ना नहीं चाहते हैं।


1
यह कितना मददगार है! मैं एक कस्टम एक्सेप्शन क्लास डिजाइन कर रहा था और मैं इसमें Json.net सामान नहीं जोड़ना चाहता था। धन्यवाद!
jpgrassi

2
यह .Net कोर में काम नहीं कर रहा था। Recomend @sirthomas उत्तर: उपयोग करें [JsonProperty (NullValueHandling = NullValueHandling.Ignore)]
डेरिक

1
यह मेरे लिए .net Core में Newtonsoft.Json 10.0.2 के साथ ठीक काम करता है।
कार्ल-जोहान सोजग्रेन ने

33

तुम लिख सकते हो: [JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]

यह डिफ़ॉल्ट मानों के साथ गुणों को क्रमबद्ध नहीं करने का भी ख्याल रखता है (केवल शून्य नहीं)। यह उदाहरण के लिए enums के लिए उपयोगी हो सकता है।


3
यह ठीक वैसे ही है जैसे कि सिथ्थोमास का उत्तर, आपने इसे क्यों जोड़ा?
OMGtechy

4
आपकी जानकारी के लिए, DefaultValueHandling और NullValueHandling के बीच अंतर है ...
वत्सल पटेल

4
क्या आप इसे अपने उत्तर में समझा सकते हैं? पहली नज़र में, यह समान दिखता है, और अब आपने उल्लेख किया है कि, यह यह नहीं बताता है कि यह दूसरे उत्तर से अलग कैसे है / यह इसकी तारीफ कैसे करता है।
OMGtechy

1
हालांकि स्वीकृत उत्तर कुछ परिस्थितियों में उपयोगी हो सकता है, लेकिन इसका उपयोग करना हमेशा संभव नहीं होता है। यह सिर्फ डॉक्टर ने आदेश दिया है।
मेलबर्न डेवलपर

1
मुझे लगता है कि यह वही है जो मैं चाहता था। कुछ गुणों पर विशिष्ट हैंडलिंग, सभी नहीं।
१२:३५ बजे ठंढाकार

23

आप ऐसा कर सकते हैं कि आप जिस धारावाहिक में किसी वस्तु को देख रहे हैं, सभी नल को अनदेखा कर सकते हैं, और कोई भी शून्य गुण तब JSON में दिखाई नहीं देगा

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

12

जैसा कि उनकी साइट (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
// }

4

@ Mrchief / @ @ amit के उत्तर के लिए एक अनुकूलन, लेकिन VB का उपयोग करने वाले लोगों के लिए

 Dim JSONOut As String = JsonConvert.SerializeObject(
           myContainerObject, 
           New JsonSerializerSettings With {
                 .NullValueHandling = NullValueHandling.Ignore
               }
  )

देखें: "ऑब्जेक्ट इनिशियलाइज़र: नाम और बेनामी प्रकार (विजुअल बेसिक)"

https://msdn.microsoft.com/en-us/library/bb385125.aspx


3

.Net कोर में यह अब बहुत आसान है। अपने startup.cs में केवल json विकल्प जोड़ें और आप वहां सेटिंग्स कॉन्फ़िगर कर सकते हैं।


public void ConfigureServices(IServiceCollection services)

....

services.AddMvc().AddJsonOptions(options =>
{
   options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;               
});

1

Json.NET के साथ

 public class Movie
 {
            public string Name { get; set; }
            public string Description { get; set; }
            public string Classification { get; set; }
            public string Studio { get; set; }
            public DateTime? ReleaseDate { get; set; }
            public List<string> ReleaseCountries { get; set; }
 }

 Movie movie = new Movie();
 movie.Name = "Bad Boys III";
 movie.Description = "It's no Bad Boys";

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

परिणाम होगा:

{
   "Name": "Bad Boys III",
   "Description": "It's no Bad Boys"
 }

1

System.Text.Json.NET .NET 3.0 के साथ और यह मेरे लिए काम करता है:

var jsonSerializerOptions = new JsonSerializerOptions()
{
    IgnoreNullValues = true
};
var myJson = JsonSerializer.Serialize(myObject, jsonSerializerOptions );

0

ग्लेनग के बहुत उपयोगी उत्तर पर थोड़ा सा विस्तार करने के लिए (सी # से VB.Net पर वाक्यविन्यास का अनुवाद हमेशा "स्पष्ट" नहीं होता है) आप यह भी प्रबंधित करने के लिए व्यक्तिगत वर्ग गुणों को प्रबंधित कर सकते हैं कि कैसे शून्य मानों को संभाला जाता है। यदि आप ऐसा करते हैं तो GlennG के सुझाव से वैश्विक JsonSerializerSettings का उपयोग न करें, अन्यथा यह व्यक्तिगत सजावट को ओवरराइड करेगा। यह काम में आता है यदि आप एक शून्य आइटम को JSON में दिखाना चाहते हैं तो उपभोक्ता को कोई विशेष हैंडलिंग करने की आवश्यकता नहीं है। यदि, उदाहरण के लिए, उपभोक्ता को वैकल्पिक वस्तुओं की एक सरणी जानना आवश्यक है, लेकिन यह वर्तमान में खाली है ... संपत्ति की घोषणा में सजावट इस तरह दिखती है:

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

उन गुणों के लिए जिन्हें आप JSON परिवर्तन में बिल्कुल नहीं दिखाना चाहते हैं : = NullValueHandling.Include to : = NullValueHandling.Ignore । वैसे - मैंने पाया है कि आप XML और JSON दोनों प्रकार के क्रमांकन के लिए एक संपत्ति को ठीक से सजा सकते हैं (बस उन्हें एक दूसरे के ठीक बगल में रखें)। यह मुझे इच्छा-सूची में XML सीरियलएजर को डॉटनेट या न्यूटनॉफ्ट सीरियल के लिए कॉल करने का विकल्प देता है - दोनों काम साइड-बाय-साइड और मेरे ग्राहकों के पास XML या JSON के साथ काम करने का विकल्प है। यह एक doorknob पर स्नॉट है क्योंकि मेरे पास ऐसे ग्राहक हैं जिनके लिए दोनों की आवश्यकता है!


0

यहां एक विकल्प है जो समान है, लेकिन एक और विकल्प प्रदान करता है:

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

फिर, मैं इसे इस तरह से उपयोग करता हूं:

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

यहाँ अंतर यह है कि:

  • बार-बार कोड को तत्काल उपयोग करके और JsonSerializerSettingsउसका उपयोग करने वाले प्रत्येक स्थान को कॉन्फ़िगर करके कम करता है।
  • क्रमबद्ध होने के लिए प्रत्येक वस्तु की प्रत्येक संपत्ति को कॉन्फ़िगर करने में समय बचाता है।
  • फिर भी अन्य डेवलपर्स को अनुक्रमिक विकल्पों में लचीलापन देता है, बजाय संपत्ति को एक पुन: प्रयोज्य वस्तु पर स्पष्ट रूप से निर्दिष्ट करने के बजाय।
  • मेरा उपयोग-मामला यह है कि कोड एक 3 पार्टी लाइब्रेरी है और मैं डेवलपर्स पर क्रमांकन विकल्पों को बाध्य नहीं करना चाहता हूं जो मेरी कक्षाओं का पुन: उपयोग करना चाहते हैं।
  • संभावित कमियां यह है कि यह एक अन्य वस्तु है जिसके बारे में अन्य डेवलपर्स को जानना होगा, या यदि आपका आवेदन छोटा है और यह दृष्टिकोण एक एकल क्रमांकन के लिए मायने नहीं रखेगा।

-1
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);

settings.NullValueHandling = NullValueHandling.Ignore अन्य उत्तरों में सुसाइड किया गया है। स्पष्ट नहीं है, आपके उत्तर में नया क्या है
माइकल फ्रीजिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.