lula / ngx-soap

Simple SOAP client for Angular
MIT License
66 stars 61 forks source link

Unable to send requests with abstract arguments #97

Closed rockwithab closed 3 years ago

rockwithab commented 3 years ago

Hello @lula, loving ngx-soap so far!

One snag that I've hit so far is being unable to send a request that includes types based on an abstract type.

Relevant wsdl snippet:

<s:element name="DoQuery">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="query" type="tns:MyQuery" />
          </s:sequence>
        </s:complexType>
</s:element>
<s:complexType name="MyQuery">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Filter" type="tns:MyQueryFilter" />
        </s:sequence>
</s:complexType>
<s:complexType name="MyQueryFilter" abstract="true" />
<s:complexType name="MyQueryByActiveFilter">
        <s:complexContent mixed="false">
          <s:extension base="tns:MyQueryFilter" />
        </s:complexContent>
</s:complexType>
<s:complexType name="MyQueryByCompletedFilter">
        <s:complexContent mixed="false">
          <s:extension base="tns:MyQueryFilter" />
        </s:complexContent>
</s:complexType>
<s:complexType name="MyQueryByIdFilter">
        <s:complexContent mixed="false">
          <s:extension base="tns:MyQueryFilter">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="Ids" type="tns:ArrayOfLong" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
</s:complexType>

When I try to make a request to this DoQuery endpoint with the following code:

    this.soap.createClient("https://mywebsite.com/my.directory/API.asmx?wsdl")
        .then(client => {
            console.log("Client", client);
            this.client = client;
        })
                .catch(err => console.log('Error', err));

    var body = {
      query: {
        Filter: {} as MyQueryByActiveFilter
      } as MyQuery
    };

    var headers = {
      SOAPAction: "http://www.mywebsite.com/MyQuery",
      "Content-Type": "application/soap+xml; charset=utf-8"
    }

    this.soap.client.call('DoQuery', body, null, headers);`

I end up with the following error:

The specified type is abstract: name='MyQueryFilter'

"<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Server was unable to read request. ---&gt; There is an error in XML document (1, 369). ---&gt; The specified type is abstract: name='MyQueryFilter', namespace='http://www.mywebsite.com/', at &lt;Filter xmlns='http://www.mywebsite.com/'&gt;.</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>"

Non abstract types seem to work just fine. I'm not sure if I'm missing special headers or just doing something plain wrong. We have a requirement to change the backend API as little as possible, so any help or tips for using abstract types would be greatly appreciated.

Brock

rockwithab commented 3 years ago

After some additional debugging, it turns out the request I was sending was missing the xsi:type attribute.

After looking at another issue resolution in this repo https://github.com/lula/ngx-soap/issues/64

I modified the body to the following and it worked:

var body = {
      query: {
        Filter: {
          attributes: {
            "xsi:type": "MyQueryByActiveFilter"
          }
        }
      }
    };