servicios - consumir web service c# desde android
¿Cómo llamar a un servicio web.NET desde Android usando KSOAP2? (6)
Tengo un problema al llamar a un servicio web. Tengo un servicio web .NET en el servidor, y estoy usando KSOAP2 (ksoap2-j2se-full-2.1.2) en Android. Mientras ejecutaba el programa obtuve una excepción de tiempo de ejecución como "org.ksoap2.serialization.SoapPrimitive". ¿Que debería hacer?
Aquí está mi código.
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());
}
}
}
¿Cómo se ve tu servicio web .NET?
Tuve el mismo efecto usando ksoap 2.3 de code.google.com . Seguí el tutorial sobre The Code Project (que es genial por cierto).
Y cada vez que usaba
Integer result = (Integer)envelope.getResponse();
para obtener el resultado de un mi servicio web (independientemente del tipo, probé Object, String, int) me encontré con la excepción org.ksoap2.serialization.SoapPrimitive
.
Encontré una solución (solución alternativa). Lo primero que tuve que hacer fue eliminar el atributo "SoapRpcMethod () de mis métodos de servicio web.
[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;
}
Luego cambié mi código de Android a:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
Sin embargo, obtengo un objeto SoapPrimitive, que tiene un archivo de "valor" que es privado. Afortunadamente, el valor se pasa a través del método toString()
, así que uso Integer.parseInt(result.toString())
para obtener mi valor, que es suficiente para mí, porque no tengo ningún tipo complejo que deba obtener de mi servicio web.
Aquí está la fuente completa:
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());
}
Creo que no puedes llamar
androidHttpTransport.call(SOAP_ACTION, envelope);
en el hilo principal.
Las operaciones de red deben hacerse en diferentes subprocesos.
Cree otro Thread o AsyncTask para llamar al método.
Encastre el sobre a SoapPrimitive:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
String strRes = result.toString();
y funcionará
Es muy sencillo. Estás obteniendo el resultado en un Object
que es primitivo.
Tu codigo:
Object result = (Object)envelope.getResponse();
Código correcto:
SoapObject result=(SoapObject)envelope.getResponse();
//To get the data.
String resultData=result.getProperty(0).toString();
// 0 is the first object of data.
Creo que esto definitivamente debería funcionar.
Puede utilizar el código siguiente para llamar al servicio web y obtener una respuesta. Asegúrese de que su servicio web devuelva la respuesta en formato de tabla de datos. Este código lo ayudará si usa datos de la base de datos de SQL Server . Si está utilizando MYSQL , necesita cambie una cosa simplemente reemplace la palabra NewDataSet de la oración obj2=(SoapObject) obj1.getProperty("NewDataSet");
por 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
}
Si tiene algún problema al respecto, puede escribirme ...
Si se espera más de un resultado, el método getResponse()
devolverá un Vector
contiene las diversas respuestas.
En cuyo caso, el código ofensivo se convierte en:
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);
Respuesta basada en el ksoap2-android (tenedor mosabua)