Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 666
breadbin Avatar asked Mar 06 '12 16:03

breadbin


1 Answers

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!

like image 195
breadbin Avatar answered Sep 18 '22 01:09

breadbin