2013-08-31 10 views
34

Json.NET सीरिएलाइज़र का उपयोग कर केवल-केवल गुणों को अनदेखा करने का कोई तरीका है लेकिन JsonIgnore विशेषताओं का उपयोग किए बिना?क्या Json.Ngnore विशेषताओं का उपयोग किये बिना Json.NET में केवल-प्राप्त गुणों को अनदेखा करने का कोई तरीका है?

उदाहरण के लिए, मैं इन के साथ एक वर्ग है पाने के गुण:

public Keys Hotkey { get; set; } 

    public Keys KeyCode 
    { 
     get 
     { 
      return Hotkey & Keys.KeyCode; 
     } 
    } 

    public Keys ModifiersKeys 
    { 
     get 
     { 
      return Hotkey & Keys.Modifiers; 
     } 
    } 

    public bool Control 
    { 
     get 
     { 
      return (Hotkey & Keys.Control) == Keys.Control; 
     } 
    } 

    public bool Shift 
    { 
     get 
     { 
      return (Hotkey & Keys.Shift) == Keys.Shift; 
     } 
    } 

    public bool Alt 
    { 
     get 
     { 
      return (Hotkey & Keys.Alt) == Keys.Alt; 
     } 
    } 

    public Modifiers ModifiersEnum 
    { 
     get 
     { 
      Modifiers modifiers = Modifiers.None; 

      if (Alt) modifiers |= Modifiers.Alt; 
      if (Control) modifiers |= Modifiers.Control; 
      if (Shift) modifiers |= Modifiers.Shift; 

      return modifiers; 
     } 
    } 

    public bool IsOnlyModifiers 
    { 
     get 
     { 
      return KeyCode == Keys.ControlKey || KeyCode == Keys.ShiftKey || KeyCode == Keys.Menu; 
     } 
    } 

    public bool IsValidKey 
    { 
     get 
     { 
      return KeyCode != Keys.None && !IsOnlyModifiers; 
     } 
    } 

मैं उन सभी को [JsonIgnore] जोड़ने के लिए (मैं भी कई अन्य वर्गों के लिए) की जरूरत है, या वहाँ सब की अनदेखी करने का इससे बेहतर तरीका है क्या केवल गुण प्राप्त करें?

उत्तर

53

आप एक कस्टम IContractResolver लागू करने और का उपयोग कर कि क्रमबद्धता के दौरान ऐसा कर सकते हैं। आप DefaultContractResolver उपवर्ग हैं, तो यह करने के लिए बहुत आसान हो जाता है:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Serialization; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Widget w = new Widget { Id = 2, Name = "Joe Schmoe" }; 

     JsonSerializerSettings settings = new JsonSerializerSettings 
     { 
      ContractResolver = new WritablePropertiesOnlyResolver() 
     }; 

     string json = JsonConvert.SerializeObject(w, settings); 

     Console.WriteLine(json); 
    } 
} 

class Widget 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string LowerCaseName 
    { 
     get { return (Name != null ? Name.ToLower() : null); } 
    } 
} 

यहाँ ऊपर के उत्पादन में है:

class WritablePropertiesOnlyResolver : DefaultContractResolver 
{ 
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     IList<JsonProperty> props = base.CreateProperties(type, memberSerialization); 
     return props.Where(p => p.Writable).ToList(); 
    } 
} 

यहाँ एक परीक्षण कार्यक्रम है कि यह कैसे उपयोग करने के लिए प्रदर्शन है। ध्यान दें कि केवल पढ़ने योग्य संपत्ति LowerCaseName आउटपुट में शामिल नहीं है।

{"Id":2,"Name":"Joe Schmoe"} 
+0

एसईटी के बिना केवल संपत्तियों को अनदेखा करने के बारे में कैसे? और अभी भी सार्वजनिक स्ट्रिंग जैसे निजी सेट होने पर क्रमबद्ध करें नाम {प्राप्त करें; निजी सेट; }? –

12

JSON.net के ऑप्टिन मोड का उपयोग करें और आपको केवल उन्हीं गुणों को सजाने की आवश्यकता होगी जिन्हें आप क्रमबद्ध करना चाहते हैं। यह स्वचालित रूप से सभी पढ़ने वाले गुणों को स्वचालित रूप से चुनने के समान नहीं है, लेकिन यह आपको कुछ काम बचा सकता है।

[JsonObject(MemberSerialization.OptIn)] 
public class MyClass 
{ 
    [JsonProperty] 
    public string serializedProp { get; set; } 

    public string nonSerializedProp { get; set; } 
} 

Udate: प्रतिबिंब

का उपयोग कर एक और संभावना जोड़ा ऊपर समाधान अभी भी नहीं है आप, के लिए आप वस्तुओं जो तब धारावाहिक की जाएगी शब्दकोश बनाने के लिए इस्तेमाल कर सकते हैं प्रतिबिंब काफी क्या देख रहे हैं। बेशक नीचे दिया गया उदाहरण केवल साधारण वर्गों के लिए काम करेगा, इसलिए यदि आपकी कक्षाओं में अन्य कक्षाएं हों तो आपको रिकर्सन जोड़ने की आवश्यकता होगी। यह आपको कम से कम सही दिशा में इंगित करना चाहिए।

सबरूटीन एक शब्दकोश में फ़िल्टर परिणाम डाल करने के लिए:

private Dictionary<String, object> ConvertToDictionary(object classToSerialize) 
    { 
     Dictionary<String, object> resultDictionary = new Dictionary<string, object>(); 

     foreach (var propertyInfo in classToSerialize.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
     { 
      if (propertyInfo.CanWrite) resultDictionary.Add(propertyInfo.Name, propertyInfo.GetValue(classToSerialize, null)); 
     } 

     return resultDictionary; 
    } 

एक टुकड़ा इसके उपयोग दिखा:

SampleClass sampleClass = new SampleClass(); 
sampleClass.Hotkey = Keys.A; 
var toSerialize = ConvertToDictionary(sampleClass); 
String resultText = JsonConvert.SerializeObject(toSerialize); 
7

आप इस प्रकार का अनुबंध समाधानकर्ता का उपयोग कर सकते हैं:

public class ExcludeCalculatedResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     var property = base.CreateProperty(member, memberSerialization); 
     property.ShouldSerialize = _ => ShouldSerialize(member); 
     return property; 
    } 

    internal static bool ShouldSerialize(MemberInfo memberInfo) 
    { 
     var propertyInfo = memberInfo as PropertyInfo; 
     if (propertyInfo == null) 
     { 
      return false; 
     } 

     if (propertyInfo.SetMethod != null) 
     { 
      return true; 
     } 

     var getMethod = propertyInfo.GetMethod; 
     return Attribute.GetCustomAttribute(getMethod, typeof(CompilerGeneratedAttribute)) != null; 
    } 
} 

यह गणना की संपत्तियों को बाहर लेकिन सी # 6 में शामिल हैं केवल गुणों और एक सेट विधि के साथ सभी गुण मिल जाएगा।

4

Json.net में एक विशेषता या अनुबंध समाधान के बिना सशर्त रूप से गुणों को क्रमबद्ध करने की क्षमता है। यह विशेष रूप से उपयोगी है अगर आप नहीं चाहते कि आपकी परियोजना Json.net पर निर्भरता हो।

Json.net documentation

अनुसार सशर्त एक संपत्ति को क्रमानुसार करने के लिए, एक विधि है कि संपत्ति के रूप में साथ बूलियन रिटर्न एक ही नाम जोड़ने और फिर ShouldSerialize साथ विधि नाम लगा दें।विधि का परिणाम यह निर्धारित करता है कि संपत्ति क्रमबद्ध है या नहीं। यदि विधि सही हो जाती है तो संपत्ति को क्रमबद्ध किया जाएगा, यदि यह झूठा लौटाता है तो संपत्ति छोड़ी जाएगी।

संबंधित मुद्दे

 संबंधित मुद्दे