XML Serialize dynamic object
[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; }
}
Output:
<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>
Olav Haugen
Coding C# for food. Nerd is my middle name. Twitter Updates Blog
Updated on June 01, 2022Comments
-
Olav Haugen about 2 years
I need to construct a set of dynamically created XML nodes from objects on the following format:
<Root> <Name>My Name</Name> <DynamicValues> <DynamicValue1>Value 1</DynamicValue1> <DynamicValue2>Value 2</DynamicValue2> </DynamicValues> </Root>
The name of the nodes within the
DynamicValues
-tag are not known in advance. My initial thought was that this should be possible using an Expando Object, e.g:[DataContract] public class Root { [DataMember] public string Name { get; set; } [DataMember] public dynamic DynamicValues { get; set; } }
by initializing it with the values:
var root = new Root { Name = "My Name", DynamicValues = new ExpandoObject() }; root.DynamicValues.DynamicValue1 = "Value 1"; root.DynamicValues.DynamicValue2 = "Value 2";
and then Xml-serialize it:
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(); }
However, when I run this, I get an SerializationException saying:
"Type 'System.Dynamic.ExpandoObject' with data contract name 'ArrayOfKeyValueOfstringanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer."
Any ideas how I can achieve this?
-
Olav Haugen almost 13 yearsIt does indeed serialize without throwing exceptions, but not into what I expected (see example XML in question). I get nodes of the type
KeyValueOfstringanyType
.