2012-07-03 11 views
5

मैं पुस्तकालय ServiceStack.Text के साथ ऑब्जेक्ट्स को क्रमबद्ध करने की कोशिश कर रहा हूं। यह काम करता हैसर्विसस्टैक के साथ ExpandoObject Serializing.Text

using System.Dynamic; 
using ServiceStack.Text; 
var x = new {Value= 10, Product = "Apples"};     
Console.WriteLine(JsonSerializer.SerializeToString(x)); 

मैं मिलता है, मैं उम्मीद के रूप में

{"Value":10,"Product":"Apples"} 

हालांकि

dynamic x = new ExpandoObject(); 
x.Value = 100; 
x.Product = "Apples"; 
Console.WriteLine(JsonSerializer.SerializeToString(x)); 

मैं मेरे आश्चर्य

[{"Key":"Value","Value":100},{"Key":"Product","Value":"Apples"}] 

क्यों! क्या चल रहा है?

दूसरा, मैं जो चाहता हूं उसे कैसे प्राप्त कर सकता हूं?

+0

ऐसा लगता है कि धारावाहिक आपके डेटा संरचना को गलत समझ रहा है ... क्या आप संरचना पोस्ट कर सकते हैं? –

+0

यदि आप ServiceStack स्थापित करते हैं। टेक्स्ट आप ऊपर अपना कोड चलाने में सक्षम होना चाहिए (उपयोग कथन दोहराएं)। –

उत्तर

5

ExpandoObject लागू करता है IConnection<KeyValuePair> और IEnumerable<KeyValuePair>:

public sealed class ExpandoObject : 
    IDynamicMetaObjectProvider, 
    IDictionary<string, object>, 
    ICollection<KeyValuePair<string, object>>, 
    IEnumerable<KeyValuePair<string, object>>, 
    IEnumerable, INotifyPropertyChanged 

मेरा अनुमान है कि आंतरिक रूप से, ServiceStack serializer एक IEnumerable<KeyValuePair> रूप ExpandoObject इलाज है, और इसलिए यह कुंजी/मान जोड़े की एक JSON सारणी को serializes।


यह आपका पहला (कार्य) कोड स्निपेट से भिन्न है क्योंकि नेट वास्तव में आपके डेटा के लिए एक असली (अनाम) वर्ग बनाता है, मूल रूप से यह बनाता है:

public class SomeNameTheCompilerMakesUp { 
    internal int Value { get; set; } 
    internal string Product { get; set; } 
} 
आप के लिए

स्वचालित रूप से है, इसलिए जब यह धारावाहिक को भेजा जाता है, यह वास्तविक गुणों के साथ एक असली कक्षा के साथ काम कर रहा है, जबकि ExpandoObject वास्तव में object[] आंतरिक रूप से समर्थित है।


अतिरिक्त नोट पर, माइक्रोसॉफ्ट के System.Web.Helpers.Json उसी तरह व्यवहार करता है। इस परीक्षण से गुजरता है:

[TestMethod] 
    public void ExpandoObjectSerializesToJsonArray() 
    { 
     dynamic anonType = new { Value = 10, Product = "Apples" }; 

     dynamic expando = new ExpandoObject(); 
     expando.Value = 10; 
     expando.Product = "Apples"; 

     var anonResult = System.Web.Helpers.Json.Encode(anonType); 
     var expandoResult = System.Web.Helpers.Json.Encode(expando); 

     Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", anonResult); 
     Assert.AreEqual("[{\"Key\":\"Value\",\"Value\":10},{\"Key\":\"Product\",\"Value\":\"Apples\"}]", expandoResult); 
    } 

एक अंतिम संपादित करें:

आप एक Dictionary<string, object> में अपने ExpandoObject बदल कर यह काम जिस तरह से आप चाहते हैं कर सकते हैं। इस कोड की चेतावनी यह है कि यह डेटा को एक शब्दकोश में डुप्लिकेट करता है, इसलिए आपके पास स्मृति में 2 प्रतियां होती हैं (या तकनीकी रूप से स्ट्रिंग को इंटर्न किया जा सकता है) से थोड़ा कम है।

[TestMethod] 
    public void TestMethod1() 
    { 
     dynamic expando = new ExpandoObject(); 
     expando.Value = 10; 
     expando.Product = "Apples"; 

     // copy expando properties to dictionary 
     var dictionary = ((ExpandoObject)expando).ToDictionary(x => x.Key, x => x.Value); 

     var expandoResult = System.Web.Helpers.Json.Encode(expando); 
     var dictionaryResult = System.Web.Helpers.Json.Encode(dictionary); 

     Assert.AreEqual("[{\"Key\":\"Value\",\"Value\":10},{\"Key\":\"Product\",\"Value\":\"Apples\"}]", expandoResult); 
     Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", dictionaryResult); 
    } 

हालांकि, किसी को भी कि यह बाद में भर आता है, और वास्तव में System.Web.Helpers.Json उपयोग कर रहा है के लिए, ऐसा करने के लिए बेहतर बात सिर्फ लपेट कर रहा है अपने ExpandoObject एक DynamicJsonObject इस तरह में:

[TestMethod] 
    public void TestMethod1() 
    { 
     dynamic expando = new ExpandoObject(); 
     expando.Value = 10; 
     expando.Product = "Apples"; 

     var dictionaryResult = System.Web.Helpers.Json.Encode(new DynamicJsonObject(expando)); 

     Assert.AreEqual("{\"Value\":10,\"Product\":\"Apples\"}", dictionaryResult); 
    } 

उत्तर: एक बार मैं काम किया इसके माध्यम से, मुझे यहां एक समान प्रश्न मिला: How to flatten an ExpandoObject returned via JsonResult in asp.net mvc?

+0

धन्यवाद रैली, यह समझ में आता है। कोई विचार है कि मैं जिस तरह से चाहता हूं Exp ExpObject serialize कर सकते हैं? –

+0

दुर्भाग्यवश, नहीं, मैं नहीं करता हूं। मैंने 'System.Web.Helpers.Json' को आज़माने की कोशिश की कि यह आपके इच्छित तरीके से काम करेगा, और एक विकल्प के रूप में प्रस्तावित करने जा रहा था, लेकिन यह वही काम करता है। :) – CodingWithSpike

+0

@ मैटहिकफोर्ड - मेरी पिछली टिप्पणी खरोंच। मैंने अपने उत्तर के अंत में एक संभावित समाधान जोड़ा। – CodingWithSpike

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