2012-02-07 3 views
6

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

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

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

У кого-нибудь есть новости о головной боли с DateTimeOffset в сервисном интерфейсе или это относительно беспроблемно использовать в конце концов?

+0

Как в стороне - DateTimeOffset действительно поддерживается стандартом ISO8601. Предпочтительный формат сериализации выглядит следующим образом: '2012-02-07T07: 17: 00-05: 00'. Но я не уверен, что WCF когда-либо принимал это правильно или нет. –

ответ

1

IMHO самая большая головная боль при использовании DateTime с сервисом WCF заключается в том, что WCF в настоящее время не поддерживает xs: Date - см. this related question и связанные предложения Connect.

DateTimeOffset не помогает в этом.

+0

Но также проблема DateTimeOffset на самом деле не связана с этим. – hangy

8

Я в настоящее время меняю часть нашей инфраструктуры на 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 не знал бы, какой тип использовать.

Смежные вопросы