如何解决 Soap header 操作不被理解?

How to resolve Soap header action not understood?

我正在为 Windows Mobile 6.5 Professional 在 VS2008 上开发我收到此错误消息“Soap header 操作不理解”

我看到很多 post 关于这个主题,但 none Windows 移动版。

如有任何帮助,我们将不胜感激。

Link 到 URL 与 XML 数据

https://silulumanzi.4most.co.za:4343/SIZA.svc?wsdl

Rene 如何以及 silulumanzi.4most.co.za:4343/SIZA.svc 建议的内容?

public void GetOpenPO()
    {
        //Get open purchase order numbers and populate combo box

        try
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.Security.Mode = BasicHttpSecurityMode.Transport;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
            //binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
            EndpointAddress ea = new EndpointAddress(new Uri("https://silulumanzi.4most.co.za:4343/SIZA.svc?wsdl"));

            SizaWS.SIZA client = new SizaWS.SIZA();

            string[] Response = client.GetOpenPO();

            //Popuplate combo box with data received from web service
            comboBox2.Items.Add("");
            for (int i = 0; i < Response.Length; i++)
            {
                if ((!String.IsNullOrEmpty(Response[i])))
                {
                    comboBox2.Items.Add(Response[i]);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error");
        }
    }

无服务参考

我添加的配置文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_ISIZA" closeTimeout="00:01:00" openTimeout="00:01:00"
        receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
        transactionFlow="false" hostNameComparisonMode="StrongWildcard"
        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
        allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
          enabled="false" />
      <security mode="Transport">
        <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true"
            establishSecurityContext="true" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="https://silulumanzi.4most.co.za:4343/SIZA.svc"
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ISIZA"
      contract="ISIZA" name="WSHttpBinding_ISIZA" />
</client>
</system.serviceModel>
</configuration>

错误列表

版本System.ServiceModel

我没有完全工作的 VS2008,但我已经重现了您的问题,这里是解决您在一个特定调用(在本例中为 GetOpenPO)时遇到的问题的步骤。这是一个黑客。我暂时找不到更好的解决方案。

首先,删除 Web 参考和服务参考以及您根据我的评论添加的任何文件。

将文本文件 'GenClient.xml' 添加到您的项目并输入以下选项(基于找到的文档 here

<?xml version="1.0" encoding="utf-8" ?>
<wsdlParameters xmlns="http://microsoft.com/webReference/">
  <webReferenceOptions>
    <verbose>false</verbose>
    <codeGenerationOptions>properties oldAsync</codeGenerationOptions>
    <style>client</style>
  </webReferenceOptions>
</wsdlParameters>

保存后,服务客户端生成了 .Net 1.1 风格的 Begin/EndInvoke 方法,省略了 System.Threading.

的任何使用

打开 Visual Studio 2008 命令提示符。将目录更改为您的项目目录。 运行 以下命令生成一个 SIZA.cs class 将作为您的 soap 客户端(它采用先前创建并保存的 genclient.xml 作为参数文件):

这将覆盖您当前的 SIZA.cs。 Re-apply之后变化

wsdl /out:SIZA.cs /protocol:soap12 /parameters:genclient.xml https://silulumanzi.4most.co.za:4343/SIZA.svc?wsdl

您的项目文件夹中现在将有一个 SIZA.cs 文件。

在 Visual Studio 2008 年打开您的项目。 在解决方案资源管理器中,right-click 您的项目,添加现有项并在文件对话框中找到项目根文件夹中的 SIZA.cs。

在解决方案资源管理器中,右键单击引用,选择“添加引用”,等待对话框加载,然后从 .Net 选项卡中找到 select 程序集 System.Web.Services,单击确定.

您的解决方案现在应该可以正确编译。

黑客攻击从这里开始:/

在SIZA.cs文件中找到以下方法:

public string[] GetOpenPO() {

在该方法之前添加此属性:

[System.Web.Services.Protocols.SoapHeader("Soap12HdrGetOpenPO", Direction = SoapHeaderDirection.InOut)]

您的最终结果应如下所示:

/// <remarks/>    
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/ISIZA/GetOpenPO", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlArrayAttribute(IsNullable=true)]
[return: System.Xml.Serialization.XmlArrayItemAttribute(Namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays")]

[System.Web.Services.Protocols.SoapHeader("Soap12HdrGetOpenPO", Direction = SoapHeaderDirection.InOut)]

public string[] GetOpenPO() {
    object[] results = this.Invoke("GetOpenPO", new object[0]);
    return ((string[])(results[0]));
}

创建一个新的 Class 文件并将其命名为:SIZA.Partial.cs

在该新文件中添加以下代码,替换其中的所有内容:

using System.Web.Services.Protocols;
using System.Xml;

public partial class SIZA
{

    private SoapUnknownHeader CreateSoapAcionHeader(string hdr, string value)
    {
        var xd = new XmlDocument();
        var sh = new SoapUnknownHeader();
        sh.MustUnderstand = true;
        sh.Element = xd.CreateElement(hdr, "http://www.w3.org/2005/08/addressing");
        sh.Element.InnerText = value;
        return sh;
    }

    // this method gets called due to the added SoapHeader attribute
    public SoapUnknownHeader[] Soap12HdrGetOpenPO
    {
        get
        {
            return new[]
                {
                    CreateSoapAcionHeader("Action", "http://tempuri.org/ISIZA/GetOpenPO"), 
                    CreateSoapAcionHeader("To", this.Url), 
                };
        }
        set { /* empty */}
    }
}

这基本上会将缺少的 SOAP12 操作和 To header 添加到 GetOpenPO 调用的 soap 信封中。这也使您调用的 WCF 服务也很愉快。

这是在线路上交换内容的 fiddler 屏幕截图:

此解决方案的缺点是您需要为要使用的 SIZA 客户端中的每个 public 方法手动执行此操作。也许其他人路过并记得应该如何利用 SoapHttpClientProtocol 中的扩展点之一。