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 DateTime
và DateTimeOffset
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>
Và 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 DateTime
và DateTimeOffset
, một khách hàng WCF sẽ không biết sử dụng loại nào.
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. –