2012-02-01 17 views
31

क्रमबद्ध नहीं करेगा मेरे पास एक आमंत्रण लॉगर है जिसका उद्देश्य XmlSerializer का उपयोग करके विधि से जुड़े पैरामीटर के साथ सभी विधि कॉल रिकॉर्ड करना है। यह अधिकांश कॉल के लिए अच्छा काम करता है, लेकिन यह उन सभी विधियों के लिए अपवाद फेंकता है जिनमें IEnumerable प्रकार का पैरामीटर है।XmlSerializer IENumerable

उदाहरण के लिए, void MethodWithPlace(Place value) क्रमबद्ध किया जाएगा, लेकिन void MethodWithPlace(IEnumerable<Place> value) नहीं होगा।

अपवाद

System.NotSupportedException है: क्रमानुसार नहीं कर सकते इंटरफेस System.Collections.Generic.IEnumerable`1 [, संस्करण = 0.0.0.0 [प्लेस, टेस्ट, संस्कृति = तटस्थ]]।

IEnumerable के साथ उन तरीकों के साथ काम करने के लिए मुझे क्या करना चाहिए इसके पैरामीटर में से एक के रूप में?

+2

आप इस तरह की सूची के रूप में IEnumerable का एक ठोस कार्यान्वयन, साथ विधि परिभाषाओं की जगह कर सकते हैं? –

+0

संभव डुप्लिकेट [डब्ल्यूसीएफ, LINQ, JSON] का उपयोग करते समय 'System.Linq.Enumerable ...' के पैरामीटर को क्रमबद्ध नहीं कर सकता है (http://stackoverflow.com/questions/2068897/cannot-serialize-parameter-of-type -सिस्टम-लिनक-एन्यूमेरेबल-कब-उपयोग-डब्ल्यूसीएफ) – Coincoin

+0

[xmlSerializer का उपयोग कर ऑरियल सीरियल ऑब्जेक्ट्स का संभावित डुप्लिकेट।Serialize और IENumerable ऑब्जेक्ट्स] (http://stackoverflow.com/questions/2729875/serialize-objects-using-xmlserializer-serialize-and-ienumerable-objects) –

उत्तर

9

मूल रूप से एक एक्सएमएलएसरियलाइज़र एक इंटरफेस को क्रमबद्ध नहीं कर सकता है। समाधान, फिर, इसे क्रमबद्ध करने के लिए एक ठोस उदाहरण देना है। कैसे अपने मंगलाचरण लकड़हारा काम करता है के आधार पर, मैं का उपयोग कर

var serializer = new XmlSerializer(value.GetType()); 
+0

के लिए विशिष्ट नहीं है हमने कक्षा में सभी संभावित विधि पैरामीटर प्राप्त करने के लिए किया था और उन्हें XmlSerializer के निर्माता में अतिरिक्त प्रकार के रूप में रखा था। फिर, हम उस वर्ग के लिए एक पारदर्शी प्रॉक्सी बनाते हैं, विधि कॉल कैप्चर करते हैं, उन्हें क्रमबद्ध करते हैं, और वास्तविक विधि का आह्वान करते हैं .. – uni

8

मुझे नहीं लगता कि आपको लगता है कि क्रमानुसार करने में सक्षम हो जाएगा पर विचार करेंगे। IENumerable को किसी सूची में कनवर्ट करने का प्रयास करें और फिर आप क्रमबद्ध करने में सक्षम होंगे।

+2

चूंकि मैं विधि हस्ताक्षर बदलने में असमर्थ हूं, क्या कोई ऐसा कामकाज संभवतः इस समस्या को हल कर सकता है? – uni

+2

यदि आप केवल उस विधि हस्ताक्षर में .olist() को जोड़ना चाहते हैं या मुझे यह कहना चाहिए कि यह आईएनम्बरंबर को वापस कर लेता है। टोस्टिस्ट() – MethodMan

+2

क्या आप NetDataContractSerializer की तरह एक अलग धारावाहिक का उपयोग कर सकते हैं? आप एक्सएमएल सीरिएलाइज़र के साथ ऐसा करने में सक्षम नहीं होंगे। – Joe

-1

XmlSerializer इसका समर्थन नहीं करता है। इन प्रकार के क्रमिकरणों के लिए YAXLib आज़माएं।

26

जिस तरह से आप एक IEnumerable संपत्ति को क्रमानुसार एक किराए संपत्ति

[XmlRoot] 
public class Entity { 
    [XmlIgnore] 
    public IEnumerable<Foo> Foo { get; set; } 

    [XmlElement, Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
    public List<Foo> FooSurrogate { get { return Foo.ToList(); } set { Foo = value; } } 
} 

यह बदसूरत है के साथ है, लेकिन यह काम किया जाता है। अच्छा समाधान एक सरोगेट वर्ग (यानी EntitySurrogate) लिखना है।

+1

सरोगेट पर '[ब्राउज़ करने योग्य (झूठा), EditorBrowsable (EditorBrowsableState.Never)] 'को फेंकने से इसे छिपाने में मदद मिलेगी। इसके अलावा, ShouldSerialize * पैटर्न पर विचार करना चाह सकते हैं। [इस उत्तर के समान] (http://stackoverflow.com/a/10840603/425809)। – Richard

3

एक्सएमएल धारावाहिक होने के लिए, आईनेमेरेबल से प्राप्त होने वाले प्रकारों को उनके उत्तराधिकारी पदानुक्रम के सभी स्तरों पर जोड़ें (System.Object) का कार्यान्वयन होना चाहिए। {आपकी कक्षा} Add (System.Object) को लागू नहीं करती है।

जोड़ें() फ़ंक्शन को लागू है, तो आप समस्या का समाधान हो सकता है

-1

आप DataContractSerializer

 using (var ms = new MemoryStream()) 
     { 
      var serialiser = new DataContractSerializer(typeof (EnvironmentMetadata)); 
      serialiser.WriteObject(ms, environmentMetadata); 

      var s = Encoding.ASCII.GetString(ms.ToArray()); 
      return s; 
     } 
+2

प्रश्न एक्सएमएल सीरिएलाइज़र के बारे में था, डेटा अनुबंध धारावाहिक नहीं। –

0

का सबसे अच्छा तरीका हो सकता है कि नहीं उपयोग कर सकते हैं, लेकिन यह मेरे लिए काम किया। मैंने एक विधि बनाई है जो क्रमबद्धता बनाता है।

उपयोग

वर एक्सएमएल = Util.ObjetoToXML (obj, अशक्त, नल) .OuterXml;

विधि

 public static XmlDocument ObjetoToXML(object obj, XmlDocument xmlDocument, XmlNode rootNode) 
    { 

     if (xmlDocument == null) 
      xmlDocument = new XmlDocument(); 

     if (obj == null) return xmlDocument; 

     Type type = obj.GetType(); 

     if (rootNode == null) { 
      rootNode = xmlDocument.CreateElement(string.Empty, type.Name, string.Empty); 
      xmlDocument.AppendChild(rootNode); 
     } 

     if (type.IsPrimitive || type == typeof(Decimal) || type == typeof(String) || type == typeof(DateTime)) 
     { 

      // Simples types 
      if (obj != null) 
       rootNode.InnerText = obj.ToString(); 

     } 
     else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) 
     { 
      // Genericis types 

      XmlNode node = null; 

      foreach (var item in (IEnumerable)obj) 
      { 
       if (node == null) 
       { 
        node = xmlDocument.CreateElement(string.Empty, item.GetType().Name, string.Empty); 
        node = rootNode.AppendChild(node); 
       } 


       ObjetoToXML(item, xmlDocument, node); 
      } 

     } 
     else 
     { 

      // Classes types 
      foreach (var propertie in obj.GetType().GetProperties()) 
      { 

       XmlNode node = xmlDocument.CreateElement(string.Empty, propertie.Name, string.Empty); 
       node = rootNode.AppendChild(node); 
       var valor = propertie.GetValue(obj, null); 

       ObjetoToXML(valor, xmlDocument, node); 
      } 

     } 


     return xmlDocument; 

    }