2011-07-26 8 views
6

मैं किसी ऑब्जेक्ट को deserialize करने के लिए JSON.net का उपयोग करना चाहता हूं लेकिन एक शब्दकोश प्रॉपर्टी में अप्रयुक्त गुण डाल सकता हूं। क्या यह संभव है?सभी शब्दकोष संपत्ति पकड़ने के साथ जेसन को किसी ऑब्जेक्ट पर सीरियलाइज़ करें

json दिया उदाहरण के लिए,

{one:1,two:2,three:3} 

और ग # वर्ग:

public class Mapped { 
    public int One {get; set;} 
    public int Two {get; set;} 
    public Dictionary<string,object> TheRest {get; set;} 
} 

JSON.NET मूल्यों के साथ एक उदाहरण के लिए deserialize कर सकते हैं एक = 1, दो = 1, therest = शब्दकोश {{"तीन, 3}}

+0

मेरा उत्तर में कोड अपडेट किया गया यह अधिक सामान्य बनाने के लिए। –

उत्तर

2

आप जो करना चाहते हैं उसे करने के लिए आप CustomCreationConverter बना सकते हैं। यहां एक नमूना है (बल्कि बदसूरत है, लेकिन यह दर्शाता है कि आप इसके बारे में कैसे जाना चाहते हैं):

namespace JsonConverterTest1 
{ 
    public class Mapped 
    { 
     private Dictionary<string, object> _theRest = new Dictionary<string, object>(); 
     public int One { get; set; } 
     public int Two { get; set; } 
     public Dictionary<string, object> TheRest { get { return _theRest; } } 
    } 

    public class MappedConverter : CustomCreationConverter<Mapped> 
    { 
     public override Mapped Create(Type objectType) 
     { 
      return new Mapped(); 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      var mappedObj = new Mapped(); 
      var objProps = objectType.GetProperties().Select(p => p.Name.ToLower()).ToArray(); 

      //return base.ReadJson(reader, objectType, existingValue, serializer); 
      while (reader.Read()) 
      { 
       if (reader.TokenType == JsonToken.PropertyName) 
       { 
        string readerValue = reader.Value.ToString().ToLower(); 
        if (reader.Read()) 
        { 
         if (objProps.Contains(readerValue)) 
         { 
          PropertyInfo pi = mappedObj.GetType().GetProperty(readerValue, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); 
          var convertedValue = Convert.ChangeType(reader.Value, pi.PropertyType); 
          pi.SetValue(mappedObj, convertedValue, null); 
         } 
         else 
         { 
          mappedObj.TheRest.Add(readerValue, reader.Value); 
         } 
        } 
       } 
      } 
      return mappedObj; 
     } 
    } 

    public class Program 
    { 
     static void Main(string[] args) 
     { 
      string json = "{'one':1, 'two':2, 'three':3, 'four':4}"; 

      Mapped mappedObj = JsonConvert.DeserializeObject<Mapped>(json, new MappedConverter()); 

      Console.WriteLine(mappedObj.TheRest["three"].ToString()); 
      Console.WriteLine(mappedObj.TheRest["four"].ToString()); 
     } 
    } 
} 

तो mappedObj के उत्पादन के बाद आप deserialize JSON स्ट्रिंग आबादी अपनी One और Two गुणों के साथ एक वस्तु हो जाएगा, और सब कुछ किसी और Dictionary में डाल दिया। अनुमोदित, मैंने एक और दो मानों को int के रूप में हार्ड-कोड किया, लेकिन मुझे लगता है कि यह दर्शाता है कि आप इसके बारे में कैसे जाएंगे।

मुझे उम्मीद है कि इससे मदद मिलती है।

संपादित करें: मैंने इसे अधिक सामान्य बनाने के लिए कोड अपडेट किया। मैंने पूरी तरह से इसका परीक्षण नहीं किया, इसलिए कुछ मामलों में यह असफल हो सकता है, लेकिन मुझे लगता है कि यह आपको वहां से अधिकतर तरीके से प्राप्त करता है।

+0

डेविड जो एक महान है, लेकिन मैं एक और सामान्य समाधान की उम्मीद कर रहा था। – PhilHoy

+0

हाँ, मैंने इसे एक साथ जल्दी से रखा है। मैं अभी इस पर वापस नहीं आ सकता, लेकिन मैं इसे थोड़ा और सामान्य बना दूंगा। इसमें शायद थोड़ा प्रतिबिंब शामिल होगा। हालांकि, बुनियादी संरचना नहीं बदलेगी - बस दूसरे 'अगर (पाठक। पढ़ें())' ब्लॉक में तर्क। लेकिन उम्मीद है कि आप देख सकते हैं कि मैं इसके साथ कहां जा रहा हूं। बीटीडब्ल्यू, आपने पूछा कि बहुत अच्छा सवाल है। –

+0

विभिन्न संपत्ति नामों और/या प्रकारों के लिए इसे अधिक सामान्य बनाने के लिए कोड अपडेट किया गया। –

1

ऐसा करने का सबसे आसान तरीका JsonExtensionData विशेषता का उपयोग सभी शब्दकोश को पकड़ने के लिए करना है। the Json.Net documentation से

उदाहरण:

public class DirectoryAccount 
{ 
    // normal deserialization 
    public string DisplayName { get; set; } 

    // these properties are set in OnDeserialized 
    public string UserName { get; set; } 
    public string Domain { get; set; } 

    [JsonExtensionData] 
    private IDictionary<string, JToken> _additionalData; 

    [OnDeserialized] 
    private void OnDeserialized(StreamingContext context) 
    { 
     // SAMAccountName is not deserialized to any property 
     // and so it is added to the extension data dictionary 
     string samAccountName = (string)_additionalData["SAMAccountName"]; 

     Domain = samAccountName.Split('\\')[0]; 
     UserName = samAccountName.Split('\\')[1]; 
    } 

    public DirectoryAccount() 
    { 
     _additionalData = new Dictionary<string, JToken>(); 
    } 
} 

string json = @"{ 
    'DisplayName': 'John Smith', 
    'SAMAccountName': 'contoso\\johns' 
}"; 

DirectoryAccount account = JsonConvert.DeserializeObject<DirectoryAccount>(json); 

Console.WriteLine(account.DisplayName); 
// John Smith 

Console.WriteLine(account.Domain); 
// contoso 

Console.WriteLine(account.UserName); 
// johns 
संबंधित मुद्दे