Search code examples
androidwcfksoap2

Server receives null when sending complex type from android client to wcf service


I am using ksoap2 library for connecting to a wcf web service. When I try to send primitive types, server gets these values and send a correct response. However, if I try to send a complex type ( an object that is a subtype of KVMSerilizable ) the server receives null. Below is the class definition of the object that I want to send.

import java.util.Hashtable;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class TwoIntegerWrapper implements KvmSerializable {

    private int Num1;
    private int Num2;

    public TwoIntegerWrapper() {
        super();
    }

    TwoIntegerWrapper(int number1, int number2) {
        super();
        this.Num1 = number1;
        this.Num2 = number2;
    }

    public int getNumber1() {
        return Num1;
    }

    public void setNumber1(int number1) {
        this.Num1 = number1;
    }

    public int getNumber2() {
        return Num2;
    }

    public void setNumber2(int number2) {
        this.Num2 = number2;
    }

    public Object getProperty(int propertyNumber) {

        Object property = null;

        switch (propertyNumber) {
        case 0:
            property = this.Num1;
            break;

        case 1:
            property = this.Num2;
            break;

        }

        return property;
    }

    public int getPropertyCount() {
        return 2;
    }

    public void getPropertyInfo(int propertyNumber, Hashtable arg1,
            PropertyInfo propertyInfo) {

        switch (propertyNumber) {
        case 0:
            propertyInfo.type = PropertyInfo.INTEGER_CLASS;
            propertyInfo.name = "Num1";
            break;
        case 1:
            propertyInfo.type = PropertyInfo.INTEGER_CLASS;
            propertyInfo.name = "Num2";
            break;
        }

    }

    public void setProperty(int propertyNumber, Object data) {
        switch (propertyNumber) {

        case 0:
            this.Num1 = Integer.parseInt(data.toString());
            break;
        case 1:
            this.Num2 = Integer.parseInt(data.toString());
            break;
        }

    }
}

And here is how I call web service.

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

PropertyInfo property = new PropertyInfo();
TwoIntegerWrapper tiw = new TwoIntegerWrapper(num1Value, num2Value);

property.setName("TwoIntegerWrapper");
property.setType(tiw.getClass());
property.setValue(tiw);

request.addProperty(property);

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

envelope.addMapping(NAMESPACE, tiw.getClass().getSimpleName(), TwoIntegerWrapper.class);

HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;

try {
    androidHttpTransport.call(Add_SOAP_ACTION, envelope);

    Log.d(logtag + " request dump", androidHttpTransport.requestDump);
    Log.d(logtag + " response dump", androidHttpTransport.responseDump);


   SoapPrimitive sp = (SoapPrimitive) envelope.getResponse();
   result = Integer.parseInt(sp.toString());
}

What are the possible reasons?


Solution

  • I found the solution by changing getPropertyInfo function of TwoIntegerWrapper class. I also set namespaces for each property in this class. The new implementation is the following:

    public void getPropertyInfo(int propertyNumber, Hashtable arg1,
            PropertyInfo propertyInfo) {
    
        switch (propertyNumber) {
        case 0:
            propertyInfo.type = PropertyInfo.INTEGER_CLASS;
            propertyInfo.name = "Num1";
            propertyInfo.setNamespace(TWO_INTEGER_WRAPPER_NAMESPACE);
            break;
        case 1:
            propertyInfo.type = PropertyInfo.INTEGER_CLASS;
            propertyInfo.name = "Num2";
            propertyInfo.setNamespace(TWO_INTEGER_WRAPPER_NAMESPACE);
            break;
        }
    
    }
    

    Even if I remove mapping from the envelope, it works. I could not understand why it is so, but it works. I appreciate if someone explains the reason. Wsdl file, xsd0, xsd1 and xsd2 files are in the link http://www.ceng.metu.edu.tr/~e1559897/

    By the way, I also changed

    property.setName("TwoIntegerWrapper");  
    

    to

    property.setName("obj");