c# - XML 序列化动态对象

标签 c# .net xml serialization dynamic

我需要从以下格式的对象构造一组动态创建的 XML 节点:

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

DynamicValues 标签中节点的名称是事先不知道的。我最初的想法是这应该可以使用 Expando Object ,例如:

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

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

通过使用值初始化它:

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 说:

"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."

有什么办法可以实现吗?

最佳答案

[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>

关于c# - XML 序列化动态对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7501846/

相关文章:

c# - 嵌套类 .GetType()

c# - 如何使用 EntityFramework 4.1 CodeFirst 防止小数值在保存时被截断为 2 个位置?

c# - 在同一行有多个工具条

.net - 作为 wpf 应用程序实现的 winforms 应用程序示例?

Java RegEx 匹配器会破坏 BMP 之外的字符

c# - 用电话线发送文件

.net - 什么是一流的 .NET 语言?

c# - 如何让 CLR 知道从 GAC 选择哪个程序集?

java - 在 SQLite 中存储数组列表的数组列表

java - 如何在android中延迟后显示按钮文本