androidksoap2android-ksoap2ksoap

Making complex requests with Ksoap Android


I'm trying to make a requests with nested array of objects, the wsdl look like this:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
  <SOAP-ENV:Body>
    <ns1:PopulateCart>
      <ns1:sc>
        <ns1:CustomerID>52</ns1:CustomerID>
        <ns1:Email>testing@gmail.com</ns1:Email>
        <ns1:Contact>0161234444</ns1:Contact>
        <ns1:RestaurantID>251</ns1:RestaurantID>
        <ns1:TimePickup>2015-03-21T23:59:00</ns1:TimePickup>
        <ns1:VoucherCode></ns1:VoucherCode>
        <ns1:FoodItems>
          <ns1:FoodMainItem>
            <ns1:product_id>20754</ns1:product_id>
            <ns1:qty>1</ns1:qty>
          </ns1:FoodMainItem>
        </ns1:FoodItems>
        <ns1:FoodItems>
          <ns1:FoodMainItem>
            <ns1:product_id>20754</ns1:product_id>
            <ns1:qty>2</ns1:qty>
          </ns1:FoodMainItem>
        </ns1:FoodItems>
      </ns1:sc>
    </ns1:PopulateCart>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I'm using ksoap2 library for Android, what I tried:

    // ApiConstant.java
    public static final String NAMESPACE = "http://tempuri.org/";
    public static final String KSOAP_BASE_URL = "http://dedev.delivereat.my/Onappservice.asmx";

    //PopulateCartTask.java
    String METHOD_NAME = "PopulateCart";
    String SOAP_ACTION = ApiConstant.NAMESPACE + METHOD_NAME;
    String URL = ApiConstant.KSOAP_BASE_URL;

    SoapObject request = new SoapObject(ApiConstant.NAMESPACE, METHOD_NAME);
    SoapObject sc = new SoapObject(ApiConstant.NAMESPACE,"sc");

    //CHANGE2
    PropertyInfo pi = new PropertyInfo();
    pi.setName("CustomerID");
    pi.setValue(52); //1
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("Email");
    pi.setValue("serene@greenroom.com.my"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("Contact");
    pi.setValue("0161235555"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("RestaurantID");
    pi.setValue("251"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("Email");
    pi.setValue("serene@greenroom.com.my"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("TimePickup");
    pi.setValue("2015-03-21T23:59:00"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("VoucherCode");
    pi.setValue(""); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    SoapObject foodItems = new SoapObject(ApiConstant.NAMESPACE, "FoodItems");
    SoapObject FoodMainItem = new SoapObject(ApiConstant.NAMESPACE, "FoodMainItem");

    pi = new PropertyInfo();
    pi.setName("product_id");
    pi.setValue("20754"); //2
    pi.setType(String.class);
    FoodMainItem.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("qty");
    pi.setValue("1"); //2
    pi.setType(String.class);
    FoodMainItem.addProperty(pi);

    foodItems.addSoapObject(FoodMainItem);
    sc.addSoapObject(foodItems);
    request.addSoapObject(sc);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request);

    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    androidHttpTransport.call(SOAP_ACTION, envelope);
    SoapObject response = (SoapObject) envelope.getResponse();

But I'm getting the following error:

03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ SoapFault - faultcode: 'soap:Client' faultstring: 'Server was unable to read request. ---> There is an error in XML document (1, 294). ---> The specified type was not recognized: name='sc', namespace='http://tempuri.org/', at <sc xmlns='http://tempuri.org/'>.' faultactor: 'null' detail: org.kxml2.kdom.Node@28028932
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:147)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:140)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.Transport.parseResponse(Transport.java:118)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:275)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:118)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:113)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at com.deliver.eat.async.PopulateCartTask.doInBackground(PopulateCartTask.java:203)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at com.deliver.eat.async.PopulateCartTask.doInBackground(PopulateCartTask.java:20)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at java.lang.Thread.run(Thread.java:818)

I suspect it is something to do with the SoapObject namespace, I checked many links, and tried out a few different ways, but non of them is working:

Question: what is the correct way to make this request?

I'm stuck for quite some time, any help is greatly appreciated!


Solution

  • I couldn't find my answer on how to do it with ksoap library, so I ended up doing POST request using volley library to achieve the same, after getting the response, I parsed the response manually using xml parser.

    So this is the code I wrote: https://gist.github.com/worker8/20eb5bd3400b88f10973

    How I used this code:

    PriceConfirmationTask.Callback callback = new PriceConfirmationTask.Callback(){
        @Override
        public void onResponse(PriceCheckResult result) {
    
        Log.d("ddw", "result: " + result.toString());
    
        if (result != null) {
            showPriceConfirmationDialog(result);
        } else {
            Toast.makeText(mActivity, "Sorry, something went wrong... ", Toast.LENGTH_LONG).show();
        }}};
    
    PriceConfirmationTask task = new PriceConfirmationTask(mActivity, "2015-04-01T13:00:00", callback);
    task.callEndpoint();
    

    There might be a better way to do it, but if you are stuck like I did, this might be a good solution.

    Hope it helps!