WCF客户端如何从JSON响应反序列化不兼容的日期格式?



我在网上搜索了这方面的信息,但大多数结果都是关于创建WCF服务或服务在您控制下的情况。

我正在为RESTful JSON服务构建一个WCF客户端代理,这是我无法控制的。我正在使用基本的ServiceContract/DataContract模式,并尝试让框架完成尽可能多的工作。

大多数情况下,这工作得很好,但是来自这个外部服务的所有datetime字段都是特定的格式,例如

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

所以我得到一个错误:

反序列化mynamspace . someobject类型的对象出错。DateTime内容'2013/01/02 23:14:55 +0000'不像JSON要求的那样以'/Date('开始,以')/'结束。'

我的数据合约是:

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]
public interface ICoolExternalApi
{
    [OperationContract]
    [WebGet(UriTemplate = "/something.json",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped)]
    [return: MessageParameter(Name = "SomeObject")]
    SomeObject GetAccount();
}

我想知道的是,我在哪里可以坚持一些代码来定义WCF应该如何反序列化lastmodified字段(使DateTime对象的字符串)?

或者更好的是,定义如何反序列化所有DateTime数据成员为我所有的数据合约。我不希望有很多重复的代码。

我也不想求助于第三方反序列化器,如果可以避免的话,我也不想开始通过自定义反序列化方法来处理其他所有内容。

我能想到的两件事:

  1. 更改LastModified为字符串,然后自己将其转换为Datetime对象。但这意味着为对象上的相同数据公开两个属性。
  2. 写一个IDispatchMessageInspector在反序列化发生之前拦截消息,并使用regex处理原始消息。它将为您服务中的所有日期提供一站式解决方案。

到目前为止,这是我想到的最好的:

我有一个内部字符串扩展方法:
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);
    }
}

这是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; }

如果你想使用这个数据合约来发送数据(让它成为一个可写属性),你必须编写一个DateTime扩展方法(GetSerializedDateString),扩展setter/getter,并引入私有成员作为中介。

它有剪切和粘贴的味道,而且它没有利用任何WCF框架的特性。比尔·盖茨会怎么做?

相关内容

  • 没有找到相关文章

最新更新