我正在尝试设置一个路由服务,该服务将位于我的网络的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的长度,这意味着最后的字节没有被报告.
原文链接:https://www.f2er.com/xml/452482.html这是一个有效的替换功能.
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; }