2

Visual Studio 2010 で最初から開始し、「WCF サービス アプリケーション」を追加するとします。このメソッドと実装を追加します。

// (in IService1.cs)
    [OperationContract]
    Dictionary<string, string> GetDictionary();

// (in Service1.svc.cs)
    public Dictionary<string, string> GetDictionary()
    {
        return new Dictionary<string, string>(
            StringComparer.InvariantCultureIgnoreCase);
    }

次に、新しい「コンソール アプリケーション」を同じソリューションに追加し、(すべての既定の設定を使用して) サービス プロジェクトにサービス参照を追加し、このコードを に追加しますMain

        var c = new ServiceReference1.Service1Client();

        var d = c.GetDictionary();

        d.Add("key",string.Empty);
        // Since this *should* be a case-insensitive dictionary,
        // this add *should* fail
        d.Add("KEY", string.Empty);

        Console.WriteLine("Both Add()s succeeded :(");
        Console.ReadKey();

大文字と小文字を区別しない辞書はkeyandKEYを同じキーと見なし、2 番目の をスローするため、このコードは失敗することが予想されAddます。

残念ながら、すべてがコンパイルされて実行されると、残念な顔:(になります。これDictionaryは、WCF レイヤーに到達すると、特定の非デフォルトで作成されたことを「忘れ」、Comparer代わりにstringデフォルトの等値比較子を取得するためです。

ワイヤを通過するときにのComparerプロパティが保持されるように変更する簡単な設定はありますか? Dictionaryまたは、カスタム クラスを作成する必要がありますか?

(カスタム IEqualityComparer を使用した Dictionary の XML シリアル化を見たことがありますが、あまり啓発されませんでした。3 年前のこの codeproject コメントも見ましたが、これは私の質問であり、回答ではありません)

4

1 に答える 1

6

「サービス参照の追加」などの標準メカニズムを使用する場合、WCFは設計上、ワイヤー上の構造(XML スキーマで表現できるXML シリアル化構造など)に基づいて、データ構造の完全に別のコピーを作成します ( XSD)。

これには、実際のデータではなく、より多くの動作(コード) であるもの (比較子など) は含まれません。

これを「オン」にする設定はありません-それはできません。これを解決する唯一の方法は、通信ワイヤの両端を制御し、両方が .NET プラットフォームである場合、両方のサーバーが必要とする共通のもの (サービス コントラクト、データ コントラクトなど) を別のアセンブリで共有することです。クライアントのリファレンスと同様に。クライアントでは、WCF プロキシを作成する前に、その共有アセンブリへの参照を追加する必要があります。その場合、WCF ランタイムは、共有アセンブリから既存のデータ構造 (カスタム比較子を使用した辞書など) を再利用します。新しい定型的なコピーを作成する代わりに。

于 2011-11-15T17:44:50.670 に答える