7

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

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

大多数情况下,这工作正常,但来自此外部服务的所有日期时间字段都采用特定格式,例如

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

所以我得到一个错误:

反序列化 MyNamespace.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 对象)?

或者更好的是,定义如何为我的所有 DataContracts 反序列化所有 DateTime DataMembers。我不想要很多重复的代码。

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

4

2 回答 2

2

我能想到两件事:

  1. 将 LastModified 更改为字符串,然后自己将其转换为 Datetime 对象。不过,这意味着为您的对象上的相同数据公开两个属性。
  2. 编写 IDispatchMessageInspector 以在反序列化发生之前拦截消息并使用正则表达式处理原始消息。它将为您服务中的所有日期提供一站式解决方案。
于 2013-01-05T02:34:04.753 回答
1

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

我有一个内部字符串扩展方法:

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

如果您想使用此 DataContract 发送数据(使其成为可写属性),则必须编写 DateTime 扩展方法(GetSerializedDateString),扩展 setter/getter 并引入私有成员作为中间人。

它闻起来像剪切和粘贴,并且没有利用任何 WCF 框架功能。比尔盖茨会怎么做?

于 2013-03-30T09:37:23.533 回答