У меня есть большая коллекция автоматически сгенерированных классов, которые сериализуются/десериализуются из XML с помощью .NET XmlSerializer. Некоторые из этих классов содержат свойства DateTime.Сериализовать DateTime для XML в определенном формате .net
У меня есть требование для сериализации всех Свойства DateTime с использованием определенного формата, например, «u». :
System.DateTime.Now.ToString("u");
//returns something like "2008-06-15 21:15:07Z"
метод Deserialize, кажется, работает с этим форматом, но сериализации не делает - он просто дает мне HARDCODED Отформатируй же формат, что у меня есть по умолчанию в системе хостинга (возможно, я могу обмануть сериалайзер путем изменения нити настройка?) (проверьте обновление №1).
Примечание: Я уже проверил несколько связанных вопросов, и они решены путем изменения оригинальных свойств и добавления новых. Для меня это неприемлемо из-за большого количества изменений, которые мне пришлось бы сделать.
- How to serialize Xml Date only from DateTime in C#
- Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hh:mm:ss'
Ниже приведен класс тестовый образец, который я использую, чтобы проверить эту проблему.
using System;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Globalization;
using System.IO;
namespace FunkyTests
{
[TestClass]
public class SerializationTests
{
[TestMethod]
public void FunkySerializationTest()
{
var date = DateTime.Now;
var dummy = new Dummy() { DummyProperty = date };
var xml = SerializeToXml(dummy);//serializes with "o" format
var expected = date.ToString("u", new CultureInfo("en-US"));//in this example I want "u" format
var actual = XDocument.Parse(xml).Descendants("DummyProperty").Single().Value;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void FunkyDeserializationTest()
{
var date = DateTime.Now;
var dummy = new Dummy() { DummyProperty = date };
var xml = SerializeToXml(dummy);//serializes with "o" format
var deserializedDummy = DeserializeFromXml<Dummy>(xml);
Assert.AreEqual(dummy.DummyProperty, deserializedDummy.DummyProperty);
}
private static T DeserializeFromXml<T>(string xml)
{
using (var textReader = new StringReader(xml))
{
using (var reader = XmlReader.Create(textReader))
{
var serializer = new XmlSerializer(typeof(T));
var result = serializer.Deserialize(reader);
return (T)result;
}
}
}
private static string SerializeToXml<T>(T objectToSerialize)
{
var xml = new StringBuilder();
using (var writer = XmlWriter.Create(xml, new XmlWriterSettings { OmitXmlDeclaration = true }))
{
var ns = new XmlSerializerNamespaces();
ns.Add(string.Empty, string.Empty);
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, objectToSerialize, ns);
}
return xml.ToString();
}
public class Dummy
{
public DateTime DummyProperty { get; set; }
}
}
}
Любые идеи для фанки?
Обновление # 1: Я думал, что сериализация даты зависит от Thread.CurrentCulture. Если я правильно интерпретирую код XmlSerializer, формат жестко запрограммирован (спасибо ILSpy).
// System.Xml.Serialization.XmlCustomFormatter
internal static string FromDateTime(DateTime value)
{
if (XmlCustomFormatter.Mode == DateTimeSerializationSection.DateTimeSerializationMode.Local)
{
return XmlConvert.ToString(value, "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz");
}
return XmlConvert.ToString(value, XmlDateTimeSerializationMode.RoundtripKind);
}
Update # 2: Я добавил метод тестирования, который использует предложенный ответ от Александра Петрова. Это не удается при утверждении Ticks. Согласно задаче Serialize DateTime as binary проблема во внутренних словах DateTime и вызвана потерей «Вид» DateTime. Было предложено использовать DateTimeOffset, что приводит к еще одной проблеме сериализации, поясняемой в How can I XML Serialize a DateTimeOffset Property?
См. [This] (http: // stackoverflow.com/q/3534525/1997232) (вы уже упоминали), вы ограничены либо «XmlIgnoreAttribute» (используя другое свойство типа «string» для сериализации/десериализации свойства DateTime), либо «IXmlSerializable» (пользовательский сериализатор, где вы можете добавить собственные атрибуты, с помощью которых вы можете указать различные параметры для сериализатора/десериализатора, включая формат данных). Если вы можете найти зависящий от культуры «XmlSerializer» (я уверен, он должен быть один), тогда вы можете создать собственную культуру с пользовательским форматом 'DateTime' и использовать его. – Sinatr
Вы решили проблему? –