2011-10-01 6 views
6

पढ़ते समय विफल रहता है मैं सदस्य का उपयोग कर रहा हूं जिसमें [DataMember()] के साथ चिह्नित किसी ऑब्जेक्ट को क्रमबद्ध करने के लिए DataContractSerializer का उपयोग कर रहा हूं। विचार वस्तु गुणों का एक लचीला बैग होना है, और मुझे नहीं पता कि वे गुण क्या हो सकते हैं।DataContractSerializer और Dictionary <string, object>

यह महान काम करता है जब मैं शब्दकोश में int, double और string वस्तुओं डाल रहा हूं, लेकिन जब मैं उस में एक List<string> डाल के साथ वस्तु deserialize करने में विफल रहता:

System.InvalidOperationException: Node type Element is not supported in this operation. 

पूरे शब्दकोश में धारावाहिक है XML, और यह बहुत उचित दिखता है:

<Attributes xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
    <d2p1:KeyValueOfstringanyType> 
     <d2p1:Key>name</d2p1:Key> 
     <d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">Test object</d2p1:Value> 
    </d2p1:KeyValueOfstringanyType> 
    <d2p1:KeyValueOfstringanyType> 
     <d2p1:Key>x</d2p1:Key> 
     <d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">0.5</d2p1:Value> 
    </d2p1:KeyValueOfstringanyType> 
    <d2p1:KeyValueOfstringanyType> 
     <d2p1:Key>y</d2p1:Key> 
     <d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">1.25</d2p1:Value> 
    </d2p1:KeyValueOfstringanyType> 
    <d2p1:KeyValueOfstringanyType> 
     <d2p1:Key>age</d2p1:Key> 
     <d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">4</d2p1:Value> 
    </d2p1:KeyValueOfstringanyType> 
    <d2p1:KeyValueOfstringanyType> 
     <d2p1:Key>list-of-strings</d2p1:Key> 
     <d2p1:Value> 
      <d2p1:string>one string</d2p1:string> 
      <d2p1:string>two string</d2p1:string> 
      <d2p1:string>last string</d2p1:string> 
     </d2p1:Value> 
    </d2p1:KeyValueOfstringanyType> 
</Attributes> 

नोट वहाँ अंत में list-of-strings। इसे सभी मान मिल गए हैं लेकिन कुछ भी यह इंगित नहीं करता कि यह List<string> या कुछ भी है।

इस स्थिति को संभालने का सही तरीका क्या है?

उत्तर

8

KnownTypeAttribute का उपयोग करने का प्रयास करें ताकि DataContractSerializerList<string> प्रकार के बारे में पता है। दुर्भाग्यवश, ऐसा लगता है कि हाथ से पहले के प्रकारों के बारे में नहीं जानना आपके विचार के खिलाफ है।

मैं निम्नलिखित कोड है, जो DataContractSerializer का उपयोग करता क्रमानुसार करने एक Dictionary<string, object> युक्त List<string> पर इस आधारित हूँ:

Dictionary<string,object> dictionary = new Dictionary<string, object>(); 

dictionary.Add("k1", new List<string> { "L1", "L2", "L3" }); 

List<Type> knownTypes = new List<Type> { typeof(List<string>) }; 
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string,object>), knownTypes); 
MemoryStream stream = new MemoryStream(); 

serializer.WriteObject(stream, dictionary); 

StreamReader reader = new StreamReader(stream); 

stream.Position = 0; 
string xml = reader.ReadToEnd(); 

आप knownTypesDataContractSerializer को प्रदान नहीं की है, तो यह एक अपवाद फेंकता है।

SerializationException: प्रकार 'System.Collections.Generic.List`1 [[System.String, mscorlib, संस्करण = 4.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = b77a5c561934e089]]' साथ डेटा अनुबंध नाम 'ऐरेऑफस्ट्रिंग: http: //schemas.microsoft.com/2003/10/Serialization/Arrays' अपेक्षित नहीं है। DataContractResolver का उपयोग करने पर विचार करें या किसी भी प्रकारों को ज्ञात प्रकारों की सूची में स्थिर रूप से ज्ञात नहीं है - उदाहरण के लिए, KnownTypeAttribute विशेषता का उपयोग करके या उन्हें डेटाकंट्रैक्टसेरियलाइज़र को ज्ञात ज्ञात प्रकारों की सूची में जोड़कर जोड़ें। (: प्रकार विशेषता i) नोटिस कि अन्य सभी <Value> तत्वों एक "प्रकार संकेत" है -

0

WCF जानते हुए भी कि तुम्हारे पास क्या है एक List<string> है का कोई रास्ता नहीं है। यदि आप इसे deserialize करना चाहते हैं, तो इसे चिह्नित करने की आवश्यकता है, और आपको डब्ल्यूसीएफ को यह भी बताना होगा कि List<string> एक "ज्ञात प्रकार" है - नीचे देखें। ज्ञात प्रकारों (और उनकी आवश्यकता क्यों है) के बारे में अधिक जानकारी के लिए web में manygoodresources हैं।

public class StackOverflow_7620718 
{ 
    public static void Test() 
    { 
     Dictionary<string, object> dict = new Dictionary<string, object> 
     { 
      { "name", "Test object" }, 
      { "x", 0.5 }, 
      { "y", 1.25 }, 
      { "age", 4 }, 
      { "list-of-strings", new List<string> { "one string", "two string", "last string" } } 
     }; 
     MemoryStream ms = new MemoryStream(); 
     XmlWriter w = XmlWriter.Create(ms, new XmlWriterSettings 
     { 
      Indent = true, 
      Encoding = new UTF8Encoding(false), 
      IndentChars = " ", 
      OmitXmlDeclaration = true, 
     }); 
     DataContractSerializer dcs = new DataContractSerializer(dict.GetType(), new Type[] { typeof(List<string>) }); 
     dcs.WriteObject(w, dict); 
     w.Flush(); 
     Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); 
     ms.Position = 0; 
     Console.WriteLine("Now deserializing it:"); 
     Dictionary<string, object> dict2 = (Dictionary<string, object>)dcs.ReadObject(ms); 
     foreach (var key in dict2.Keys) 
     { 
      Console.WriteLine("{0}: {1}", key, dict2[key].GetType().Name); 
     } 
    } 
} 
संबंधित मुद्दे