Consumir un servicio WCF localhost utilizando kSOAP2 en el emulador

He golpeado mi cabeza contra esta pared por un par de días ahora así que cualquier ayuda es muy apreciada.

Un poco de fondo, primero. Soy un desarrollador de WindowsMobile experimentado moviéndose a Android por lo que, por lo tanto, soy un noob en Java, Android, e incluso WCF. He hecho un montón de investigación sobre cómo consumir aplicaciones de WCF en Android usando kSOAP2, pero no importa lo que hago lo mejor que puedo llegar con un error de socket en Android debido a un tiempo fuera.

Primero, creé una aplicación de servicio web en Visual Studio 2008 que no requiere parámetros y simplemente responde con un valor de cadena. El código del servicio web es el siguiente:

using System; using System.Collections.Generic; using System.Web; using System.Web.Services; namespace Sample { [WebService(Namespace = "http://sample.com/")] public class Service1 : System.Web.Services.WebService { [WebMethod] public string SayHello() { return "Hello, Android. From your friend, WCF"; } } } 

Para este servicio web no he ajustado ninguna otra configuración ni he hecho ninguna modificación al archivo Web.config.

Cuando ejecuto el servicio abre mi navegador y señala a la url siguiente:

 http://localhost:61554/Service1.asmx 

A continuación, salté a Eclipse y creé un sencillo proyecto Android para consumir el servicio de WCF. Para empezar, cambié el archivo AndroidManifest.xml y le agregé esta declaración:

 <uses-permission android:name="android.permission.INTERNET" /> 

Ahora para el código de mi clase de Android que se supone que hacer el trabajo pesado:

 package com.sample; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import org.ksoap2.*; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.*; public class Sample extends Activity { TextView result; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); result = (TextView)findViewById(R.id.textViewResult); try { SoapObject Request = new SoapObject("http://sample.com/", "SayHello"); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(Request); HttpTransportSE androidHttpTransport = new HttpTransportSE("http://192.168.1.72:61554/Service1.asmx"); androidHttpTransport.call("http://192.168.1.72:61554/SayHello", envelope); SoapObject response = (SoapObject)envelope.getResponse(); String resultValue = response.getProperty(0).toString(); result.setText(resultValue); } catch (Exception e) { result.setText(e.getMessage()); } } } 

La línea de código que me está dando el error es:

 androidHttpTransport.call("http://192.168.1.72:61554/SayHello", envelope); 

Cuando se ejecuta en el emulador el código llega a esa línea, se detiene durante un minuto o dos y luego cae en el bloque catch con una excepción de tiempo de espera.

¿Alguna idea sobre lo que podría faltar aquí? La ayuda es apreciada.

De acuerdo, finalmente descubrí mi problema (s). Varios factores estaban en juego que usted esperaría para alguien nuevo a estas tecnologías. Espero que mis errores salvarán a los demás algún tiempo.

El primer problema que tuve fue un error de parámetro en mi código. La línea

 androidHttpTransport.call("http://192.168.1.72:61554/SayHello", envelope); 

era incorrecto en que debería haber enumerado el espacio de nombres para mi servicio web seguido por el nombre del método. Así que cambié esa línea a esto:

 androidHttpTransport.call("http://sample.com/SayHello", envelope); 

Después de este cambio todavía tenía la línea de lanzar una excepción, pero ahora estaba recibiendo una excepción diferente que era al menos una victoria moral. La nueva excepción decía lo siguiente:

 expected START_TAG{http://schemas.xmlsoap.org/soap/envelope/} Envelope(position:START_TAG<html>@1:6 in java.io.InputStreamReader@d3el2cc4) 

Este mensaje es desenfrenado en Internet, pero ninguna de las soluciones que encontré funcionó para mí. Después de muchas pruebas y errores encontré mi problema particular. Mi servicio web se crea en Visual Studio 2008 y lo estoy probando simplemente ejecutándolo dentro de Visual Studio y luego tratando de consumirlo desde mi emulador de Android. Resulta que hay una configuración de seguridad en el "sandbox" IIS de VS2008 que rechaza cualquier solicitud más allá de la PC local y aparentemente el emulador no se considera el PC local.

Para corregir ese problema tomé los pasos siguientes en Visual Studio 2008:

  1. Salir de Visual Studio y abrirlo con derechos administrativos (estoy usando Windows 7).
  2. Con mi proyecto abierto vi las propiedades del proyecto.
  3. En la pestaña "Web" cambié el botón de opción de la sección "Servidores" a "Usar servidor web IIS local", ingresé "http: // localhost / Sample" para mi URL de proyecto y pulsé el botón "Crear directorio virtual".

Después de completar estos pasos corrí mi servicio web de nuevo, lanzé mi aplicación para Android en el emulador y finalmente me puse por la línea que ha estado lanzando una excepción todo el tiempo. Esta vez, sin embargo, la siguiente línea lanzó una excepción. Otra victoria moral y un paso más cerca. Esta nueva excepción fue:

 org.ksoap2.serialization.SoapPrimitive 

Una búsqueda rápida de Google resolvió este para mí. Las líneas

 SoapObject response = (SoapObject)envelope.getResponse(); String resultValue = response.getProperty(0).toString(); 

en mi código original necesitaba ser cambiado a esto:

 SoapPrimitive response = (SoapPrimitive)envelope.getResponse(); String resultValue = response.toString(); 

Después de ese cambio tuve una aplicación de trabajo.

Código de trabajo final

Servicio Web (creado en Visual Studio 2008 y ejecutándose en el servidor web IIS local configurado en las propiedades del proyecto)

 using System; using System.Collections.Generic; using System.Web; using System.Web.Services; namespace Sample { [WebService(Namespace = "http://sample.com/")] public class Service1 : System.Web.Services.WebService { [WebMethod] public string SayHello() { return "Hello, Android. From your friend, WCF"; } } } 

Clase de Android

 package com.sample; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import org.ksoap2.*; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.*; import org.ksoap2.serialization.SoapPrimitive; public class Sample extends Activity { TextView result; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); result = (TextView)findViewById(R.id.textViewResult); final String SOAP_ACTION = "http://sample.com/SayHello"; final String METHOD_NAME = "SayHello"; final String NAMESPACE = "http://sample.com/"; final String URL = "http://192.168.1.72/Sample/Service1.asmx"; try { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); androidHttpTransport.call(SOAP_ACTION, envelope); SoapPrimitive response = (SoapPrimitive)envelope.getResponse(); String resultValue = response.toString(); result.setText(resultValue); } catch (Exception e) { result.setText(e.getMessage()); } } } 

Acabo de luchar por este problema. Para acceder al host local en tu PC, necesitas el Dirección IP 10.0.2.2. Encontré la respuesta aquí. http://developer.android.com/resources/faq/commontasks.html#localhostalias . Ahora no consigo un tiempo de espera del zócalo pero consigo una excepción de XMLPullParser, que estoy pegado encendido.

  • Solicitud de aplicaciones para Android Servicio WCF (SerializationException - utf-8 related)
  • ¿Cuál es la forma correcta de auto-hospedar una API Web?
  • Cómo enviar la cadena codificada base 64 de android a wcf
  • Consumir servicio WCF en android
  • Pasar objetos al servicio de jabón wcf desde android usando ksoap2; Envía y recibe 0
  • Cómo consumir servicios WCF dependientes de la sesión usando Ksoap2-Android
  • Obtención de imagen de la matriz de bytes en el objeto JSON a la aplicación de Android
  • Consumir el servicio web de WCF desde la aplicación Android?
  • Error de acceso denegado con jQuery
  • Cómo llamar a un servicio WCF usando ksoap2 en android?
  • WCF vs WEB api vs Web servicios para el nuevo sitio web de comercio electrónico
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.