如何使用KSOAP2从Android调用.NET Web服务?

调用Web服务时遇到问题。 我在服务器上有一个.NET Web服务,我在Android中使用KSOAP2(ksoap2-j2se-full-2.1.2)。 运行程序时,我得到了一个像“org.ksoap2.serialization.SoapPrimitive”运行时exception。 我该怎么办?

这是我的代码。

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()); } } } 

这很简单。 你得到的结果是一个原始的Object

你的代码:

 Object result = (Object)envelope.getResponse(); 

正确的代码:

 SoapObject result=(SoapObject)envelope.getResponse(); //To get the data. String resultData=result.getProperty(0).toString(); // 0 is the first object of data. 

我认为这应该肯定工作。

你的.NET Web服务是怎样的?

我使用code.google.com中的ksoap 2.3来获得相同的效果。 我跟着“代码项目”的教程(这是很棒的顺便说一下)

每次我用

  Integer result = (Integer)envelope.getResponse(); 

获取我的web服务的结果(不pipetypes,我试过对象,string,诠释)我碰到了org.ksoap2.serialization.SoapPrimitiveexception。

我find了一个解决scheme(解决方法)。 我必须做的第一件事是从我的web服务方法中删除“SoapRpcMethod()属性。

  [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; } 

然后,我将我的Android代码更改为:

  SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); 

但是,我得到一个SoapPrimitive对象,它有一个私有的“值”字段。 幸运的是,值通过toString()方法传递,因此我使用Integer.parseInt(result.toString())来获取我的值,这对我来说已经足够了,因为我没有任何需要获取的复杂types从我的Web服务。

这是完整的来源:

 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()); } 

inputSoapPrimitive的信封:

 SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); String strRes = result.toString(); 

它会工作。

您可以使用下面的代码来调用Web服务并获取响应。确保您的Web服务以数据表格式返回响应。如果您使用的是来自SQL Server数据库的数据,则此代码可以帮助您。如果您使用MYSQL ,则需要改变一件事就是从句子obj2=(SoapObject) obj1.getProperty("NewDataSet");replace单词NewDataSet obj2=(SoapObject) obj1.getProperty("NewDataSet");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 } 

如果你有任何问题,你可以写我..

如果预期有多个结果,则getResponse()方法将返回包含各种响应的Vector

在这种情况下,有问题的代码变成:

 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); 

基于ksoap2-android(mosabua fork)的答案

我想你不能打电话

  androidHttpTransport.call(SOAP_ACTION, envelope); 

在主线程。

networking操作应该在不同的线程上完成。

创build另一个线程或AsyncTask来调用该方法。