XML 序列化动态对象 [英] XML Serialize dynamic object
问题描述
我需要从以下格式的对象构建一组动态创建的 XML 节点:
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>
DynamicValues
标签中的节点名称事先未知.我最初的想法是使用 Expando Object,例如:
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";
然后Xml序列化它:
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();
}
然而,当我运行这个时,我得到一个 SerializationException 说:
However, when I run this, I get an SerializationException saying:
"使用数据协定名称键入System.Dynamic.ExpandoObject"'ArrayOfKeyValueOfstringanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays'不是预期的.考虑使用 DataContractResolver 或添加任何已知类型列表中静态未知的类型 - 例如,通过使用KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表."
"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?
推荐答案
[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>
这篇关于XML 序列化动态对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!