3

I have spent several days trying to figure out how can I make my user defined java class serializable, so that i can send it as a parameter in android ksoap call to c# web method . Below is my code and the exceptions thrown in logcat when calling the webservice , I would be thankful if i get an immediate answer or help .

My java class XY.java:

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

public class XY implements KvmSerializable {
    public static Class XY_CLASS = XY.class;
    private String MyNum;
    private String OppPhoneNum;
    private String Name;

    public XY()
    {

    }
    public XY(String MyNum, String Name, String oppNum)
    {
        this.MyNum = MyNum;
        this.Name = Name;
        this.OppPhoneNum = oppNum;
    }

    public String getPhoneNum() {
        return MyNum;
    }
    public void setPhoneNum(String MyNum) {
        this.MyNum = MyNum;
    }
    public String getName() {
        return Name;
    }
    public void setName(String Name) {
        this.Name = Name;
    }
    public String getOpponentPhoneNum() {
        return OppPhoneNum;
    }
    public void setOpponentPhoneNum(String OppPhoneNum) {
        this.OppPhoneNum = OppPhoneNum;
    }
    @Override
    public Object getProperty(int arg0) {

        switch(arg0)
        {
        case 0:
            return MyNum;
        case 1:
            return OppPhoneNum;
        case 2:
            return Name;
        }

        return null;
    }
    @Override
    public int getPropertyCount() {
        // TODO Auto-generated method stub
        return 3;
    }
    @Override
    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {



        switch(index)
        {
        case 0:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "MyNum";
            break;
        case 1:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "OppPhoneNum";
            break;
        case 2:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "Name";
            break;
        default:break;
        }
    }
    @Override
    public void setProperty(int index, Object value) {


        switch(index)
        {
        case 0:
            MyNum = value.toString();
            break;
        case 1:
            OppPhoneNum = value.toString();
            break;
        case 2:
            Name = value.toString();
            break;
        default:
            break;
        }
    }
}

C# equivalent class:

[Serializable]
public class XY
    {

        public System.String Name
        {
            get;
            set;
        }
        public System.String MyNum
        {
            get;
            set;
        }
        public System.String OppPhoneNum
        {
            get;
            set;
        }
    }

And this is how i am calling the service using ksoap from my activity:

private void unKnown(List<XY> entries) 
    {

         //Initialize soap request + add parameters
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

        PropertyInfo entriesProp =new PropertyInfo();
        entriesProp.setName("entries");          
        entriesProp.setValue(entries);
        entriesProp.setType(ArrayList.class);


        //Use this to add parameters
        request.addProperty(entriesProp);
        //Declare the version of the SOAP request

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.setOutputSoapObject(request);
        envelope.addMapping(NAMESPACE, "XY", XY.XY_CLASS);

        envelope.dotNet = true;

        try {

              HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

              //this is the actual part that will call the webservice

              androidHttpTransport.call(SOAP_ADDCONTACTS, envelope);

              // Get the SoapResult from the envelope body.

              if (envelope.bodyIn instanceof SoapFault) 
              {
                  String str= ((SoapFault) envelope.bodyIn).faultstring;
                  Log.i("", str);
              } 
              else 
              {
                  SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
                  if(resultsRequestSOAP != null)
                  {
                      Log.i("AddContacts", "Adding Contacts succeeded");
                  }
              }
        }
        catch (Exception e)
        {
              e.printStackTrace();
        }
    }**

Logcat Exception :

java.lang.RuntimeException: Cannot Serialize: [XY .....** 

Note : i am trying to pass list of XY objects as parameter to the web service method . I would appreciate any help .

jbihan
  • 3,053
  • 2
  • 24
  • 34
Hussein Terek
  • 588
  • 9
  • 13

2 Answers2

3

I have edited my example and add new and full example for you that I think it can help you. In this example I have a customer table in server side database and I want to insert data from android to this table via KvmSerializable user defined class. Here is KvmSerializable user defined class for customers:

public class Customer implements KvmSerializable {
public int Customer_ID;
public String Customer_Name;
public String Customer_Family;

public Customer() {
}

public Customer(int customer_id,
                String customer_name, 
                String customer_family) {

    Customer_ID = customer_id;
    Customer_Name = customer_name;
    Customer_Family = customer_family;
}

public Object getProperty(int arg0) {
    // TODO Auto-generated method stub
    switch (arg0) {
    case 0:
        return Customer_ID;
    case 1:
        return Customer_Name;
    case 2:
        return Customer_Family;


    }
    return null;
}

public int getPropertyCount() {
    // TODO Auto-generated method stub
    return 25;
}

public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
    // TODO Auto-generated method stub
    switch (index) {
    case 0:
        info.type = PropertyInfo.INTEGER_CLASS;
        info.name = "Customer_ID";
        break;
    case 1:
        info.type = PropertyInfo.STRING_CLASS;
        info.name = "Customer_Name";
        break;
    case 2:
        info.type = PropertyInfo.STRING_CLASS;
        info.name = "Customer_Family";
        break;
    default:
        break;

    }
}

public void setProperty(int index, Object value) {
    // TODO Auto-generated method stub
    switch (index) {
    case 0:
        Customer_ID = Integer.parseInt(value.toString());
        break;
    case 1:
        Customer_Name = value.toString();
        break;
    case 2:
        Customer_Family = value.toString();
        break;
    default:
        break;
    }

}

}

And now c# user defined class for customers:

    public class Customer
    {
        public int Customer_ID;
        public string Customer_Name;
        public string Customer_Family;
    }

Here is CallSoap class that I defined for send KvmSerializable object via this:

public class CallSoap {
public static String NAMESPACE = "http://127.0.0.1:80/";
public static String URL = "http://127.0.0.1:80/service.asmx?WSDL";
public static Customer[] customers;
public static int AddCustomer(Customer[] customers) {
    String MethodName = "AddCustomer";
    SoapObject soapAddCustomer = new SoapObject(NAMESPACE, MethodName);
    //customers Parameter
    SoapObject soapDetails = new SoapObject(NAMESPACE, "customers");
    SoapObject soapDetail[] = new SoapObject[customers.length];

    for (int i=0;i<customers.length;i++){
        soapDetail[i]= new SoapObject(NAMESPACE, "Customer");
        soapDetail[i].addProperty("Customer_ID", customers[i].Customer_ID);
        soapDetail[i].addProperty("Customer_Name", customers[i].Customer_Name);
        soapDetail[i].addProperty("Customer_Family", customers[i].Customer_Family);

    }

    soapAddRequest.addSoapObject(soapDetails);
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11);
    envelope.dotNet = true;
    envelope.setOutputSoapObject(soapAddRequest);
    envelope.addMapping(NAMESPACE, "Customer", new Customer().getClass());
    HttpTransportSE HttpTransportSE = new HttpTransportSE(URL);
    try {
        HttpTransportSE.call(NAMESPACE + MethodName, envelope);
        String result = envelope.getResponse().toString();
        return Integer.parseInt(result);
    } catch (Exception e) {
        e.printStackTrace();
        return 0;

        }
}

and finally the AddCustomer method in server side:

[WebMethod]
public int AddCustomer(Customer[] customers)
{

    for(int i=0;i<customers.Length;i++){
        //Access to customer fields for allrows via 
        int id = customers[i].Customer_ID;
        String name = customers[i].Customer_Name;
        String = customers[i].Customer_Family;
    }
    return customers.Length;

}
Majid Daeinejad
  • 1,037
  • 8
  • 19
  • Your point is to make the same order for the properties(Name,MyNum, OppPhoneNum) in c# and java class right ? but at least it should pass the serialize process and then after that data switch will be witnessed . since they are all of the same type String – Hussein Terek Oct 28 '13 at 09:39
  • I have tested this way and I can send array of object from this user defined class. what is your general purpose of using this? is this to send an array of object? – Majid Daeinejad Oct 28 '13 at 09:43
  • Yes , i am trying to send list of XY objects . Thanks for your efforts i'll try it and let you know if it works for me. – Hussein Terek Oct 28 '13 at 10:27
  • hey Majid, I tried the same classes above and still showing the same exception : " Cannot Serialize ", Can you please show me how are you building your ksoap request in order to send list of objects? – Hussein Terek Oct 28 '13 at 21:44
  • hey @HousseinLterek, I have edited my example. you can now check my full example. – Majid Daeinejad Oct 29 '13 at 09:33
  • Can you look into [`this`](http://stackoverflow.com/questions/25377225/send-data-to-wcf-from-android-using-ksoap2) – Gunaseelan Aug 23 '14 at 12:02
  • Tried your method. No exception but the server get zero size of the object array. Any idea? @MajidDaeiNejad – sky91 Jan 20 '16 at 17:06
  • Create new question because it needs to see your code. @sky91 – Majid Daeinejad Jan 22 '16 at 15:21
  • @MajidDaeiNejad I have solved after added these line: soapEnvelope.addMapping("http://xxx.xxx.com/","list",new VectorMeterUsage().getClass()); MarshalFloat marshalFloat = new MarshalFloat(); marshalFloat.register(soapEnvelope); – sky91 Jan 23 '16 at 17:16
0

I think the validate as correct example is incomplete. You must do something with the object 'soapDetail' (CallSoap class), adding it to the object 'soapDetails' or something, because if I did not send empty array.

EDITED:

This line of code missing on for iterator to complete Majid Daei Nejad example:

soapDetails.addSoapObject(soapDetail[i]);
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
  • Please add the missing line of code as a comment on Majid's answer. :) – Barett Jan 27 '16 at 19:46
  • The first paragraph should be added as a comment on the original question. As such, this is not a standalone answer. – Barett Jan 27 '16 at 19:47