Как вызвать.NET Webservice из Android, используя KSOAP2?

У меня проблема при звонке в веб-сервис. У меня есть веб-сервис.NET на сервере, и я использую KSOAP2 (ksoap2-j2se-full-2.1.2) в Android. Во время работы программы я получил исключение во время выполнения, например "org.ksoap2.serialization.SoapPrimitive". Что я должен делать?

Вот мой код

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

6 ответов

Это очень просто. Вы получаете результат в 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 Webservice?

У меня был тот же эффект, используя ksoap 2.3 от code.google.com. Я следовал за учебником по проекту кода (это здорово).

И каждый раз, когда я использовал

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

чтобы получить результат моего веб-сервиса (независимо от типа, я пробовал Object, String, int) я столкнулся с org.ksoap2.serialization.SoapPrimitive исключение.

Я нашел решение (обходной путь). Первое, что мне нужно было сделать, - это удалить атрибут 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()) чтобы получить мое значение, которого мне достаточно, потому что у меня нет сложных типов, которые мне нужно получить из моего веб-сервиса.

Вот полный источник:

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

Введите тип конверта в SoapPrimitive:

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

и это будет работать.

Вы можете использовать приведенный ниже код для вызова веб-службы и получения ответа. Убедитесь, что ваша веб-служба возвращает ответ в формате таблицы данных. Этот код поможет вам, если вы используете данные из базы данных SQL Server. Если вы используете MYSQL, вам нужно изменить одну вещь просто заменить слово 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
}

Если у вас есть какие-либо проблемы по этому поводу, вы можете написать мне..

Я думаю, что вы не можете позвонить

 androidHttpTransport.call(SOAP_ACTION, envelope);

в главной теме.

Сетевые операции должны выполняться в разных потоках.

Создайте другой поток или AsyncTask для вызова метода.

Если ожидается более одного результата, то 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)

Другие вопросы по тегам