加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xml – 替换WCF消息的内容

发布时间:2020-12-15 23:53:16 所属栏目:百科 来源:网络整理
导读:我正在尝试设置一个路由服务,该服务将位于我的网络的DMZ中,并允许外部人员访问一些内部托管的WCF服务.我已经设置好所有工作,但是当我转发MEX服务时,它会将我们的外部客户端指向我们的内部地址,这显然是他们无法访问的. Microsoft seems to recommend making
我正在尝试设置一个路由服务,该服务将位于我的网络的DMZ中,并允许外部人员访问一些内部托管的WCF服务.我已经设置好所有工作,但是当我转发MEX服务时,它会将我们的外部客户端指向我们的内部地址,这显然是他们无法访问的.

Microsoft seems to recommend making a copy of the wsdl,这可能会起作用,但是每次服务定义发生变化时都需要我制作wsdl的新副本,而这些副本经常发生,而且看起来有点过分.唯一需要改变的是mex消息中的地址.

<endpoint address="http://appsrv1:8781/ProcessManagementService/"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IProcessManagementService"
            contract="IProcessManagementService" name="WSHttpBinding_IProcessManagementService" />

好像使用IDispatchMessageInspector,我应该能够拦截mex消息并用外部服务器名称替换内部服务器名称,然后我只需要在需要添加或删除服务时触摸路由服务,而不是每次我做出任何改变.

我对XML阅读器,编写器等没有太多经验,所以我正在寻找有关如何继续的一些指导.如果我可以将xml内容读入字符串,我可以执行替换操作来替换内部地址的外部地址,然后用我的修改版本替换回复的消息内容.我该如何去做,或者有更好的方法来修改WCF消息的内容?

编辑:所以这就是我到目前为止拼凑的东西.

public class EndpointReplacementInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request,IClientChannel channel,InstanceContext instanceContext)
    {
        return null;
    }

    public void BeforeSendReply(ref Message reply,object correlationState)
    {           
        var ms = new MemoryStream();
        var w = XmlWriter.Create(ms,new XmlWriterSettings { Indent = true,IndentChars = "  ",OmitXmlDeclaration = true });
        var bodyReader = reply.GetReaderAtBodyContents();
        w.WriteStartElement("s","Body","http://schemas.xmlsoap.org/soap/envelope/");
        while (bodyReader.NodeType != XmlNodeType.EndElement && bodyReader.LocalName != "Body" && bodyReader.NamespaceURI != "http://schemas.xmlsoap.org/soap/envelope/")
        {
            if (bodyReader.NodeType != XmlNodeType.Whitespace)
            {
                w.WriteNode(bodyReader,true);
            }
            else
            {
                bodyReader.Read(); // ignore whitespace; maintain if you want
            }
        }
        w.WriteEndElement();
        w.Flush();
        var body = Encoding.UTF8.GetString(ms.ToArray());
        body = body.Replace("internalserver","externalserver");            
        var replacedMessage = Message.CreateMessage(XmlReader.Create(new StringReader(body)),int.MaxValue,reply.Version);
        replacedMessage.Headers.CopyHeadersFrom(reply.Headers);
        replacedMessage.Properties.CopyProperties(reply.Properties);
        reply = replacedMessage;    
    }
}

它似乎主要起作用.但是,XMLReader抛出异常“根级别的数据无效.第1行,位置1”.当我尝试创建消息时.我不知道从那里开始.

编辑2:

好的,现在我有一个方法将消息提取到xdocument中,然后将其发送到字符串,然后编辑它,然后将其拉回到xdocument中,当我发回一个时,我得到一个“强制关闭连接”包含该已编辑邮件的邮件.可怕.

编辑3:

在测试之后,简单地从回复到xdoc中提取消息然后将其加载到新消息中就足以导致“连接强制关闭”问题.这绝不是编辑邮件的正确方法.我正在寻找有关如何最好地解决这个问题的示例或经验.

我从 MSDN Forums得到了答案.我的问题是我正在改变字符串的长度,但没有重置MemoryStream的长度,这意味着最后的字节没有被报告.

这是一个有效的替换功能.

public Message ChangeString(Message oldMessage,string from,string to)
        {
            MemoryStream ms = new MemoryStream();
            XmlWriter xw = XmlWriter.Create(ms);
            oldMessage.WriteMessage(xw);
            xw.Flush();
            string body = Encoding.UTF8.GetString(ms.ToArray());
            xw.Close();

            body = body.Replace(from,to);

            ms = new MemoryStream(Encoding.UTF8.GetBytes(body));
            XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(ms,new XmlDictionaryReaderQuotas());
            Message newMessage = Message.CreateMessage(xdr,oldMessage.Version);
            newMessage.Properties.CopyProperties(oldMessage.Properties);
            return newMessage; 
       }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读