Сериализация DataType = полевое использование “времени” XmlSerializer

Я получаю нечетный результат при сериализации использования поля DateTime XmlSerializer.

У меня есть следующий класс:

public class RecordExample
{
    [XmlElement("TheTime", DataType = "time")]
    public DateTime TheTime { get; set; }

    [XmlElement("TheDate", DataType = "date")]
    public DateTime TheDate { get; set; }

    public static bool Serialize(
        Stream stream, object obj, Type objType, Encoding encoding)
    {
        try
        {
            var settings = new XmlWriterSettings { Encoding = encoding };

            using (var writer = XmlWriter.Create(stream, settings))
            {
                var xmlSerializer = new XmlSerializer(objType);
                if (writer != null) xmlSerializer.Serialize(writer, obj);
            }

            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }
}

Когда я называю использование XmlSerializer со следующим кодом тестирования:

var obj = new RecordExample 
{ 
    TheDate = DateTime.Now.Date, 
    TheTime = new DateTime(0001, 1, 1, 12, 00, 00) 
};

var ms = new MemoryStream();

RecordExample.Serialize(ms, obj, typeof(RecordExample), Encoding.UTF8);
txtSource2.Text = Encoding.UTF8.GetString(ms.ToArray());

Я получаю некоторые странные результаты, вот xml, который производится:

<?xml version="1.0" encoding="utf-8"?>
<RecordExample 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <TheTime>12:00:00.0000000+00:00</TheTime>
    <TheDate>2010-03-08</TheDate>
</RecordExample>

Любая идея, как я могу заставить элемент "TheTime" содержать время, которое больше походит на это:

<TheTime>12:00:00.0Z</TheTime>

... поскольку это - то, что я ожидал?

Спасибо

Dave

5
задан João Angelo 8 March 2010 в 18:38
поделиться

4 ответа

1
ответ дан 14 December 2019 в 19:10
поделиться

У меня самого были разные проблемы с этим ... однако я пытался сериализовать объект TimeSpan. Решение заключалось в том, чтобы иметь два свойства, одно из которых содержало TimeSpan, а другое - строковое представление TimeSpan, которое было сериализовано. Вот шаблон:

[XmlIgnore]
public TimeSpan ScheduledTime
{
    get;
    set;
}

[XmlElement("ScheduledTime", DataType="duration")]
public string XmlScheduledTime
{
    get { return XmlConvert.ToString(ScheduledTime); }
    set { ScheduledTime = XmlConvert.ToTimeSpan(value); }
}

Однако в этом коде время выводится в следующем формате:

<ScheduledTime>PT23H30M</ScheduledTime>

Определение продолжительности W3C здесь, которое объясняет это .

2
ответ дан 14 December 2019 в 19:10
поделиться

Расширяя комментарий, который я сделал к одному из других ответов.

public class RecordExample : IXmlSerializable
{
    public DateTime TheTime { get; set; }
    public DateTime TheDate { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        // TODO : Deserialization logic here
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString(
            "date", 
            this.TheDate.ToString("yyyy-MM-dd"));

        writer.WriteElementString(
            "time", 
            this.TheTime.ToString("hh:mm:ss.fK"));
    }
}

Сериализация следующим образом:

var rc = new RecordExample()
{
    TheDate = DateTime.Today,
    TheTime = DateTime.UtcNow
};

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

var ms = new MemoryStream();

serializer.Serialize(ms, rc);

ms.Seek(0, SeekOrigin.Begin);

Console.WriteLine(new StreamReader(ms).ReadToEnd());

Пример вывода:

<?xml version="1.0"?>
<RecordExample>
  <date>2010-03-08</date>
  <time>04:26:16.1Z</time>
</RecordExample>
1
ответ дан 14 December 2019 в 19:10
поделиться

Я согласен с другими ответами (я еще не закончил писать, когда они появились). не похоже, что это возможно напрямую. Взгляд на источник с помощью Reflector показывает, что значение времени в конечном итоге преобразуется в строку с помощью System.Xml.XmlConvert.ToString, которая имеет жестко запрограммированный формат:

ЧЧ: мм: ss.fffffffzzzzzz

Таким образом, наличие двух свойств, реальное - [XmlIgnore] и строка, которую вы создаете самостоятельно, - хороший способ.

1
ответ дан 14 December 2019 в 19:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: