DateTime wrapper serialization

J

Jarlaxle

I am trying to figure out how DateTime handles its serialization. I can see
it derives from ISerialization. I am basically trying to wrap a DateTime in
another struct and have it serialize like DateTime does.

i can't seem to get past the "XMLAttribute/XMLText can't be used on complex
types" error.

Its like...

public struct DateTimeEx
{
private DateTime _dt;

....
}

How can I get this to serialize using XMLSerializer like the following...

public class Test
{
[XmlAttribute(AttributeName="myattr")]
public DateTimeEx MyDateAttr
{
get;
set;
}
[XmlText]
public DateTimeEx MyDate
{
get;
set;
}
}

Not sure if I need to implement ISerializable or can do it using attributes.

Thanks for any help.
 
J

Jeroen Mostert

Jarlaxle said:
I am trying to figure out how DateTime handles its serialization. I can see
it derives from ISerialization. I am basically trying to wrap a DateTime in
another struct and have it serialize like DateTime does.
I almost hesitate to ask why. If you serialize it the same, it contains the
same data, right? So why wrap it? If you need additional operations, you can
probably provide these more effectively with static methods. (Or, if you've
got C# 3, through extension methods.)

If you're wrapping it because you need to restrict the value, this may have
some merit, but I'd imagine most restrictions on date/time values would
occur on system boundaries rather than within the system, so factored-out
checks would serve too.
i can't seem to get past the "XMLAttribute/XMLText can't be used on complex
types" error.

Its like...

public struct DateTimeEx
{
private DateTime _dt;

....
}

How can I get this to serialize using XMLSerializer like the following...

public class Test
{
[XmlAttribute(AttributeName="myattr")]
public DateTimeEx MyDateAttr
{
get;
set;
}
[XmlText]
public DateTimeEx MyDate
{
get;
set;
}
}
Well, to the best of my knowledge borne from pretty extensive suffering, you
just can't do this. This is a shortcoming of XMLSerializer; it can't
serialize "complex types" (i.e. non-built-in types) as attributes. You can
serialize it as an element, but not as an attribute. The magic here is not
in DateTime, but in XmlSerializer, and there's no way to "give it more magic".

<rant>
In general, XmlSerializer is perfectly useful in exactly those circumstances
it wants to be useful in, and perfectly painful in others. I've seen few
hard problems with XmlSerializer that couldn't be solved by not using it,
but unfortunately it's .NET's flagship for XML serialization (that and the
SOAP formatter, which solves the shortcomings of XmlSerializer's magic by
adding *even more magic*). WCF largely solves all of this, but at the
expense of Lots of Layers (tm) that discourage you from thinking about XML
at all and tie it up in services, thus limiting the applicability.
</rant>

Your best option here is really to use DateTime fields, and shunt whatever
additional functionality you require to new classes. It's not very O-O, but
it's the workable solution. Alternatively, if you don't mind disfiguring
your classes with properties just meant for serialization, you could do:

[XmlIgnore]
public DateTimeEx MyDate { get; set; }

[XmlAttribute(...)]
public DateTime MyDateAttrXml {
get { return (DateTime) MyDateAttr; }
set { MyDateAttr = (DateTimeEx) value; }
}

(This assumes your struct has conversion operators defined.) These
attributes should come with a "please do not use" sign for everyone who's
not an XmlSerializer. Pretty ugly stuff, and if you're this far, you'll
probably want to use these types *only* for XML serialization and have the
"proper" classes somewhere else, converting as necessary.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top