You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不修改自动生成类时自定义XmlSerializer日期序列化格式

自定义XmlSerializer序列化第三方自动生成类的日期格式

问题背景

有从第三方XSD自动生成的partial实体类:

public partial class MyRegistry
{
    public DateTime MyDateTime { get; set; }
}

使用默认XmlSerializer序列化时,日期输出为ISO标准格式:

var myRegistry = new MyRegistry()
{
    MyDateTime = DateTime.Now
};

var serializer = new XmlSerializer(typeof(MyRegistry));

using (var stringWriter = new StringWriter()) 
{
    serializer.Serialize(stringWriter, myRegistry);
    Console.WriteLine(stringWriter.ToString());
}

输出结果:

<?xml version="1.0" encoding="utf-16"?>
<MyRegistry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <MyDateTime>2024-04-07T12:05:21.9739342+02:00</MyDateTime>
</MyRegistry>

需要将日期格式改为*dd/MM/yyyy hh:mm*,但直接修改自动生成的类会在XSD更新时丢失,因此需寻找无需修改原始类/XSD的解决方案。

解决方案

方案1:Partial类扩展 + XmlAttributeOverrides动态配置

利用C# partial类的特性,在独立文件中扩展类并添加格式化属性,再通过XmlAttributeOverrides告诉序列化器忽略原日期属性:

  1. 创建独立文件扩展partial类:
// 此文件不会被XSD生成工具覆盖
public partial class MyRegistry
{
    [XmlElement("MyDateTime")]
    public string MyDateTimeFormatted
    {
        get => MyDateTime.ToString("dd/MM/yyyy hh:mm");
        set => MyDateTime = DateTime.ParseExact(value, "dd/MM/yyyy hh:mm", null);
    }
}
  1. 序列化时应用属性覆盖配置:
var overrides = new XmlAttributeOverrides();
// 标记原MyDateTime属性为XmlIgnore
var ignoreAttrs = new XmlAttributes { XmlIgnore = true };
overrides.Add(typeof(MyRegistry), nameof(MyRegistry.MyDateTime), ignoreAttrs);

// 使用配置好的overrides创建序列化器
var serializer = new XmlSerializer(typeof(MyRegistry), overrides);

var myRegistry = new MyRegistry()
{
    MyDateTime = DateTime.Now
};

using (var stringWriter = new StringWriter())
{
    serializer.Serialize(stringWriter, myRegistry);
    Console.WriteLine(stringWriter.ToString());
}

方案2:自定义XmlTextWriter处理日期格式

通过自定义XmlTextWriter,在写入XML时针对性替换指定节点的日期格式:

  1. 实现自定义XmlWriter:
public class CustomDateXmlWriter : XmlTextWriter
{
    private string _currentElement;

    public CustomDateXmlWriter(TextWriter writer) : base(writer) { }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        _currentElement = localName;
        base.WriteStartElement(prefix, localName, ns);
    }

    public override void WriteString(string text)
    {
        // 仅处理MyDateTime节点的日期格式
        if (_currentElement == "MyDateTime" && DateTime.TryParse(text, out var date))
        {
            base.WriteString(date.ToString("dd/MM/yyyy hh:mm"));
        }
        else
        {
            base.WriteString(text);
        }
    }
}
  1. 序列化时使用自定义Writer:
var myRegistry = new MyRegistry()
{
    MyDateTime = DateTime.Now
};

var serializer = new XmlSerializer(typeof(MyRegistry));

using (var stringWriter = new StringWriter())
using (var xmlWriter = new CustomDateXmlWriter(stringWriter))
{
    serializer.Serialize(xmlWriter, myRegistry);
    Console.WriteLine(stringWriter.ToString());
}

内容的提问来源于stack exchange,提问作者Art

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:32:37