【问题标题】:XML Serialize dynamic objectXML序列化动态对象
【发布时间】:2011-11-22 01:03:42
【问题描述】:

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

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

DynamicValues-tag 中的节点名称事先不知道。我最初的想法是,这应该可以使用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 说:

"使用数据合约名称键入“System.Dynamic.ExpandoObject” 'ArrayOfKeyValueOfstringanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays' 预计不会。考虑使用 DataContractResolver 或添加任何 已知类型列表中静态未知的类型 - 例如, 通过使用 KnownTypeAttribute 属性或将它们添加到 传递给 DataContractSerializer 的已知类型列表。”

有什么想法可以实现吗?

【问题讨论】:

    标签: c# .net xml serialization dynamic


    【解决方案1】:
    [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)。我得到KeyValueOfstringanyType 类型的节点。
    猜你喜欢
    • 2011-03-04
    • 2018-05-25
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多