在WCF客户端的SOAP信封中包含另一个NameSpace

时间:2011-11-11 21:02:09

标签: .net wcf wcf-client

我正在连接到Soap1.1服务。这是一个使用行业标准接口定义的预先存在的服务(名为MultiSpeak,在实用程序空间中非常常见)

MultiSpeak标准不包含传递此供应商所需的CustomerID的规定,因此他们稍微修改了SoapEvenelope。我的问题是我无法说服如何说服WCF发出正确的XML。

我目前的信封看起来像这样:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:MultiSpeakMsgHeader UserID="****" Pwd="****" Company="****"
      xmlns="http://www.multispeak.org/Version_3.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:h="http://www.multispeak.org/Version_3.0" />
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetAMRSupportedMeters xmlns="http://www.multispeak.org/Version_3.0" />
  </s:Body>
</s:Envelope>

这就是我需要它看起来像工作:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:MultiSpeakMsgHeader UserID="****" Pwd="****" Company="****"
      vendor:CustomerID="StringValue"
      xmlns="http://www.multispeak.org/Version_3.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:h="http://www.multispeak.org/Version_3.0" 
      xmlns:vendor="http://www.MyVendor.com/Multispeak3"/>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetAMRSupportedMeters xmlns="http://www.multispeak.org/Version_3.0" />
  </s:Body>

因此引入了一个新的命名空间(我的供应商的自定义命名空间)并且在现有的“MultiSpeakMsgHeader”对象上引入了一个名为“CustomerID”的新属性,但是表示该属性的XML中的属性位于不同的NameSpace中

他们为我提供的WSDL(标准MultiSPeak WSDL)不会生成这个。

我觉得将“CustomerID”作为字符串属性添加到reference.cs中的MultiSpeakMsgHeader对象很容易,但是它不会使用正确的xmlns装饰发出,因此不起作用(是的,我测试过......没有命名空间,没有爱情。)

我很茫然。我尝试调整他们的WSDL并重新生成以使其工作,但没有运气。

任何提示,我一定会感激不尽。我已经失去了太多时间来解决这个问题。

谢谢大家。

1 个答案:

答案 0 :(得分:1)

您可以尝试构建自己的soap标头。下面是一些示例代码:

using (OperationContextScope scope = new OperationContextScope(objService.InnerChannel))

        {
            UsernameToken objUsernameToken = new UsernameToken() { Username = "rajesh", Password = "rajesh" };
            List<Type> obj = new List<Type>();
            obj.Add(typeof(UsernameToken));

            //XmlObjectSerializer ser = new DataContractSerializer(typeof(Security), "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", obj);

            XmlObjectSerializer ser = new CustomXmlSerializer(typeof(Security), "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            Security security = new Security();
            security.UsernameToken = objUsernameToken;

            MessageHeader header = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
                                                              security, ser, false);

            OperationContext.Current.OutgoingMessageHeaders.Add(header);

            try
            {   
                //Would get a exception but the response was successful. You can see that in fiddler. 
                //The cause for the exception is that the response has the security elements mustUnderstand set to 1 chagning that to 0 would resolve the problem. Need to find on how to do that
                string response = objService.GetInformation();
            }
            catch (Exception ex)
            {
                OperationContext.Current.IncomingMessageHeaders.RemoveAll("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");   
                //throw;
            }

        } 

希望您能够根据自己的要求选择上面的代码。