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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1052300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:38:49  来源:igfitidea点击:

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

androidksoap2ksoap

提问by Rajapandian

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?

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

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

回答by 1HaKr

It's very simple. You are getting the result into an Objectwhich is a primitive one.

这很简单。您正在将结果转化Object为原始结果。

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.

我认为这绝对有效。

回答by Jürgen Steinblock

How does your .NET Webservice look like?

您的 .NET Web 服务是什么样的?

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

我使用来自 code.google.com 的 ksoap 2.3也有同样的效果。我遵循了The Code Project上的教程(顺便说一句,这很棒。)

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.SoapPrimitiveexception.

为了获得我的网络服务的结果(无论类型如何,我尝试过 Object、String、int)我遇到了org.ksoap2.serialization.SoapPrimitive异常。

I found a solution (workaround). The first thing I had to do was to remove the "SoapRpcMethod() attribute from my webservice methods.

我找到了一个解决方案(解决方法)。我必须做的第一件事是从我的网络服务方法中删除“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;
    }

Then I changed my Android code to:

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

    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.

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

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

回答by ali

Typecast the envelope to SoapPrimitive:

将信封类型转换为 SoapPrimitive:

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

and it will work.

它会起作用。

回答by Sachin D

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 Serverdatabase .If you you using MYSQLyou need to change one thing just replace word NewDataSetfrom sentence obj2=(SoapObject) obj1.getProperty("NewDataSet");by DocumentElement

您可以使用以下代码调用 Web 服务并获得响应。确保您的 Web 服务以数据表格式返回响应。如果您使用SQL Server数据库中的数据,此代码可以帮助您。如果您使用MYSQL,则需要改变一件事,只需用DocumentElement替换句子中的单词 NewDataSetobj2=(SoapObject) obj1.getProperty("NewDataSet");

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..

如果您对此有任何问题,可以写信给我..

回答by naveejr

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.

创建另一个 Thread 或 AsyncTask 来调用该方法。

回答by Richard Le Mesurier

If more than one result is expected, then the getResponse()method will return a Vectorcontaining the various responses.

如果预期的结果不止一个,则该getResponse()方法将返回Vector包含各种响应的 。

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)

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