2012-02-07 26 views
6

Tôi có dịch vụ .NET WCF với một vài hợp đồng hoạt động mất DateTimeOffset. Ý tưởng là để tránh bất kỳ sự nhầm lẫn nào với DST và múi giờ. Tuy nhiên, tôi nghi ngờ rằng việc sử dụng DateTimeOffset là một ý tưởng tốt sau khi tất cả, vì nó khá chuẩn và sẽ gây ra đau đầu cho bất kỳ ai cố gắng kết nối với, ví dụ, một ứng dụng Java hoặc một ứng dụng .NET liên kết với một phiên bản .NET cũ hơn.WCF DateTimeKhả năng tương thích với thiết bị

Cách khác là mong đợi UTC DateTime, nhưng điều này dẫn đến nguy cơ ai đó sẽ quên sử dụng thời gian UTC và gọi dịch vụ theo giờ địa phương. Tôi cũng có thể mong đợi một giờ địa phương DateTime, vì khách hàng sẽ luôn ở trong cùng một múi giờ, nhưng điều này để lại một số sự tinh tế, nhưng cổ điển, mơ hồ xung quanh những thay đổi của DST.

Có ai có câu chuyện đau đầu với DateTimeOffset trong giao diện dịch vụ hay không tương đối không có ý nghĩa để sử dụng sau khi tất cả?

+0

Là một sang một bên - DateTimeOffset thực sự được hỗ trợ bởi một tiêu chuẩn - ISO8601. Định dạng tuần tự hóa ưa thích trông giống như sau: '2012-02-07T07: 17: 00-05: 00'. Nhưng tôi không chắc liệu WCF có bao giờ chấp nhận điều này đúng hay không. –

Trả lời

1

IMHO nhức đầu lớn nhất khi sử dụng DateTime với Dịch vụ WCF là WCF hiện không hỗ trợ xs: Date - xem this related question và các đề xuất Kết nối được liên kết.

DateTimeOffset không giúp giải quyết vấn đề này.

+0

Nhưng cũng có thể, vấn đề DateTimeOffset không thực sự liên quan đến vấn đề này. – hangy

8

Tôi hiện đang thay đổi một số cơ sở hạ tầng của mình thành WCF và tình cờ gặp phải câu hỏi chưa được trả lời này và đã quyết định dùng thử. :)

Cách WCF tuần tự hóa DateTimeDateTimeOffset có vẻ hơi lạ. Như các chương trình mẫu sau, sử dụng DateTime trông giống như lựa chọn tốt hơn khi làm việc với các nền tảng khác:

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 đáp ứng được yêu cầu là:

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

Tôi đang ở múi giờ GMT + 01.00 , vì vậy các giá trị dường như đúng. Tại sao lại là cách này? Vâng, WSDL định nghĩa Container như thế này:

<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 - trong WSDL - được định nghĩa là:

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

Vì vậy, về cơ bản, DateTime được đăng như một tiêu chuẩn xs:dateTime (mà không có múi giờ đúng thành phần) và DateTimeOffset được tuần tự hóa thành một loại phức hợp không chuẩn, mà người gọi sẽ phải hiểu và xử lý chính xác.

FWIW; Kể từ khi tôi tìm thấy điều này, tôi có thể sẽ sử dụng DateTime cho giao diện WCF trừ khi tôi thực sự cần phải chăm sóc các khoảng thời gian khác nhau.

Hiện nay, sự biện minh duy nhất tôi có thể nhìn thấy trong lợi của việc sử dụng các loại phức tạp (vì xs:dateTime sẽ có thể chứa tất cả các thông tin mà nó!) Là nếu xs:dateTime đã được sử dụng để serialize DateTimeDateTimeOffset, một khách hàng WCF sẽ không biết sử dụng loại nào.

Các vấn đề liên quan