Próbuję serializować TimeSpan
obiekt .NET do XML i nie działa. Szybki google zasugerował, że chociaż TimeSpan
można go serializować, XmlCustomFormatter
nie zapewnia on metod konwertowania TimeSpan
obiektów na i z XML.
Jednym sugerowanym podejściem było zignorowanie TimeSpan
serializacji i zamiast tego serializacja wyniku TimeSpan.Ticks
(i użycie new TimeSpan(ticks)
do deserializacji). Oto przykład:
[Serializable]
public class MyClass
{
// Local Variable
private TimeSpan m_TimeSinceLastEvent;
// Public Property - XmlIgnore as it doesn't serialize anyway
[XmlIgnore]
public TimeSpan TimeSinceLastEvent
{
get { return m_TimeSinceLastEvent; }
set { m_TimeSinceLastEvent = value; }
}
// Pretend property for serialization
[XmlElement("TimeSinceLastEvent")]
public long TimeSinceLastEventTicks
{
get { return m_TimeSinceLastEvent.Ticks; }
set { m_TimeSinceLastEvent = new TimeSpan(value); }
}
}
Chociaż wydaje się, że działa to w moich krótkich testach - czy to najlepszy sposób na osiągnięcie tego?
Czy istnieje lepszy sposób na serializację TimeSpan do iz XML?
c#
serialization
timespan
joeldixon66
źródło
źródło
Odpowiedzi:
Sposób, w jaki już pisałeś, jest prawdopodobnie najczystszy. Jeśli nie podoba ci się dodatkowa właściwość, możesz ją wdrożyć
IXmlSerializable
, ale wtedy musisz zrobić wszystko , co w dużej mierze pokonuje sens. Z chęcią skorzystam z opublikowanego przez ciebie podejścia; jest (na przykład) wydajny (bez złożonej analizy itp.), liczby niezależne od kultury, jednoznaczne, a numery typu datownika są łatwe i powszechnie rozumiane.Nawiasem mówiąc, często dodaję:
To tylko ukrywa go w interfejsie użytkownika i odwołuje się do bibliotek dll, aby uniknąć nieporozumień.
źródło
To tylko niewielka modyfikacja podejścia zaproponowanego w pytaniu, ale ten problem z Microsoft Connect zaleca użycie właściwości do serializacji takiej jak ta:
Spowodowałoby to serializację TimeSpan 0:02:45 jako:
Alternatywnie
DataContractSerializer
obsługuje TimeSpan.źródło
Coś, co może działać w niektórych przypadkach, to nadanie swojej własności publicznej pola pomocniczego, które jest TimeSpan, ale własność publiczna jest ujawniona jako ciąg znaków.
na przykład:
Jest to w porządku, jeśli wartość właściwości jest używana głównie w / w klasie zawierającej lub dziedziczącej i jest ładowana z konfiguracji xml.
Inne proponowane rozwiązania są lepsze, jeśli chcesz, aby własność publiczna była użyteczną wartością TimeSpan dla innych klas.
źródło
Łącząc odpowiedź z serializacji kolorów i tego oryginalnego rozwiązania (które samo w sobie jest świetne) otrzymałem to rozwiązanie:
gdzie
XmlTimeSpan
klasa jest taka:źródło
Możesz stworzyć lekkie opakowanie wokół struktury TimeSpan:
Przykładowy wynik zserializowany:
źródło
Ticks
tak długo.Bardziej czytelną opcją byłoby serializowanie jako ciąg i użycie
TimeSpan.Parse
metody do deserializacji. Możesz zrobić to samo, co w twoim przykładzie, ale używającTimeSpan.ToString()
gettera iTimeSpan.Parse(value)
setera.źródło
Inną opcją byłoby serializowanie go za pomocą
SoapFormatter
klasy, a nieXmlSerializer
klasy.Wynikowy plik XML wygląda trochę inaczej ... niektóre tagi z prefiksem „SOAP” itp., Ale może to zrobić.
Oto, co
SoapFormatter
szeregowało przedział czasowy wynoszący 20 godzin i 28 minut, aby:Aby użyć klasy SOAPFormatter, należy dodać odwołanie do
System.Runtime.Serialization.Formatters.Soap
przestrzeni nazw o tej samej nazwie i użyć jej.źródło
Moja wersja rozwiązania :)
Edycja: zakładając, że jest zerowy ...
źródło
Przedział czasu przechowywany w xml jako liczba sekund, ale mam nadzieję, że łatwo go przyjąć. Przedział czasu jest serializowany ręcznie (implementacja IXmlSerializable):
Bardziej wyczerpujący przykład: https://bitbucket.org/njkazakov/timespan-serialization
Spójrz na Settings.cs. I jest jakiś trudny kod do użycia XmlElementAttribute.
źródło
Do serializacji umów danych używam następujących.
źródło
Jeśli nie chcesz żadnych obejść, użyj klasy DataContractSerializer z System.Runtime.Serialization.dll.
źródło
Spróbuj tego :
źródło