Appeler une méthode de SAVON avec des préfixes d'espace de noms

Mon C# client de service web envoie la suite dans le message soap en Java-service web:

<?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> 

et Java web service renvoie l'erreur:

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

Client écrit en Java, qui fonctionne, envoie le message suivant:

<?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> 

Est-il un moyen facile en C# pour envoyer des messages SOAP de la même manière Java client envoie: avec des préfixes d'espace de noms?

Qui suit est le code C# qui envoie un message:

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

RequestMessage request = new RequestMessage();
...

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

Mise à JOUR:

Ici est RequestMessage classe:

///<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;
}
}
}

Mise à JOUR #2:

La raison pour laquelle basé sur Java web service n'a pas aimé mon client C# produit SAVON message n'est pas d'omission de préfixes d'espace de noms, mais seulement en raison de l'omission de xmlns dans getData élément, donc si mon message ressemble à ceci:

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

ça marche!!!

J'ai réussi à mettre xmlns à l'intérieur de getData en modifiant manuellement SoapRpcMethodAttribute en wsdl.exe-produit code source. Voici l'extrait:

///<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]));
}
...
}

Avant mon changement, SoapRpcMethodAttribute avait constructeur suivant:

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

Maintenant, la question est: que mettre dans le fichier WSDL afin que SoapRpcMethodAttribute ces chaînes dans le constructeur (rempli par le wsdl.exe l'outil) en premier lieu?

  • Avez-vous générer votre service proxy avec wsdl.exe?
  • Oui (voir le commentaire dans le code, au fond de la question).
InformationsquelleAutor mvladic | 2010-12-20