使用BulkCopy进行序列化后的DateTime格式

时间:2017-12-19 17:01:57

标签: c# xml datetime serialization

反序列化XML响应后出现问题。日期始终设置为{1/1/0001 12:00:00 AM}。

这是我的DTO课程定义:

    [XmlElement]
    public System.DateTime Date_of_Birth { get; set; }

问题是从服务器格式化收到的XML。我使用DB第一种方法并从现有DB填充我的对象,因此使用DateTime作为属性类型自动构造类。 SQL数据类型是" Date"。在excel电子表格中手动导入记录时,我没有遇到任何问题,但此程序的目的是使用XML响应自动执行该过程。

示例响应如下所示:

<root><i Other_Attributes="" Date_of_Birth="10/21/1999" More_Attributes="" /></root>

我已经看到了类似下面的建议:

public class SomeClass
{
    [XmlIgnore]
    public DateTime SomeDate { get; set; }

    [XmlElement("SomeDate")]
    public string SomeDateString
    {
        get { return this.SomeDate.ToString("yyyy-MM-dd HH:mm:ss"); }
        set { this.SomeDate = DateTime.Parse(value); }
    }
}

但是这导致我的数据表有太多列(额外的字符串值)并且BulkCopy失败。

修改 我作为DataTable转换为BulkCopy失败的原因是因为我要么映射太多列,要么使用错误的访问器方法。我能够通过将我的DTO更改为以下内容来解决:

    [XmlIgnore]
    public DateTime Date_of_Birth { get; set; }
    [XmlAttribute(AttributeName = "Date_of_Birth")]
    public string Date_of_Birth_String
    {
        get { return this.Date_of_Birth.ToString("yyyy-MM-dd HH:mm:ss"); }
        set { this.Date_of_Birth = DateTime.Parse(value); }
    }

然后我不得不改变我的方法,将我的反序列化对象转换为DataTable,将字符串值添加到DateTime行,如下所示:

    public static DataTable AsDataTable<T>(this IEnumerable<T> data)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
        var table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
        {
            if( prop.Name == "Date_of_Birth_String")
            {
                continue;
            }
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        }
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
            {
                if (prop.Name == "Date_of_Birth_String")
                {
                    row["Date_of_Birth"] = prop.GetValue(item) ?? DBNull.Value;
                    continue;
                }
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            }
            table.Rows.Add(row);
        }
        return table;

1 个答案:

答案 0 :(得分:1)

XmlSerializer does not support customized formats for DateTime properties是正确的,因此您需要一个代理string属性来解析并格式化您所需格式的DateTime

但是,在您的XML中,Date_Of_Birthattribute而不是孩子element,因此您需要使用[XmlAttribute(AttributeName="Date_of_Birth")]标记代理属性:

[XmlRoot(ElementName="i")]
public class I 
{
    [XmlIgnore]
    public DateTime SomeDate { get; set; }      

    [XmlAttribute(AttributeName="Other_Attributes")]
    public string Other_Attributes { get; set; }

    [XmlAttribute(AttributeName="Date_of_Birth")]
    public string Date_of_Birth 
    { 
        get { return this.SomeDate.ToString("yyyy-MM-dd HH:mm:ss"); }
        set { this.SomeDate = DateTime.Parse(value); }          
    }

    [XmlAttribute(AttributeName="More_Attributes")]
    public string More_Attributes { get; set; }
}

[XmlRoot(ElementName="root")]
public class Root {
    [XmlElement(ElementName="i")]
    public I I { get; set; }
}

在这里,我使用https://xmltocsharp.azurewebsites.net/自动为您的XML生成类,然后修改Date_of_Birth属性以使用基础DateTime SomeDate属性。

示例fiddle显示您的XML字符串可以反序列化并重新序列化为:

<root>
  <i Other_Attributes="" Date_of_Birth="1999-10-21 00:00:00" More_Attributes="" />
</root>