2011-09-21 15 views
19

को क्रमानुसार मैं निम्न स्वरूप पर वस्तुओं से डायनामिक रूप से तैयार एक्सएमएल नोड्स का एक सेट का निर्माण करने की जरूरत है:एक्सएमएल गतिशील वस्तु

<Root> 
    <Name>My Name</Name> 
    <DynamicValues> 
     <DynamicValue1>Value 1</DynamicValue1> 
     <DynamicValue2>Value 2</DynamicValue2> 
    </DynamicValues> 
</Root> 

DynamicValues -tag भीतर नोड्स के नाम पहले से ज्ञात नहीं हैं। मेरे प्रारंभिक सोचा था कि यह एक Expando Object, जैसे का उपयोग कर संभव हो जाना चाहिए: यह XML-क्रमानुसार

var root = new Root 
        { 
         Name = "My Name", 
         DynamicValues = new ExpandoObject() 
        }; 

root.DynamicValues.DynamicValue1 = "Value 1"; 
root.DynamicValues.DynamicValue2 = "Value 2"; 

और उसके बाद:

string xmlString; 

var serializer = new DataContractSerializer(root.GetType()); 
using (var backing = new StringWriter()) 
using (var writer = new XmlTextWriter(backing)) 
{ 
    serializer.WriteObject(writer, root); 
    xmlString = backing.ToString(); 
} 

मूल्यों के साथ यह आरंभ से

[DataContract] 
public class Root 
{ 
    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public dynamic DynamicValues { get; set; } 
} 

हालांकि, जब मैं इसे चलाता हूं, मुझे एक सीरियलाइजेशन एक्सेप्शन मिलता है:

"प्रकार डेटा अनुबंध नाम साथ 'System.Dynamic.ExpandoObject' 'ArrayOfKeyValueOfstringanyType: http://schemas.microsoft.com/2003/10/Serialization/Arrays' की उम्मीद नहीं है।

, KnownTypeAttribute विशेषता का उपयोग करके या उन्हें DataContractSerializer के लिए पारित किया जाना जाता है प्रकार के सूची में जोड़ने से उदाहरण के लिए "- एक DataContractResolver उपयोग पर विचार करें या किसी प्रकार नहीं जाना जाता है प्रकार की सूची को स्थिर में जाना जाता है जोड़ें। कोई भी विचार मैं यह कैसे प्राप्त कर सकते हैं

उत्तर

24
[Serializable] 
public class DynamicSerializable : DynamicObject, ISerializable 
{ 
    private readonly Dictionary<string, object> dictionary = new Dictionary<string, object>(); 

    public override bool TrySetMember(SetMemberBinder binder, object value) 
    { 
     dictionary[binder.Name] = value; 

     return true; 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     foreach (var kvp in dictionary) 
     { 
      info.AddValue(kvp.Key, kvp.Value); 
     } 
    } 
} 

[KnownType(typeof(DynamicSerializable))] 
[DataContract] 
public class Root 
{ 
    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public dynamic DynamicValues { get; set; } 
} 

आउटपुट:?

<Program.Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http:// 
schemas.datacontract.org/2004/07/"> 
    <DynamicValues i:type="Program.DynamicSerializable"> 
    <DynamicValue1 xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:st 
ring" xmlns="">Value 1</DynamicValue1> 
    <DynamicValue2 xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:st 
ring" xmlns="">Value 2</DynamicValue2> 
    </DynamicValues> 
    <Name>My Name</Name> 
</Program.Root> 
+0

यह वास्तव में क्रमानुसार करता अपवाद फेंकने के बिना, लेकिन में मेरी अपेक्षा के अनुसार (प्रश्न में उदाहरण एक्सएमएल देखें)। मुझे 'KeyValueOfstringanyType' प्रकार के नोड्स मिलते हैं। –

+0

@ ओलावहॉगेन, मैंने अपना जवाब अपडेट कर लिया है। –

+1

महान काम करता है। धन्यवाद! –

0

में यह कोशिश की vb.netbut आवश्यक आउटपुट नहीं मिला था। सहायता चाहिए।

_ सार्वजनिक कक्षा DynamicSerializable विरासत में मिली System.Dynamic.DynamicObject इम्प्लीमेन्ट्स ISerializable

Private ReadOnly dict As New Dictionary(Of String, Object) 

Public Overrides Function TrySetMember(binder As SetMemberBinder, value As Object) As Boolean 
    If Not dict.ContainsKey(binder.Name) Then 
     dict.Add(binder.Name, value) 
    Else 
     dict(binder.Name) = value 
    End If 
    Return True 
End Function 

Public Overrides Function TryGetMember(binder As GetMemberBinder, ByRef result As Object) As Boolean 
    Return dict.TryGetValue(binder.Name, result) 
End Function 

Public Sub GetObjectData(info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData 
    For Each keyValPair In dict 
     info.AddValue(keyValPair.Key, keyValPair.Value) 
    Next 
End Sub 

समाप्ति कक्षा

कोड का प्रयोग किया:

मंद जड़ नए रूट root.name के रूप में = " 1 " रूट। डायनामिक वैल्यूज = नया डायनामिक सर्जिकिज़ेबल

root.DynamicValues.DynamicValue1 = "Value1" 
    root.DynamicValues.DynamicValue2 = "Value1" 

    Dim serializer = New DataContractSerializer(Root.GetType) 
    Dim backing As New StringWriter 
    Dim writer As New XmlTextWriter(backing) 
    serializer.WriteObject(writer, Root) 

आउटपुट:

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