WCF Compatibility DateTimeOffset

I have a WCF.NET service with several operating contracts that use DateTimeOffset. The idea is to avoid confusion with DST and time zones.

However, I doubt that using DateTimeOffset is a good idea, since it is rather non-standard and can cause a headache for anyone trying to connect, say, to a Java application or to a .NET application tied to an earlier version of .NET.

An alternative would be a UTC DateTime, but this creates the risk that someone will forget to use UTC and call the service with local time. I could also expect a local DateTime, as clients will always be in the same time zone, but this leaves some subtle, but classic, ambiguity around DST changes.

Does anyone have any headache news with DateTimeOffset in the service interface or is it relatively hassle-free to use in the end?

+6
source share
2 answers

I am currently changing part of our infrastructure to WCF and stumbled upon this unanswered question and decided to give it a try. :)

The way WCF DateTime and DateTimeOffset are serialized seems a bit odd. As the following example shows, using DateTime looks like the best option when working with other platforms:

 using System; using System.Runtime.Serialization; using System.ServiceModel; [ServiceContract] public class DateTimeOffsetService { [OperationContract] public Container DoWork() { return new Container { NowDateTime = DateTime.Now, UtcNowDateTime = DateTime.UtcNow, NowDateTimeOffset = DateTimeOffset.Now, UtcNowDateTimeOffset = DateTimeOffset.UtcNow }; } } [DataContract] public class Container { [DataMember] public DateTime NowDateTime { get; set; } [DataMember] public DateTime UtcNowDateTime { get; set; } [DataMember] public DateTimeOffset NowDateTimeOffset { get; set; } [DataMember] public DateTimeOffset UtcNowDateTimeOffset { get; set; } } 

XML response request:

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header /> <s:Body> <DoWorkResponse xmlns="http://tempuri.org/"> <DoWorkResult xmlns:a="http://schemas.datacontract.org/2004/07/RD.MES.WcfService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:NowDateTime>2012-03-23T15:59:47.8328698+01:00</a:NowDateTime> <a:NowDateTimeOffset xmlns:b="http://schemas.datacontract.org/2004/07/System"> <b:DateTime>2012-03-23T14:59:47.8328698Z</b:DateTime> <b:OffsetMinutes>60</b:OffsetMinutes> </a:NowDateTimeOffset> <a:UtcNowDateTime>2012-03-23T14:59:47.8328698Z</a:UtcNowDateTime> <a:UtcNowDateTimeOffset xmlns:b="http://schemas.datacontract.org/2004/07/System"> <b:DateTime>2012-03-23T14:59:47.8328698Z</b:DateTime> <b:OffsetMinutes>0</b:OffsetMinutes> </a:UtcNowDateTimeOffset> </DoWorkResult> </DoWorkResponse> </s:Body> </s:Envelope> 

I am in the GMT + 01.00 time zone, so the values ​​seem to be correct. Why is that? Well, WSDL defines a Container as follows:

 <xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/WcfService"> <xs:import schemaLocation="http://localhost:3608/DateTimeOffsetService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/System"/> <xs:complexType name="Container"> <xs:sequence> <xs:element minOccurs="0" name="NowDateTime" type="xs:dateTime"/> <xs:element minOccurs="0" name="NowDateTimeOffset" type="q1:DateTimeOffset"/> <xs:element minOccurs="0" name="UtcNowDateTime" type="xs:dateTime"/> <xs:element minOccurs="0" name="UtcNowDateTimeOffset" type="q2:DateTimeOffset"/> </xs:sequence> </xs:complexType> <xs:element name="Container" nillable="true" type="tns:Container"/> </xs:schema> 

And DateTimeOffset - in WSDL - is defined as:

 <xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/System"> <xs:import schemaLocation="http://localhost:3608/DateTimeOffsetService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/> <xs:complexType name="DateTimeOffset"> <xs:annotation> <xs:appinfo> <IsValueType>true</IsValueType> </xs:appinfo> </xs:annotation> <xs:sequence> <xs:element name="DateTime" type="xs:dateTime"/> <xs:element name="OffsetMinutes" type="xs:short"/> </xs:sequence> </xs:complexType> <xs:element name="DateTimeOffset" nillable="true" type="tns:DateTimeOffset"/> </xs:schema> 

Basically, DateTime serialized as the standard xs:dateTime (which has the right timezone component), and DateTimeOffset serialized into a non-standard complex type that the caller would need to correctly understand and process.

FWIW; Since I found this, I will probably use DateTime for the WCF interface if I really don't need to care about different timezone offsets.

Currently, the only excuse I could see for using a complex type (since xs:dateTime should contain all the information it does!) Is that if xs:dateTime used to serialize DateTime and DateTimeOffset , the WCF client I wouldn’t know which type to use.

+9
source

IMHO the biggest headache when using DateTime with a WCF service is that WCF does not currently support xs: Date - see this related question and related Connect suggestions.

DateTimeOffset does not help with this problem.

+1
source

Source: https://habr.com/ru/post/907823/


All Articles