2

WCF ルーティング サービスを実装しました。また、サービス (ま​​たは同様の WCF サービス) が規定の統一された (コンテンツに依存しない) 方法でペイロードを変換することも望んでいます。たとえば、ペイロードは常にフォームを取り、すべての場合Foo<T>と同様に渡したいと思います。Bar<T>変換が XSLT またはプログラムによるものであることを嬉しく思います。タイプではない受信メッセージがどうなるかは気にしませんFoo<T>

多くの OOTB 機能 (多数のバインドのサポートなど) を提供する WCF を使用したいと考えています。新しいメッセージ型がルーティングされるたびに再コンパイル/再展開が必要になるため、多数のボイラープレート メソッドを使用して WCF サービスを実装して、閉じたジェネリック ( Foo<Class1>-> Bar<Class1>; Foo<Class2>-> ; など) を変換することは現実的ではありません。Bar<Class2>

私の知る限りでは、WCF はオープン ジェネリックを処理せず、WCF ルーティングはコンテンツ変換 OOTB を促進しません。とはいえ、System.ServiceModel.Routing.RoutingService明らかに WCF 呼び出しを非特定の形式でインターセプトするため、同じパターンを活用して目標を達成したいと考えていました。誰かがこれを行う方法について指示を与えることができますか (またはそれが不可能な理由を示してください)?

4

1 に答える 1

3

質問に対する私のコメントで提案したように、IDispatchMessageInspector を使用した解決策があります。以下に、私が最終的に書いたものの非常に単純化されたバージョンを見つけてください (20 クラスのコードを投稿するよりも簡単です)。このコードをよりクリーンで高度な方法で実装した完全なソリューションが必要な場合は、お知らせください。私のデモを CodeProject に掲載します。今のところ、内臓の断片に満足していると思います.

コンソール コマンドは明らかに削除できます (自己ホストしている場合にデバッグできるようにするためです)。

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        if (request == null || request.IsEmpty)
            return null;

        Console.WriteLine();
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine(request);
        Console.ResetColor();

        // Load the request into a document.
        XPathDocument document;
        MemoryStream stream;
        using (stream = new MemoryStream())
        {
            using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream))
            {
                request.WriteMessage(writer);
                writer.Flush();
                stream.Position = 0L;
                document = new XPathDocument(stream);
            }
        }

        // Load the XSLT.
        XslCompiledTransform transformer = new XslCompiledTransform();
        transformer.Load("RequestTransformation.xslt");

        // Transform the document.
        byte[] transformedDocument;
        using (stream = new MemoryStream())
        {
            transformer.Transform(document, null, stream);
            transformedDocument = stream.ToArray();
        }

        // Construct new request from tranformed document.
        stream = new MemoryStream(transformedDocument);
        XmlReader reader = XmlReader.Create(stream);
        Message modifiedMessage = Message.CreateMessage(reader, int.MaxValue, request.Version);
        modifiedMessage.Properties.CopyProperties(request.Properties);
        request = modifiedMessage;

        Console.WriteLine();
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine(new System.Text.UTF8Encoding(false).GetString(transformedDocument));
        Console.ResetColor();

        return null;
    }
于 2013-04-03T13:33:50.590 に答える