XmlSchemaClassGenerator icon indicating copy to clipboard operation
XmlSchemaClassGenerator copied to clipboard

Can configure the CLR type for XML Datetime

Open emmanuelbenitez opened this issue 5 years ago • 10 comments

We would like to have possibility the generate class having DateTimeOffset when the XML element type is datetime.

emmanuelbenitez avatar Feb 21 '20 12:02 emmanuelbenitez

AFAICT XmlSerializer doesn't support DateTimeOffset.

mganss avatar Feb 21 '20 15:02 mganss

You're right but it is possible create your own IXmlSerializable.

emmanuelbenitez avatar Feb 21 '20 15:02 emmanuelbenitez

Can you provide an example how this would work with DateTimeOffset?

mganss avatar Feb 21 '20 15:02 mganss

This link provide a good sample: link

emmanuelbenitez avatar Feb 25 '20 08:02 emmanuelbenitez

This means we would have to make the type configurable as a string, e.g. MyTypes.MyDateTimeOffset. Currently types are handled internally as objects of Type, i.e. the type needs to be known at compile time. Or do you think this could be handled differently?

mganss avatar Feb 25 '20 10:02 mganss

This seems like a good fit for the MemberVisitor action that can be specified on the Generator. I tried to use the visitor pattern to configure xs:date as SQL date and xs:dateTime as SQL datetime2(0) using the Column attribute. Unfortunately, I discovered that the Nullable<DateTime> property can't be visited. Please allow the nullable property to be visited, since that's the one that Entity Framework can actually use.

bcallaghan-et avatar Apr 23 '20 19:04 bcallaghan-et

@bcallaghan-et This should be possible now.

mganss avatar Apr 24 '20 10:04 mganss

@mganss Yes, I can now configure the column type of the Nullable<DateTime> properties through MemberVisitor. Thanks!

bcallaghan-et avatar Apr 24 '20 17:04 bcallaghan-et

I think we need a flag that will replace standard generated code

[System.Xml.Serialization.XmlElement("RequestTime")]
public System.DateTime RequestTime { get; set; }

with workaround code

[System.Xml.Serialization.XmlIgnore]
public System.DateTimeOffset RequestTime { get; set; }

[System.Xml.Serialization.XmlElement("RequestTime")]
public string RequestTimeString {
       get => RequestTimeOffset.ToString("o");
       set => RequestTimeOffset = System.DateTimeOffset.Parse(value);
}

heggi avatar Aug 01 '20 16:08 heggi

@heggi Wouldn't this also have to account for the different XML schema types in the ToString() call (date, time, datetime)? Also, we might want to use TryParse(). Can you make a PR?

mganss avatar Aug 03 '20 11:08 mganss

Any update on this ? Is this something that is being considered ? I think it makes sense to implement the solution that was posted by @heggi here

fgheysels avatar Dec 01 '23 16:12 fgheysels

No, at least I'm not working on it. I'm open to PRs though.

mganss avatar Dec 01 '23 16:12 mganss

AFAICT XmlSerializer doesn't support DateTimeOffset.

That no longer holds true. I've created a small sample (.NET 6)

using System.Xml.Serialization;

XmlSerializer serializer = new XmlSerializer(typeof(TestClass));
using (var fs = new FileStream(@"c:\temp\serializerdatetime.xml", FileMode.Create))
{
    var tc = new TestClass()
    {
        Id = 5,
        Timestamp = new DateTimeOffset(2023, 12, 1, 8, 0, 0, TimeSpan.FromHours(4))
    };
    serializer.Serialize( fs,tc);
}

public class TestClass
{
    public int Id { get; set; }
    public DateTimeOffset Timestamp { get; set; }
}

This results in this:

<?xml version="1.0" encoding="utf-8"?>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>5</Id>
  <Timestamp>2023-12-01T08:00:00+04:00</Timestamp>
</TestClass>

As you can see, the timezone information is serialized in the Xml.

I did the other way around as well:

using (var fs = new FileStream(@"c:\temp\serializerdatetime.xml", FileMode.Open))
{
    var result = (TestClass)serializer.Deserialize(fs);

    Console.WriteLine(result.Timestamp);
}

this results in

1/12/2023 8:00:00 +04:00

So this means that it's no longer necessary to implement the work-around solution. This makes it much simpler to implement I believe.

fgheysels avatar Dec 01 '23 20:12 fgheysels