具有内容转换的WCF路由

时间:2013-01-09 06:08:13

标签: wcf .net-4.0 wcf-routing

我实施了WCF路由服务;我还希望服务(或类似的WCF服务)以规定的和统一的(内容不可知的)方式转换有效载荷。例如,有效负载将始终采用Foo<T>形式,并且我希望在所有情况下都将其作为Bar<T>传递。我很高兴转型为XSLT或程序化。我并不关心收到的Foo<T>类型的邮件会发生什么。

我希望使用WCF,因为它提供了许多OOTB功能(例如,它支持多种绑定)。使用众多样板方法实现WCF服务来转换每个封闭的通用(Foo<Class1> - &gt; Bar<Class1>; Foo<Class2> - &gt; Bar<Class2>;这是不切实际的。等),因为每次要路由新的消息类型时都需要重新编译/重新部署。

据我所知,WCF不处理开放式泛型,WCF路由不能促进内容转换OOTB。也就是说,System.ServiceModel.Routing.RoutingService显然以某种非特定形式拦截WCF调用,因此我希望利用相同的模式来实现我的目标。任何人都可以请指明如何做到这一点(或说明为什么不可能)?

1 个答案:

答案 0 :(得分: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;
    }