.NET How to serialize a TimeSpan to XML (not the same question!)
My question is a continuation of How to serialize a TimeSpan to XML
I have many DTO objects which pass TimeSpan
instances around. Using the hack described in the original post works, but it requires me to repeat the same bulk of code in each and every DTO for each and every TimeSpan
property.
So, I came with the following wrapper class, which is XML serializable just fine:
#if !SILVERLIGHT
[Serializable]
#endif
[DataContract]
public class TimeSpanWrapper
{
[DataMember(Order = 1)]
[XmlIgnore]
public TimeSpan Value { get; set; }
public static implicit operator TimeSpan?(TimeSpanWrapper o)
{
return o == null ? default(TimeSpan?) : o.Value;
}
public static implicit operator TimeSpanWrapper(TimeSpan? o)
{
return o == null ? null : new TimeSpanWrapper { Value = o.Value };
}
public static implicit operator TimeSpan(TimeSpanWrapper o)
{
return o == null ? default(TimeSpan) : o.Value;
}
public static implicit operator TimeSpanWrapper(TimeSpan o)
{
return o == default(TimeSpan) ? null : new TimeSpanWrapper { Value = o };
}
[JsonIgnore]
[XmlElement("Value")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public long ValueMilliSeconds
{
开发者_高级运维 get { return Value.Ticks / 10000; }
set { Value = new TimeSpan(value * 10000); }
}
}
The problem is that the XML it produces looks like so:
<Duration>
<Value>20000</Value>
</Duration>
instead of the natural
<Duration>20000</Duration>
My question is can I both "eat the cake and have it whole"? Meaning, enjoy the described hack without cluttering all the DTOs with the same repetitive code and yet have a natural looking XML?
Thanks.
Change [XmlElement("Value")]
to [XmlText]
. Then, if you serialize something like this:
[Serializable]
public class TestEntity
{
public string Name { get; set; }
public TimeSpanWrapper Time { get; set; }
}
You will get XML like this:
<TestEntity>
<Name>Hello</Name>
<Time>3723000</Time>
</TestEntity>
You will need to implement IXmlSerializable:
[Serializable,XmlSchemaProvider("TimeSpanSchema")]
public class TimeSpanWrapper : IXmlSerializable
{
private TimeSpan _value;
public TimeSpanWrapper()
{
_value = TimeSpan.Zero;
}
public TimeSpanWrapper(TimeSpan value)
{
_value = value;
}
public XmlSchema GetSchema() {
return null;
}
public void ReadXml(XmlReader reader) {
_value = XmlConvert.ToTimeSpan(reader.ReadElementContentAsString());
}
public void WriteXml(XmlWriter writer) {
writer.WriteValue(XmlConvert.ToString(_value));
}
public static XmlQualifiedName TimeSpanSchema(XmlSchemaSet xs)
{
return new XmlQualifiedName("duration", "http://www.w3.org/2001/XMLSchema");
}
public static implicit operator TimeSpan?(TimeSpanWrapper o)
{
return o == null ? default(TimeSpan?) : o._value;
}
public static implicit operator TimeSpanWrapper(TimeSpan? o)
{
return o == null ? null : new TimeSpanWrapper { _value = o.Value };
}
public static implicit operator TimeSpan(TimeSpanWrapper o)
{
return o == null ? default(TimeSpan) : o._value;
}
public static implicit operator TimeSpanWrapper(TimeSpan o)
{
return o == default(TimeSpan) ? null : new TimeSpanWrapper { _value = o };
}
}
精彩评论