Search code examples
androidwcfweb-servicesksoap2

Ksoap2 Android - how to specify a namespace for the child properties of a complex object?


I'm trying to upload a complex object to a WCF webservice using KSoap2 Android and having some difficulty doing this. I have achieved successful calls to the webservice when I use SoapUI and fill in the data by hand. The successful SoapUI-generated request is as follows:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:fpm="http://schemas.datacontract.org/2004/07/FPMobileServices">
<soapenv:Header/>
<soapenv:Body>
  <tem:CommitOne>
     <tem:qr>
        <fpm:ClientID>8aa2f6a4-4d15-4b4c-9cac-fb2478d0d27a</fpm:ClientID>
        <fpm:CreatedBy>admin</fpm:CreatedBy>
        <fpm:CreatedDate>2012-03-01T19:50:37</fpm:CreatedDate>
        <fpm:DimensionID>8a02a339-b5a7-4c76-b95f-5891ef57736d</fpm:DimensionID>
        <fpm:ImageID>b76c7bcc-a8f8-49ff-94c6-08cd2e05b1a8</fpm:ImageID>
        <fpm:IndicatorID>4637b333-701d-4d03-a708-4de48569be84</fpm:IndicatorID>
        <fpm:LoanOperationNumber>6-2011-72978</fpm:LoanOperationNumber>
        <fpm:ModifiedBy>admin</fpm:ModifiedBy>
        <fpm:ModifiedDate>2012-03-01T19:50:37</fpm:ModifiedDate>
        <fpm:QuestionaireCompletedDate>2012-03-01T19:50:54</fpm:QuestionaireCompletedDate>
        <fpm:QuestionnaireID>99967f70-8161-4922-929f-03136a389ba6</fpm:QuestionnaireID>
        <fpm:ResultID>95fa03b5-80af-479d-9dec-f2bf94baf3cd</fpm:ResultID>
        <fpm:ResultWeighting>0</fpm:ResultWeighting>
        <fpm:StatusLevelID>03a91cd6-93cd-4503-a676-efa2967e82a7</fpm:StatusLevelID>
        <fpm:UploadID>141D6A1F-8FFD-4CA4-8073-009338F22B13</fpm:UploadID>
     </tem:qr>
  </tem:CommitOne>
</soapenv:Body>
</soapenv:Envelope>

The request generated by my Java code is:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
    <CommitOne xmlns="http://tempuri.org/" id="o0" c:root="1">
        <qr>
            <ClientID>8aa2f6a4-4d15-4b4c-9cac-fb2478d0d27a</ClientID>
            <LoanOperationNumber>6-2011-72978</LoanOperationNumber>
            <CreatedBy i:null="true" />
            <CreatedDate>2012-03-01T19:50:37</CreatedDate>
            <DimensionID>8a02a339-b5a7-4c76-b95f-5891ef57736d</DimensionID>
            <ImageID>b76c7bcc-a8f8-49ff-94c6-08cd2e05b1a8</ImageID>
            <IndicatorID>4637b333-701d-4d03-a708-4de48569be84</IndicatorID>
            <ModifiedBy i:null="true" />
            <ModifiedDate i:null="true" />
            <QuestionnaireCompletedDate>2012-03-01T19:50:54</QuestionnaireCompletedDate>
            <QuestionnaireID>99967f70-8161-4922-929f-03136a389ba6</QuestionnaireID>
            <ResultID i:type="d:string">95fa03b5-80af-479d-9dec-f2bf94baf3cc</ResultID>
            <ResultWeighting>0</ResultWeighting>
            <StatusLevelID>03a91cd6-93cd-4503-a676-efa2967e82a7</StatusLevelID>
            <UploadID i:type="d:string">8ffa3665-b691-486f-91a0-ebbe8575896c</UploadID>
        </qr>
    </CommitOne>
</v:Body>

The main difference between the two seems to be the prefixes/namespaces. For some reason when the "qr" object arrives in my .NET code, all its properties are null/zero.

I have tried 2 different approaches in my java code, trying to set my "qr" object as a PropertyInfo:

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

    // build request object 
    PropertyInfo qrPi = new PropertyInfo();
    qrPi.setName("qr");
    qrPi.setType(qr.getClass());
    qrPi.setValue(qr);

    request.addProperty(qrPi); 

And also setting my "qr" as a SoapObject and then using .addProperty:

    SoapObject result = new SoapObject(NAMESPACE, "qr");
    result.addProperty("ClientID", (String) qr.getClientID());
    result.addProperty("CreatedBy", (String) qr.getCreatedBy());
    result.addProperty("CreatedDate", (String) qr.getCreatedDate());
    result.addProperty("DimensionID", (String) qr.getDimensionID());
    result.addProperty("ImageID", (String) qr.getImageID());
    result.addProperty("IndicatorID", (String) qr.getIndicatorID());
    result.addProperty("LoanOperationNumber", (String) qr.getLoanOperationNumber());
    result.addProperty("ModifiedBy", (String) qr.getModifiedBy());
    result.addProperty("ModifiedDate", (String) qr.getModifiedDate());
    result.addProperty("QuestionnaireCompletedDate", (String) qr.getQuestionnaireCompletedDate());
    result.addProperty("QuestionnaireID", (String) qr.getQuestionnaireID());
    result.addProperty("ResultID", (String) qr.getResultID());
    result.addProperty("ResultWeighting", qr.getResultWeighting());
    result.addProperty("StatusLevelID", (String) qr.getStatusLevelID());
    result.addProperty("UploadID", (String) qr.getUploadID());

    request.addSoapObject(result); 

But both of these approaches get the same result - all my "qr" object's fields are null when it gets into my webservice. I have been looking for similar questions on StackOverflow and found this but I can't figure out how to apply it to my own case.

Can anyone help shed any light on the situation?


Solution

  • Not sure if I'm supposed to answer my own question, but I've figured out a solution and will leave it here for anyone who has a similar issue.

    The key is different namespaces. In the SoapUI generated example we can see that the child elements (ClientID etc) use the fpm namespace, while the elements above them use the tem namespace. To explicitly specify the namespace for these child elements, I altered the 2nd approach discussed above - I created PropertyInfo objects for each child element and added them to the SoapObject.

    Instead of using:

    result.addProperty(String "ClientID", Object qr.getClientID());
    

    I used:

    PropertyInfo pi = new PropertyInfo();
    pi.setNamespace(QR_NAMESPACE);
    pi.setType(PropertyInfo.STRING_CLASS);
    pi.setName("ClientID");
    pi.setValue(qr.getClientID()); 
    result.addProperty(pi);
    

    When I did this with all the properties, it worked fine.

    Hope this helps someone else some day!