【问题标题】:DataContractSerializer - How to serialize objects using ElementName instead of property name?DataContractSerializer - 如何使用 ElementName 而不是属性名称来序列化对象?
【发布时间】:2018-08-03 14:08:13
【问题描述】:

我在使用DataContractSerializer 时遇到了序列化问题。我面临的问题是生成的 XML 文件始终具有为类和字段定义名称的标签,而不是使用 ElementName 属性在 XmlRootXmlElement 中设置的名称。例如对于定义如下的类:

[XmlRoot(ElementName = "customer")]
public class Customer
{
    [XmlElement(ElementName = "name")]
    public string Name { get; set; }
    [XmlElement(ElementName = "address")]
    public string Address { get; set; }
}

在我的例子中生成的 XML 总是:

<Customer>
    <Name>abc</Name>
    <Address>xyz</Address>
</Customer>

虽然我希望得到的输出是使用小写 ElementName 的输出:

<customer>
    <name>abc</name>
    <address>xyz</address>
</customer>

我正在使用扩展方法通过 C# 对象使用以下方法进行序列化:

public static XDocument SerializeToXElement(object o)
{
    XDocument doc = new XDocument();

    using (var writer = doc.CreateWriter())
    {
        var serializer = new DataContractSerializer(o.GetType());
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        serializer.WriteObject(writer, o);
    }

    doc.StripNamespace();

    return doc;
}

我还在我的序列化函数中调用了另一个扩展方法,以从我的XDocument 中剥离命名空间,如下所示:

public static void StripNamespace(this XDocument document)
{
    if (document.Root == null) return;

    foreach (var element in document.Root.DescendantsAndSelf())
    {
        element.Name = element.Name.LocalName;
        element.ReplaceAttributes(GetAttributesWithoutNamespace(element));
    }
}

如何使 DataContractSerializer 使用 ElementName 而不是类/属性名称?

【问题讨论】:

  • 也许您应该使用 DataContract 和 DataMember 属性?见docs.microsoft.com/en-us/dotnet/api/…
  • 发布的代码应该可以工作。您确定您正在运行最新版本的可执行文件吗?我会检查项目 bin 文件夹并查看最新版本是否在调试或发布文件夹中,然后确保您运行的是最新版本。
  • @jdweng 我已经删除了整个发布文件夹并重新发布,所以应该使用最新的代码。
  • @SJaka 删除其中一个属性,看看你是否仍然得到最新的结果,这意味着你是 100% 使用最新的代码
  • 您是否尝试过按照第一条评论的建议进行操作? DataContractSerializer 不看XmlElementXmlRoot 等,只有XmlSerializer 看。

标签: c# xml datacontractserializer


【解决方案1】:

根据我的评论,您应该use DataContract and DataMember attributes 而不是XmlRootXmlElement

[DataContract(Name = "customer", Namespace = "")]
public class Customer
{
    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "address")]
    public string Address { get; set; }
}

【讨论】:

    【解决方案2】:

    这应该适合你,

    [XmlRoot("customer")]
    public class Customer
    {
        [XmlElement("name")]
        public string Name { get; set; }
        [XmlElement("address")]
        public string Address { get; set; }
    }
    

    【讨论】:

    • 不。它没有。结果还是和以前一样。我相信XmlRoot(string) 无论如何都定义了ElementName
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多