【问题标题】:Re-writing WCF Message using IClientMessageInspector使用 IClientMessageInspector 重写 WCF 消息
【发布时间】:2014-12-04 21:25:05
【问题描述】:

我正在调用供应商 Web 服务,他们调用的架构需要在 body 标记中使用自定义命名空间,如下所示:

<s:Body xmlns:ddw="http://www.infinity.com/bpm/model/OmniLinkServices/DDWEBCallInput" 
        xmlns:omn="http://eclipse.org/stardust/models/generated/OmniLinkServices">

我找不到通过属性配置、绑定配置等添加这个命名空间的好方法,所以我创建了一个 IClientMessageInspector 的实现来将命名空间添加到 body 标记中。它有效,但随后消息的正文变为:

<s:Body xmlns:ddw="http://www.infinity.com/bpm/model/OmniLinkServices/DDWEBCallInput" 
   xmlns:omn="http://eclipse.org/stardust/models/generated/OmniLinkServices">
   ... stream ...
</s:Body>

注意奇怪的......流......身体的内容。

这是我在IClientMessageInspector 上对BeforeSendRequest 的实现

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
        //Copy old message into XPathNavigator so as first step in transforming it to (newer) XDocument for modification
        Message newMessage = null;
        MessageBuffer msgbuf = request.CreateBufferedCopy(int.MaxValue);
        XPathNavigator nav = msgbuf.CreateNavigator();

        //load the old message into message stream via XmlWriter
        MemoryStream ms = new MemoryStream();
        XmlWriter xw = XmlWriter.Create(ms);
        nav.WriteSubtree(xw);
        xw.Flush();
        xw.Close();
        ms.Position = 0;

        //load the XDocument from the XmlREader
        XDocument xDoc = XDocument.Load(XmlReader.Create(ms));
        ms.Close();

        //add the sungard namespaces to the body of the message
        var body = (from x in xDoc.Descendants() where x.Name.LocalName == "Body" select x).First();
        var ddwns = new XAttribute(XNamespace.Xmlns + "ddw", "http://www.infinity.com/bpm/model/OmniLinkServices/DDWEBCallInput");
        var omnns = new XAttribute(XNamespace.Xmlns + "omn", "http://eclipse.org/stardust/models/generated/OmniLinkServices");
        body.Add(ddwns);
        body.Add(omnns);

        //create the new message
        //write the XDoc back out to memory stream
        MemoryStream newMsg = new MemoryStream();
        xw = XmlWriter.Create(newMsg);            
        xDoc.Save(xw);
        xw.Flush();
        xw.Close();
        newMsg.Position = 0;

        //create the new message        
        XmlReader reader = XmlReader.Create(newMsg);
        newMessage = Message.CreateMessage(reader, int.MaxValue, request.Version);
        request = newMessage;
        return null;
}

在函数的最后,XDocument 仍然具有有效的 XML,但是当我在最后创建消息时,这似乎就是问题所在。

有人有什么想法吗?

【问题讨论】:

  • this answer 有用吗?
  • 这很烦人。我从 WCF 日志中获取消息,但是当我通过提琴手查看完整消息时,我看到的是正确的 XML,即不是 ... 流 ... 为什么 WCF 会以这种方式记录?浪费了半天时间 :) 感谢@barrick 将我指向那个链接 b/c 链接说了同样的话,这让我看到了提琴手。
  • @jeff.enyon 没问题。根据内存,尝试将 *.config 中 &lt;binding&gt; 上的 transferMode 设置为 buffered...stream... 出现是因为消息正在通过 WCF 流式传输(可能以块的形式),因此无法确定它在任何时候都包含整个消息,并且显然将块保存在内存中以便能够获取之后的整个消息被有效地缓冲,然后流的优势就消失了。

标签: c# .net xml wcf soap


【解决方案1】:

看来这正是 WCF 记录消息的方式。看着提琴手整个 xml 正在经历。我不明白为什么 WCF 会以这种方式记录,但无论如何。

对于遇到此问题的其他任何人,仅供参考。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多