2010-12-20 91 views
1

我的C#Web服務客戶端發送以下SOAP消息,基於Java的Web服務:調用與命名空間前綴一個SOAP方法

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Body> 
<getData> 
<request> 
<requestParameters xmlns="http://b..."> 
<equals> 
... 
</equals> 
</requestParameters> 
</request> 
</getData> 
</soap:Body> 
</soap:Envelope> 

和基於Java的Web服務將返回錯誤:

500 Internal Server Error 
... 
Cannot find dispatch method for {}getData 
... 

客戶端用Java編寫,它工作,發送以下消息:

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Body> 
<ns2:getData xmlns:ns2="http://a..."> 
<ns2:request> 
<ns3:requestParameters xmlns:ns3="http://b..."> 
<ns3:equals> 
... 
</ns3:equals> 
</ns3:requestParameters> 
</ns2:request> 
</ns2:getData> 
</soap:Body> 
</soap:Envelope> 

在C#中是否有簡單的方法發送SOAP m以Java客戶端發送的相同方式發送消息:使用名稱空間前綴?

以下是發送消息的C#代碼:

// class MyService is auto-generated using wsdl.exe tool 
MyService service = new MyService(); 

RequestMessage request = new RequestMessage(); 
... 

ResponseMessage response = service.getData(request); 
... 

UPDATE:

這裏是RequestMessage類:

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://uri.etsi.org/02657/v1.5.1#/RetainedData")] 
public partial class RequestMessage 
{ 

    private byte[] requestPriorityField; 

    private RequestConstraints requestParametersField; 

    private string deliveryPointHIBField; 

    private string maxHitsField; 

    private NationalRequestParameters nationalRequestParametersField; 

    private System.Xml.XmlElement anyField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(DataType="hexBinary", Order=0)] 
    public byte[] requestPriority 
    { 
     get 
     { 
      return this.requestPriorityField; 
     } 
     set 
     { 
      this.requestPriorityField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Order=1)] 
    public RequestConstraints requestParameters 
    { 
     get 
     { 
      return this.requestParametersField; 
     } 
     set 
     { 
      this.requestParametersField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Order=2)] 
    public string deliveryPointHIB 
    { 
     get 
     { 
      return this.deliveryPointHIBField; 
     } 
     set 
     { 
      this.deliveryPointHIBField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(DataType="integer", Order=3)] 
    public string maxHits 
    { 
     get 
     { 
      return this.maxHitsField; 
     } 
     set 
     { 
      this.maxHitsField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute(Order=4)] 
    public NationalRequestParameters nationalRequestParameters 
    { 
     get 
     { 
      return this.nationalRequestParametersField; 
     } 
     set 
     { 
      this.nationalRequestParametersField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlAnyElementAttribute(Order=5)] 
    public System.Xml.XmlElement Any 
    { 
     get 
     { 
      return this.anyField; 
     } 
     set 
     { 
      this.anyField = value; 
     } 
    } 
} 

更新#2:

之所以Java的基於Web的Web服務並不像我的C#客戶端產生的SOAP消息不會遺漏namespac Ë前綴,但在元素的getData的xmlns遺漏的,只是因爲,所以如果我的消息是這樣的:

... 
<getData xmlns="http://a..."> 
... 
</getData> 
... 

它的作品!

我通過手動編輯wsdl.exe生成的源代碼中的SoapRpcMethodAttribute來設法將xmlns放入getData中。下面是摘錄:

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Web.Services.WebServiceBindingAttribute(
    Name="AxxxPortTypeBinding", Namespace="http://a...")] 
public partial class AxxxService 
    : System.Web.Services.Protocols.SoapHttpClientProtocol { 

    ... 

    /// <remarks/> 
    [System.Web.Services.Protocols.SoapRpcMethodAttribute(
     "http://a.../getData", 
     RequestNamespace = "http://a...", 
     ResponseNamespace = "http://a...", 
     Use = System.Web.Services.Description.SoapBindingUse.Literal)] 
    [return: System.Xml.Serialization.XmlElementAttribute("response")] 
    public ResponseMessage getData(RequestMessage request) { 
     object[] results = this.Invoke("getData", new object[] { 
        request}); 
     return ((ResponseMessage)(results[0])); 
    } 

    ... 
} 

我改變之前,SoapRpcMethodAttribute了下面的構造:

[System.Web.Services.Protocols.SoapRpcMethodAttribute(
    "", RequestNamespace = "", ResponseNamespace = "", 
    Use = System.Web.Services.Description.SoapBindingUse.Literal)] 

現在的問題是:要放什麼東西在WSDL文件,以便SoapRpcMethodAttribute在構造函數的字符串(用實心wsdl.exe工具)在第一個地方?

+0

您是否使用wsdl.exe生成服務代理? – 2010-12-20 15:09:33

+0

是(請參閱問題底部的代碼註釋)。 – mvladic 2010-12-20 15:15:43

回答

1

我在WSDL.exe工具在生成服務代碼時沒有正確拉入命名空間之前就已經看到過這個問題。檢查生成的代碼中的request對象定義。我的猜測是request對象的類定義上沒有定義XmlRootAttribute屬性。

將屬性[XmlRootAttribute(Namespace "http://a...")]添加到request對象的類定義應該可以解決此問題。作爲便箋,我建議使用部分類定義在單獨的代碼文件中添加此附加屬性。在一個單獨的文件中定義屬性將允許您在需要時使用WSDL.exe重新生成Web服務代碼,而不必重寫修正以正確設置根元素的名稱空間。

+0

是的,你是對的,RequestMessage類定義中沒有XmlRootAttribute(或者在同一自動生成文件中的任何其他類中)。 – mvladic 2010-12-20 16:36:27

+0

我已經將XmlRootAttribute添加到類定義中,並沒有幫助。 – mvladic 2010-12-21 10:24:00

+0

@mvladic上面發佈的示例顯示您添加了'XmlTypeAttribute'屬性,而不是'XmlRootAttribute'屬性。鑑於您的示例SOAP請求,應將RequestMessage類標識爲要發送的XML消息的根元素。我也從你的例子中注意到服務返回一個響應(可能在ResponseMessage類中?)。您還需要使用'XmlRootAttribute'屬性修飾這個響應類,以確保使用正確的名稱空間返回響應。 – pmartin 2010-12-21 13:43:37

0

生成的代理類應該在其中包含正確的名稱空間。我推薦兩件事:

1)從命令行運行WSDL.EXE,並注意是否有任何錯誤或警告。如果是這樣,請編輯您的問題以包含它們。2)除非使用.NET 2.0,否則應該嘗試使用「添加服務引用」或等效的「SVCUTIL.EXE」來創建代理類,這些類將使用客戶端的現代WCF基礎結構,解決這個問題的可能性更大。

+0

「添加服務引用」僅適用於asmx,並且我只有一個wsdl和一個xsd文件。 – mvladic 2010-12-21 09:51:50

+0

我用「svcutil my.wsdl my.xsd/language:C#」創建了客戶端,但它仍然不起作用 - 沒有名稱空間前綴。 – mvladic 2010-12-21 10:49:02

+0

我在我的問題中添加了RequestMessage類的定義。 – mvladic 2010-12-21 10:54:49

0

我有同樣的問題,並解決它更改屬性使用的值System.Web.Services.Protocols.SoapDocumentMethodAttribute屬性corrisponding到每個Web服務方法。 System.Web.Services.Description.SoapBindingUse。 文字默認值被替換爲System.Web.Services.Description.SoapBindingUse。 編碼爲