Заставить XmlSerializer сериализовать DateTime как «ГГГГ-ММ-ДД чч: мм: сс» - PullRequest
61 голосов
/ 21 августа 2010

У меня есть схема XSD для некоторого сервиса RESTful.При использовании вместе с инструментом xsd.exe для генерации кода на C # XSD xs:date генерирует следующий код:

[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date")]
public System.DateTime time {
    get {
        return this.timeField;
    }
    set {
        this.timeField = value;
    }
}

При десериализации XML для объектов с использованием XmlSerializer все выглядит хорошо.Проблема, с которой я сталкиваюсь, заключается в том, что служба ожидает, что даты будут отформатированы как YYYY-MM-DD hh:mm:ss, а код, сгенерированный XSD, похоже, выдаст только YYYY-MM-DD.

Если я вручную изменю XSD на тип xs:dateTime, сгенерированныйКод C # выдает: 2010-08-20T20:07:03.915039Z.

В принципе, как заставить сериализацию произвести YYYY-MM-DD hh:mm:ss?Что-то нужно делать с XSD или я могу что-то сделать, чтобы изменить сгенерированный код C #?

Ответы [ 5 ]

122 голосов
/ 21 августа 2010

В прошлом я делал следующее для управления сериализацией datetime:

  • Игнорируем свойство DateTime.
  • Создаем свойство фиктивной строки, которое сериализует / десериализует способ, которым яхочу

Вот пример:

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); }
    }
}
51 голосов
/ 06 июня 2012

Используйте атрибут [XmlElement(DataType = "date")] для форматирования значения свойства DateTime, как вам нужно.

От MSDN :

Примечание:
Атрибут, который аннотирует поле публикации, имеет Свойство DataType. В .NET Framework нет типа, соответствующего тип xs: date полностью. Наиболее близким совпадением является System.DateTime, который хранит данные даты и времени. Указание свойства DataType как «date» гарантирует, что XmlSerializer будет только сериализовать дату часть объекта DateTime.

3 голосов
/ 21 августа 2010

Я считаю, что реализация интерфейса IXmlSerializable поможет. Затем вы можете контролировать, как сериализовать и десериализовать ваш объект.

1 голос
/ 06 ноября 2018

см. Ответы выше, но для добавления - если вы хотите выводить только тогда, когда значение не равно нулю (например, XML maxOccurs = 0), вы можете использовать что-то вроде этого:

private System.DateTime? someDateField;

public string someDate
{
    get
    {
        return someDateField?.ToString("MM-dd-yyyy");
    }
    set
    {
        dobField = System.DateTime.Parse(value);
    }
}
1 голос
/ 10 ноября 2016

Если вам нужно только очистить миллисекундную часть.Обратитесь к:

Как обрезать миллисекунды от .NET DateTime

И в основном сделать что-то вроде:

  startDateTimeToUse = startDateTimeToUse.AddTicks(-(startDateTimeToUse.Ticks % TimeSpan.TicksPerSecond));
  endDate = endDate.AddTicks(-(endDate.Ticks % TimeSpan.TicksPerSecond));

Я могу подтвердить, чтоэто сериализуется в:

            <startDate>2015-10-31T12:13:04</startDate>
            <endDate>2016-11-10T12:13:06</endDate>

Я также должен заявить, что Перед очисткой миллисекунд я делаю это:

            var startDateTimeToUse = ssStartDateTime.ToUniversalTime();
            var endDate = DateTime.Now.ToUniversalTime();
            startDateTimeToUse = DateTime.SpecifyKind(startDateTimeToUse, DateTimeKind.Unspecified);
            endDate = DateTime.SpecifyKind(endDate, DateTimeKind.Unspecified);

Что я не знаю, еслиэто оказывает какое-либо влияние на сериализацию или нет на данный момент

...