Совместимость WCF DateTimeOffset

У меня есть служба .NET WCF с несколькими операционными контрактами, которые принимают DateTimeOffset. Идея состоит в том, чтобы избежать путаницы с летним временем и часовыми поясами.

Однако я сомневаюсь, что использование DateTimeOffset - это все-таки хорошая идея, поскольку это довольно нестандартно и вызовет головную боль у любого, кто пытается подключиться, скажем, к приложению Java или приложению .NET, привязанному к более старой версии .NET. .

Альтернативой является ожидание UTC DateTime, но это создает риск того, что кто-то забудет использовать время UTC и вызовет службу с местным временем. Я также мог ожидать DateTime местного времени, поскольку клиенты всегда будут в одном часовом поясе, но это оставляет некоторую тонкую, но классическую двусмысленность в отношении изменений DST.

Есть ли у кого-нибудь истории о головной боли с DateTimeOffset в интерфейсе службы, или ее все-таки относительно легко использовать?


person Holstebroe    schedule 07.02.2012    source источник
comment
Кстати, DateTimeOffset действительно поддерживается стандартом ISO8601. Предпочтительный формат сериализации выглядит следующим образом: 2012-02-07T07:17:00-05:00. Но я не уверен, принял ли WCF это должным образом или нет.   -  person Matt Johnson-Pint    schedule 13.02.2013


Ответы (2)


В настоящее время я меняю часть нашей инфраструктуры на WCF, наткнулся на этот вопрос без ответа и решил попробовать. :)

Способ, которым WCF сериализует DateTime и DateTimeOffset, кажется немного странным. Как показано в следующем примере, использование DateTime выглядит лучшим вариантом при работе с другими платформами:

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 ответа на запрос:

<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>

Я нахожусь в часовом поясе GMT ​​+ 01.00, поэтому значения кажутся правильными. Почему так? Ну, WSDL определяет Container следующим образом:

<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>

А DateTimeOffset - в WSDL - определяется как:

<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>

Таким образом, DateTime сериализуется как стандартный xs:dateTime (который имеет правильный компонент часового пояса), а DateTimeOffset сериализуется в нестандартный сложный тип, который вызывающий должен понимать и правильно обрабатывать.

FWIW; Поскольку я это обнаружил, я, вероятно, буду использовать DateTime для интерфейса WCF, если мне действительно не нужно заботиться о разных смещениях часовых поясов.

В настоящее время единственное оправдание, которое я мог видеть в пользу использования сложного типа (поскольку xs:dateTime должен содержать всю информацию, которую он делает!), Заключается в том, что если бы xs:dateTime использовался для сериализации DateTime и DateTimeOffset, клиент WCF не имел бы представления какой тип использовать.

person hangy    schedule 23.03.2012

ИМХО, самая большая головная боль при использовании DateTime со службой WCF заключается в том, что WCF в настоящее время не поддерживает xs: Date - см. этот связанный вопрос и связанные предложения по подключению.

DateTimeOffset не помогает с этой проблемой.

person Joe    schedule 07.02.2012
comment
Но также проблема DateTimeOffset на самом деле не связана с этой. - person hangy; 23.03.2012