Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hh:mm:ss'
I have a XSD schema for some RESTful service. When used in conjunction with xsd.exe
tool to generate C# code, XSD's xs:date
generates the following code:
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date")]
public System.DateTime time {
get {
return this.timeField;
}
set {
this.timeField = value;
}
}
When deserializing XML to objects using XmlSerializer
all seems to be well. The problem I am facing is that the service expects dates to be formatted as YYYY-MM-DD hh:mm:ss
and the XSD generated code seems to produce only YYYY-MM-DD
.
If I modify XSD manually to xs:dateTime
type, the generated C# code produces: 2010-08-20T20:07:03.915039Z
.
Basically, how do I force serialization to produce YYYY-MM-DD hh:mm:ss
? Is there something to do to XSD or is there something I can do to alter generated C# code?
Solution 1:
In the past, I've done the following to control datetime serialization:
- Ignore the DateTime property.
- Create a dummy string property that serializes/deserializes the way I want
Here is an example:
public class SomeClass
{
[XmlIgnore]
public DateTime SomeDate { get; set; }
[XmlElement("SomeDate")]
public string SomeDateString
{
get { return this.SomeDate.ToString("yyyy-MM-dd HH:mm:ss"); }
set { this.SomeDate = DateTime.Parse(value); }
}
}
Solution 2:
Use [XmlElement(DataType = "date")]
attribute to format your DateTime
property value as you need.
From MSDN:
Note:
The attribute that annotates the publicationdate field has a DataType property. There is no type in the .NET Framework that matches the type xs:date completely. The closest match is System.DateTime, which stores date and time data. Specifying the DataType property as a "date" ensures that the XmlSerializer will only serialize the date part of the DateTime object.
Solution 3:
If you only need to clear out the millisecond part. Refer to:
How to truncate milliseconds off of a .NET DateTime
And basicly do something like:
startDateTimeToUse = startDateTimeToUse.AddTicks(-(startDateTimeToUse.Ticks % TimeSpan.TicksPerSecond));
endDate = endDate.AddTicks(-(endDate.Ticks % TimeSpan.TicksPerSecond));
I can confirm that this serializes to:
<startDate>2015-10-31T12:13:04</startDate>
<endDate>2016-11-10T12:13:06</endDate>
I must also state that Before clearing the milliseconds I'm doing this:
var startDateTimeToUse = ssStartDateTime.ToUniversalTime();
var endDate = DateTime.Now.ToUniversalTime();
startDateTimeToUse = DateTime.SpecifyKind(startDateTimeToUse, DateTimeKind.Unspecified);
endDate = DateTime.SpecifyKind(endDate, DateTimeKind.Unspecified);
Which I don't know if it's having any effect on the serialization or not at this point
Solution 4:
I believe implementing IXmlSerializable
interface will do a trick. You can then control how you serialize and deserialize your object.
Solution 5:
see answers above but to add-- if you only wanted output when the value is non-null (e.g. XML maxOccurs=0) you can utilize something like this:
private System.DateTime? someDateField;
public string someDate
{
get
{
return someDateField?.ToString("MM-dd-yyyy");
}
set
{
dobField = System.DateTime.Parse(value);
}
}