C# 强制WCF在客户端代理中创建xml命名空间别名
我使用添加服务引用功能创建了一个到外部web服务的代理 默认情况下,WCF客户端生成SOAP消息,其中消息体具有如下名称空间装饰:C# 强制WCF在客户端代理中创建xml命名空间别名,c#,wcf,xml-serialization,wcf-client,C#,Wcf,Xml Serialization,Wcf Client,我使用添加服务引用功能创建了一个到外部web服务的代理 默认情况下,WCF客户端生成SOAP消息,其中消息体具有如下名称空间装饰: <s:Body> <BankingTransaction xmlns="http://tempuri.org/"> <amount>0</amount> </BankingTransaction> </s:Body> 0 我需要消息体看起来像这样 &
<s:Body>
<BankingTransaction xmlns="http://tempuri.org/">
<amount>0</amount>
</BankingTransaction>
</s:Body>
0
我需要消息体看起来像这样
<s:Body>
<bb:BankingTransaction xmlns:bb="http://tempuri.org/">
<amount>0</amount>
</bb:BankingTransaction>
</s:Body>
0
区别在于“bb”xml名称空间别名。我试图使用的web服务要求消息负载的xml命名空间具有别名。WCF客户端的默认行为是将名称空间定义为默认名称空间。我到处寻找这个问题的配置/装饰解决方案,但没有找到。除非有配置解决方案,否则在序列化每个SOAP消息之后,我必须对其进行检查和更改#瘸子
这里有一个简单的解决方案吗?这个问题的解决方案是创建一个自定义MessageInspector(通过IClientMessageInspector)来检查和更改WCF客户端代理生成的SOAP消息,然后再通过网络发送这些消息。这一解决方案的基础在Steven Cheng的文章中阐述,并从Kirk Evan的文章中进一步介绍 我使用Steven帖子中的代码连接自定义MessageInspector基础结构。然后我修改了他的Transformf2()方法,该方法只对SOAP消息的
部分进行操作,以满足我的特殊需要。在我的例子中,如原始问题中所述,我需要为我的目标web服务XML命名空间定义并使用别名,xmlns=”http://tempuri.org“
,如上所述
要做到这一点,我必须
,
它将始终是
private static Message Transform(Message oldMessage)
{
//load the old message into XML
var msgbuf = oldMessage.CreateBufferedCopy(int.MaxValue);
var tmpMessage = msgbuf.CreateMessage();
var xdr = tmpMessage.GetReaderAtBodyContents();
var xdoc = new XmlDocument();
xdoc.Load(xdr);
xdr.Close();
// We are making an assumption that the Operation element is the
// first child element of the Body element
var targetNodes = xdoc.SelectNodes("./*");
// There should be only one Operation element
var node = (null != targetNodes) ? targetNodes[0] : null;
if (null != node)
{
if(null != node.Attributes) node.Attributes.RemoveNamedItem("xmlns");
node.Prefix = "bb";
}
var ms = new MemoryStream();
var xw = XmlWriter.Create(ms);
xdoc.Save(xw);
xw.Flush();
xw.Close();
ms.Position = 0;
var xr = XmlReader.Create(ms);
//create new message from modified XML document
var newMessage = Message.CreateMessage(oldMessage.Version, null, xr);
newMessage.Headers.CopyHeadersFrom(oldMessage);
newMessage.Properties.CopyProperties(oldMessage.Properties);
return newMessage;
}
}
这有用吗:?谢谢你的回复。这似乎是可行的。它要求手动修改所有消息约定。这个API中有很多这样的内容。我最终找到了一个更简单的解决方案。再次感谢。