How to call a .NET Webservice from Android using KSOAP2? - android

I have a problem while calling a webservice. I have a .NET web service on the server, and I am using KSOAP2 (ksoap2-j2se-full-2.1.2) in Android. While running the program I got an runtime exception like "org.ksoap2.serialization.SoapPrimitive". What should I do?
Here is my code.
package projects.ksoap2sample;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.*;
import android.os.*;
import android.widget.TextView;
public class ksoap2sample extends Activity {
/** Called when the activity is first created. */
private static final String SOAP_ACTION = "http://tempuri.org/HelloWorld";
private static final String METHOD_NAME = "HelloWorld";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://192.168.1.19/TestWeb/WebService.asmx";
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv=(TextView)findViewById(R.id.text1);
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//request.addProperty("prop1", "myprop");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
Object result = (Object)envelope.getResponse();
String[] results = (String[]) result;
tv.setText( ""+results[0]);
}
catch (Exception e) {
tv.setText(e.getMessage());
}
}
}

It's very simple. You are getting the result into an Object which is a primitive one.
Your code:
Object result = (Object)envelope.getResponse();
Correct code:
SoapObject result=(SoapObject)envelope.getResponse();
//To get the data.
String resultData=result.getProperty(0).toString();
// 0 is the first object of data.
I think this should definitely work.

How does your .NET Webservice look like?
I had the same effect using ksoap 2.3 from code.google.com. I followed the tutorial on The Code Project (which is great BTW.)
And everytime I used
Integer result = (Integer)envelope.getResponse();
to get the result of a my webservice (regardless of the type, I tried Object, String, int) I ran into the org.ksoap2.serialization.SoapPrimitive exception.
I found a solution (workaround). The first thing I had to do was to remove the "SoapRpcMethod() attribute from my webservice methods.
[SoapRpcMethod(), WebMethod]
public Object GetInteger1(int i)
{
// android device will throw exception
return 0;
}
[WebMethod]
public Object GetInteger2(int i)
{
// android device will get the value
return 0;
}
Then I changed my Android code to:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
However, I get a SoapPrimitive object, which has a "value" filed that is private. Luckily the value is passed through the toString() method, so I use Integer.parseInt(result.toString()) to get my value, which is enough for me, because I don't have any complex types that I need to get from my Web service.
Here is the full source:
private static final String SOAP_ACTION = "http://tempuri.org/GetInteger2";
private static final String METHOD_NAME = "GetInteger2";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://10.0.2.2:4711/Service1.asmx";
public int GetInteger2() throws IOException, XmlPullParserException {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi = new PropertyInfo();
pi.setName("i");
pi.setValue(123);
request.addProperty(pi);
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
return Integer.parseInt(result.toString());
}

Typecast the envelope to SoapPrimitive:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
String strRes = result.toString();
and it will work.

You can Use below code to call the web service and get response .Make sure that your Web Service return the response in Data Table Format..This code help you if you using data from SQL Server database .If you you using MYSQL you need to change one thing just replace word NewDataSet from sentence obj2=(SoapObject) obj1.getProperty("NewDataSet"); by DocumentElement
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://localhost/Web_Service.asmx?"; // you can use IP address instead of localhost
private static final String METHOD_NAME = "Function_Name";
private static final String SOAP_ACTION = NAMESPACE + METHOD_NAME;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("parm_name", prm_value); // Parameter for Method
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope); //call the eb service Method
} catch (Exception e) {
e.printStackTrace();
} //Next task is to get Response and format that response
SoapObject obj, obj1, obj2, obj3;
obj = (SoapObject) envelope.getResponse();
obj1 = (SoapObject) obj.getProperty("diffgram");
obj2 = (SoapObject) obj1.getProperty("NewDataSet");
for (int i = 0; i < obj2.getPropertyCount(); i++) //the method getPropertyCount() return the number of rows
{
obj3 = (SoapObject) obj2.getProperty(i);
obj3.getProperty(0).toString(); //value of column 1
obj3.getProperty(1).toString(); //value of column 2
//like that you will get value from each column
}
If you have any problem regarding this you can write me..

If more than one result is expected, then the getResponse() method will return a Vector containing the various responses.
In which case the offending code becomes:
Object result = envelope.getResponse();
// treat result as a vector
String resultText = null;
if (result instanceof Vector)
{
SoapPrimitive element0 = (SoapPrimitive)((Vector) result).elementAt(0);
resultText = element0.toString();
}
tv.setText(resultText);
Answer based on the ksoap2-android (mosabua fork)

I think you can't call
androidHttpTransport.call(SOAP_ACTION, envelope);
on main Thread.
Network operations should be done on different Thread.
Create another Thread or AsyncTask to call the method.

Related

Android Web Service connenction Error

I created Java web services and trying to connect with android code.I am getting the service running but android app is showing error in soap object creating for namespace and method name.I did all the changes and everything is correct namespace,method name,URL all is correct.But I don't know what is wrong can anyone help me out...!
My android code is----->
showing error in
-"SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);"
public class RetailerActivity extends Activity {
private static final String SOAP_ACTION = "urn:training/searchCompanyInfo";
private static final String METHOD_NAME = "searchCompanyInfo";
private static final String NAMESPACE = "urn:training/";
private static final String URL = "http://localhost/attest/CompanyInfoService?wsdl";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println(NAMESPACE);
System.out.println(METHOD_NAME);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(URL);
try {
ht.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
SoapPrimitive s = response;
String str = s.toString();
String resultArr[] = str.split("&");//Result string will split & store in an array
TextView tv = new TextView(this);
for(int i = 0; i<resultArr.length;i++){
tv.append(resultArr[i]+"\n\n");
}
setContentView(tv);
} catch (Exception e) {
e.printStackTrace();
}
}
}
In Android, You cannot perform network operation on the main thread, You need to execute your soap request in a background thread. Please read up on AsyncTask.

android send data to a .net webservice

I am trying to create a android app to send text and photos to .net webservice. I have functions in my webservice. one of them gets a dummy name(I created this to check if I can make a connection) and the other one is to insert some data into DB. I want to post my work to get help.
private final String NAMESPACE = "http://methodoor.com/";
//webservice is working, you can check it online
private final String URL = "http://servicing2.rotanet.com.tr/service.asmx";
private final String SOAP_ACTION = "http://methodoor.com/checkupservice/SendData";
private final String METHOD_NAME = "SendData";
//Create request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("containerId",1);
.........
.........
request.addProperty("sFileID","asd");
request.addProperty("userId",1);
//Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
//Set output SOAP object
envelope.setOutputSoapObject(request);
//Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
//Invole web service
androidHttpTransport.call(SOAP_ACTION, envelope);
//Get the response
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
//Assign it to fahren static variable
fahren = response.toString();
} catch (Exception e) {
}
My problem is, I am not sure if this is the correct way to pass data to webservice. it doesnt crash or gives any error message. It just doesnt insert into the DB
here you go..make sure to check spelling of each tag in your service, method name and path of your service..
public SoapObject soap(String METHOD_NAME, String SOAP_ACTION, String NAMESPACE, String URL,String IP,String SERVICEPATH) throws IOException, XmlPullParserException
{
abc.allowAllSSL();
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); //set up request
//request.addProperty("iTopN", "5"); //variable name, value. I got the variable name, from the wsdl file!
request.addProperty("UserId", login);
request.addProperty("Password", password);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); // put all required data into a soap
envelope.dotNet = true;
envelope.setOutputSoapObject(request); // prepare request
envelope.bodyOut = request;
Log.d("ENVELOPE",""+"Coming3");
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//androidHttpTransport.
androidHttpTransport.call(SOAP_ACTION, envelope);
Log.d("ENVELOPE",""+envelope.bodyIn);
SoapObject result = (SoapObject) envelope.bodyIn; // get response
Log.d("ENVELOPE",""+envelope.bodyIn);
SoapObject responseBodyRaw,responseBody,tableRow;
return result;
}
Here is parameter details
private String NAMESPACE = "http://tempuri.org/";
private String SOAP_ACTION = "http://tempuri.org/UserProfile";
private String METHOD_NAME = "UserProfile";
private String URL="https://172.17.60.15/HostingService/PhoneForService.asmx";
//private String URL="https://172.19.2.250/testService/phone.asmx";
private String SERVICEPATH="/HostingService/PhoneForService.asmx";
I hope would be helpful for you

How do I use parameters with ksoap2?

I have created a web service to test passing parameters via ksoap2. I thought it seemed like a pretty simple process, but I'm apparently missing something simple. The web service does nothing more than return the integer that is passed to it. When I execute the code below it returns the number 0 instead of 1.
private static String SOAP_ACTION = "http://tempuri.org/TestParams";
private static String NAMESPACE = "http://tempuri.org/";
private static String METHOD_NAME = "TestParams";
private static String URL = "http://services.lockrem.com/WebService.asmx?WSDL";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("RoundId", 1);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
} catch (Exception e) {
e.printStackTrace();
}
SoapObject result = (SoapObject)envelope.bodyIn;
Note: I have tested this using a .net web page and it returns the number 1 as expected. The web service is not the issue here.
Here is the web service.
[WebMethod]
public int TestParams(int RoundId)
{
return RoundId;
}
Thank you for any help.
Disclaimer: Whenever I try to talk to a .NET webservice using kSoap2, I usually end up doing a lot of fiddling. And I mean that literally: I setup a windows machine with Fiddler2 and use that as a proxy for both the failing request and a working reference request, so I can actually see what's going wrong. I strongly advise doing something similar as soon as you try to do something non-trivial.
That said, in your case, it might be enough to do
envelope.dotNet = true;
Try removing the WSDL at the end
private static String URL = "http://services.lockrem.com/WebService.asmx";
In addition try using this to get the response:
Object response = envelope.getResponse();
instead of SoapObject result = (SoapObject)envelope.bodyIn;
EDITED
This works:
public class MainActivity extends Activity {
private static String NAMESPACE = "http://tempuri.org/";
private static String METHOD_NAME = "TestParams";
private static String URL = "http://services.lockrem.com/WebService.asmx";
private TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.tv);
HttpTransportSE transport = new HttpTransportSE(URL);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("RoundId", 1);
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
try {
transport.call(NAMESPACE + METHOD_NAME, envelope);
Object response = envelope.getResponse();
tv.setText(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Hope it helps.

get multiple data from webservice using SOAP in android

Im getting single data from web service using SOAP in android and displayed well.But when i need to retrieve multiple set of values from web services..How could i do that?For ex.from a webservice.,im getting 10 set of student records with fields stu.Name,stuRegno.,stuAge.After getting response of this.,i need to parse it to stored into local db with corresponding field names.How could i do that?
My code:
public class Main extends Activity {
private static final String METHOD_NAME = "TopGoalScorers";
private static final String SOAP_ACTION = "http://footballpool.dataaccess.eu/data/TopGoalScorers";
private static final String NAMESPACE = "http://footballpool.dataaccess.eu";
private static final String URL = "http://footballpool.dataaccess.eu/data/info.wso?WSDL";
//Called when the activity is first created.
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
//Buttons deaktiviert alles automatisch
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("iTopN", 3);// username von Preferences abgeholt
//request.addProperty("intB", 4);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
Toast.makeText(getApplicationContext(), request.toString(), Toast.LENGTH_LONG).show();
envelope.setOutputSoapObject(request);
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport (URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
//Parse Response
SoapObject resultsRequestSOAP = (SoapObject) envelope.getResponse();
String xy = resultsRequestSOAP.getProperty(0).toString();
((TextView)findViewById(R.id.lblStatus)).setText(xy);
} catch(Exception E) {
((TextView)findViewById(R.id.lblStatus)).setText("ERROR:" + E.getClass().getName() + ": " + E.getMessage());
}
}
}
I don't understand what is your problem. You need to convert resultsRequestSOAP to appropriate data format(for example String) and parse it(for example through SAX) and in your parser collect all data in a container(for example List).

Android: soap primitive error

I am having some issues with accessing a web service. Getting ClassCastException Error. Consider a scenario that I am trying to access a method of a web-service and the webservice is supposed to return two strings (Lets say String1 and String2). Moreover, I have to provide or pass two parameters (lets say Parameter 1 and Parameter 2 where Parameter 1 should be integer and Parameter 2 should be String) Here is my code
public class MyWebService extends Activity {
private static final String SOAP_ACTION ="http://www.mywebsite.com/myMethod";
private static final String METHOD_NAME = "MyMethod";
private static final String NAMESPACE = "http://www.myNamespace/";
private static final String URL = "http://mysession.com/myservice.asmx?WSDL";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi = new PropertyInfo();
pi.setName("Parameter 1");
pi.setValue(1);
pi.setType(pi.INTEGER_CLASS);
request.addProperty(pi);
PropertyInfo pi2 = new PropertyInfo();
pi2.setName("Parameter 2");
pi2.setValue("Any string");
pi2.setType(pi2.STRING_CLASS);
request.addProperty(pi2);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject result=(SoapObject)envelope.getResponse();
String string1=result.getProperty(0).toString();
String string2=result.getProperty(1).toString();
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is the exception I am getting
java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive
Can anyone tell me if I am doing something wrong here..
Thanks
Try this,
SoapPrimitive result= (SoapPrimitive)envelope.getResponse();
OR
Object result= (Object)envelope.getResponse();
instead of
SoapObject result=(SoapObject)envelope.getResponse();
Try this:
SoapObject request = new SoapObject(SOAP_NAMESPACE,SOAP_METHOD);
request.addProperty("name", abcd);
request.addProperty("age", 30);

Categories

Resources