2013-01-04 23 views
7

Tôi đã tẩy sạch Net để biết thông tin về điều này, nhưng hầu hết các kết quả là về việc tạo ra các dịch vụ WCF hoặc các tình huống mà dịch vụ nằm dưới sự kiểm soát của bạn.WCF Client làm thế nào tôi có thể deserialize một định dạng ngày không tương thích từ các phản ứng JSON?

Tôi đang xây dựng một proxy máy khách WCF cho một dịch vụ JSON RESTful nằm ngoài tầm kiểm soát của tôi. Tôi đang sử dụng mẫu ServiceContract/DataContract cơ bản và cố gắng để khung làm việc càng nhiều càng tốt.

Chủ yếu điều này hoạt động tốt, nhưng tất cả các trường ngày giờ đến từ dịch vụ bên ngoài này đều có định dạng cụ thể, ví dụ:

{"SomeObject": 
    {"details":"blue and round", "lastmodified":"2013/01/02 23:14:55 +0000"} 
} 

Vì vậy, tôi nhận được một lỗi:

There was an error deserializing the object of type MyNamespace.SomeObject. DateTime content '2013/01/02 23:14:55 +0000' does not start with '/Date(' and end with ')/' as required for JSON.'.

DataContract của tôi là:

namespace Marshmallow.WebServices.ServiceModels 
{ 
    [DataContract] 
    public class SomeObject 
    { 
     [DataMember(Name = "details")] 
     public string Details { get; set; } 

     [DataMember(Name = "lastmodified")] 
     public DateTime LastModified { get; set; } 
    } 
} 

ServiceContract của tôi là:

[ServiceContract] 
public interface ICoolExternalApi 
{ 
    [OperationContract] 
    [WebGet(UriTemplate = "/something.json", 
     ResponseFormat = WebMessageFormat.Json, 
     BodyStyle = WebMessageBodyStyle.Wrapped)] 
    [return: MessageParameter(Name = "SomeObject")] 
    SomeObject GetAccount(); 
} 

Những gì tôi muốn biết là, nơi tôi có thể dính một số cá tuyết e để xác định cách WCF nên deserialize trường lastmodified (làm cho một đối tượng DateTime ra khỏi chuỗi)?

Hoặc tốt hơn, hãy xác định cách deserialize tất cả các DataMembers DateTime cho tất cả DataContracts của tôi. Tôi không muốn nhiều mã lặp lại.

Tôi cũng không muốn sử dụng dịch vụ deserializer của bên thứ ba cũng như không muốn bắt đầu đặt mọi thứ khác thông qua phương pháp deserialization tùy chỉnh, nếu có thể tránh được.

+0

Deserializing vào một chuỗi có những hạn chế bạn đã lưu ý. Nó sẽ hoạt động nhưng cách xa thanh lịch. Thiết lập một IDispatchMessageInspector là một nỗ lực nhiều hơn một chút nhưng nên được sạch hơn. –

+1

Tôi cảm thấy như sử dụng một IDispatchMessageInspector không thực sự là thanh lịch. A) Regex chậm và không có khả năng mở rộng. B) Nó là một phân tích thêm của toàn bộ cơ thể json. C) Tôi sẽ phải chuyển đổi các chuỗi ngày giờ thành định dạng 'đó' "\/Ngày (1297293089984-0800) \ /" mà sau đó sẽ được phân tích cú pháp một lần nữa để popluate DataMember (chế biến kép). D) Đó là một hack. Chắc chắn phải có một tính năng WCF mà tôi không hiểu (OnDeserializing hay cái gì?) Được thiết kế để đối phó với những tình huống này? –

Trả lời

1

Cho đến nay này là tốt nhất mà tôi đã đưa ra:

Tôi có một phương pháp chuỗi mở rộng nội bộ:

internal static class DeserializationHelper 
{ 
    internal static DateTime GetDeserializedDateTime(this string @string) 
    { 
     if (string.IsNullOrEmpty(@string)) return default(DateTime); 
     //insert complex custom deserialization logic here 
     return DateTime.Parse(@string); 
    } 

} 

Đây là thiết lập DataMember:

[DataMember(Name = "lastmodified")] 
internal string _LastModified 
{ 
    set { LastModified = value.GetDeserializedDateTime(); } 
    //getter is not needed for receiving data but WCF requires one 
    get { return default(string); } 
} 

public DateTime LastModified { get; private set; } 

Nếu bạn muốn sử dụng DataContract này để gửi dữ liệu (làm cho thuộc tính này có thể ghi được), bạn sẽ phải viết một phương thức DateTime Extension (GetSerialized) DateString), mở rộng trình cài đặt/getters và giới thiệu các thành viên riêng tư như go-betweens.

Nó có mùi cắt và dán, và nó không tận dụng lợi thế của bất kỳ tính năng khung WCF. Bill Gates sẽ làm gì?

2

Hai điều tôi có thể nghĩ:

  1. Thay đổi LastModified là một chuỗi và sau đó chuyển nó sang một Datetime đối tượng chính mình. Nó sẽ có nghĩa là lộ hai thuộc tính cho cùng một dữ liệu trên đối tượng của bạn mặc dù.
  2. Viết IDispatchMessageInspector để chặn thư trước khi quá trình deserialization xảy ra và xoa bóp thư thô bằng regex. Nó sẽ cho phép một giải pháp một cửa cho tất cả các ngày trong dịch vụ của bạn.
+0

Cảm ơn bạn đã nhập. 1) Cho đến nay đây là những gì tôi đang làm, trong khi vẫn giữ thuộc tính chuỗi bên trong. Nó đòi hỏi thêm mã hóa cho mỗi Datetime DataTime, tuy nhiên, do đó, nó có mùi khá xấu với tôi. 2) Trong khi điều này sẽ làm việc, nó giống như một hack, và giới thiệu trên cao mà sẽ thỏa hiệp khả năng mở rộng. –