Клиент веб-службы My C # отправляет следующее мыльное сообщение веб-службе на основе 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>
<getData>
<request>
<requestParameters xmlns="http://b...">
<equals>
...
</equals>
</requestParameters>
</request>
</getData>
</soap:Body>
</soap:Envelope>
и веб-служба на основе Java возвращает ошибку:
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 так же, как отправляет клиент 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 не понравился мой клиент C #, создаваемый SOAP-сообщение, является не пропуск префиксов пространства имен, а только из-за пропуска xmlns в элементе getData, поэтому, если мое сообщение выглядит так:
...
<getData xmlns="http://a...">
...
</getData>
...
это работает!
Мне удалось поместить xmlns в getData, вручную отредактировав SoapRpcMethodAttribute в исходном коде, созданном wsdl.exe. Вот выдержка:
/// <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)?