Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke a SOAP method with namespace prefixes

My C# web service client sends following soap message to Java-based web service:

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

and Java-based web service returns error:

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

Client written in Java, which works, sends the following message:

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

Is there an easy way in C# to send SOAP messages the same way Java client sends: with namespace prefixes?

Following is C# code that sends message:

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

RequestMessage request = new RequestMessage();
...

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

UPDATE:

Here is RequestMessage class:

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

UPDATE #2:

The reason why Java-based web service didn't like my C# client produced SOAP message is not omission of namespace prefixes, but only because of omission of xmlns in getData element, so if my message looks like this:

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

it works!

I managed to put xmlns inside getData by manually editing SoapRpcMethodAttribute in wsdl.exe-produced source code. Here is excerpt:

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

    ...
}

Before my change, SoapRpcMethodAttribute had following constructor:

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

Now, the question is: what to put in WSDL file so that SoapRpcMethodAttribute have those strings in constructor (filled by the wsdl.exe tool) in the first place?

like image 321
mvladic Avatar asked May 04 '26 20:05

mvladic


1 Answers

I've seen this problem before where the WSDL.exe tool did not properly pull in the namespace when generating the service code. Check the request object definition in your generated code. My guess is that there is no XmlRootAttribute attribute defined on the class definition for the request object.

Adding the attribute [XmlRootAttribute(Namespace "http://a...")] to the class definition for the request object should fix this issue.

As a side note, I recommend adding this additional attribute in a separate code file using a partial class definition. Defining the attribute in a separate file will allow you to regenerate the web service code using WSDL.exe whenever neccessary without overwriting the fix to set the root element's namespace properly.

like image 199
pmartin Avatar answered May 07 '26 08:05

pmartin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!