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 オブジェクトを作成する) 方法を定義するコードをどこに貼り付ければよいかということです。

または、すべての DataContract のすべての DateTime DataMembers を逆シリアル化する方法を定義することをお勧めします。多くの繰り返しコードは必要ありません。

また、サードパーティのデシリアライザーに頼ったり、回避できる場合は、カスタムのデシリアライゼーション メソッドを使用したりしたくありません。

4

2 に答える 2

2

私が考えることができる2つのこと:

  1. LastModified を文字列に変更してから、自分で Datetime オブジェクトに変換します。ただし、オブジェクトの同じデータに対して 2 つのプロパティを公開することを意味します。
  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) を記述し、セッター/ゲッターを展開して、プライベート メンバーを仲介者として導入する必要があります。

カット アンド ペーストの匂いがし、WCF フレームワークの機能をまったく利用していません。ビル・ゲイツはどうする?

于 2013-03-30T09:37:23.533 に答える