Cómo consumir el servicio WCF con Android

79

Estoy creando un servidor en .NET y una aplicación cliente para Android. Me gustaría implementar un método de autenticación que envía el nombre de usuario y la contraseña al servidor y un servidor devuelve una cadena de sesión.

No estoy familiarizado con WCF, por lo que realmente agradecería su ayuda.

En Java, escribí el siguiente método:

private void Login()
{
  HttpClient httpClient = new DefaultHttpClient();
  try
  {
      String url = "http://192.168.1.5:8000/Login?username=test&password=test";

    HttpGet method = new HttpGet( new URI(url) );
    HttpResponse response = httpClient.execute(method);
    if ( response != null )
    {
      Log.i( "login", "received " + getResponse(response.getEntity()) );
    }
    else
    {
      Log.i( "login", "got a null response" );
    }
  } catch (IOException e) {
    Log.e( "error", e.getMessage() );
  } catch (URISyntaxException e) {
    Log.e( "error", e.getMessage() );
  }
}

private String getResponse( HttpEntity entity )
{
  String response = "";

  try
  {
    int length = ( int ) entity.getContentLength();
    StringBuffer sb = new StringBuffer( length );
    InputStreamReader isr = new InputStreamReader( entity.getContent(), "UTF-8" );
    char buff[] = new char[length];
    int cnt;
    while ( ( cnt = isr.read( buff, 0, length - 1 ) ) > 0 )
    {
      sb.append( buff, 0, cnt );
    }

      response = sb.toString();
      isr.close();
  } catch ( IOException ioe ) {
    ioe.printStackTrace();
  }

  return response;
}

Pero en el lado del servidor hasta ahora no he descubierto nada.

Estaría muy agradecido si alguien pudiera explicar cómo crear una cadena de método apropiada Iniciar sesión (cadena de nombre de usuario, contraseña de cadena) con la configuración apropiada de App.config y la interfaz con la firma apropiada de [OperationContract] para leer estos dos parámetros del cliente y responder con cadena de sesión.

¡Gracias!

Niko Gamulin
fuente
2
Me encantaría ver una forma de consumir wcf binary serializado en Android. Eso sí que sería genial.
Brady Moritz

Respuestas:

41

Para comenzar con WCF, puede ser más fácil usar el formato SOAP predeterminado y HTTP POST (en lugar de GET) para los enlaces del servicio web. El enlace HTTP más fácil de poner en funcionamiento es "basicHttpBinding". A continuación, se muestra un ejemplo de cómo se vería ServiceContract / OperationContract para su servicio de inicio de sesión:

[ServiceContract(Namespace="http://mycompany.com/LoginService")]
public interface ILoginService
{
    [OperationContract]
    string Login(string username, string password);
}

La implementación del servicio podría verse así:

public class LoginService : ILoginService
{
    public string Login(string username, string password)
    {
        // Do something with username, password to get/create sessionId
        // string sessionId = "12345678";
        string sessionId = OperationContext.Current.SessionId;

        return sessionId;
    }
}

Puede alojar esto como un servicio de Windows utilizando un ServiceHost, o puede alojarlo en IIS como una aplicación (servicio) web ASP.NET normal. Hay muchos tutoriales para ambos.

La configuración del servicio WCF podría verse así:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>


    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="LoginServiceBehavior">
                    <serviceMetadata />
                </behavior>
            </serviceBehaviors>
        </behaviors>

        <services>
            <service name="WcfTest.LoginService"
                     behaviorConfiguration="LoginServiceBehavior" >
                <host>
                    <baseAddresses>
                        <add baseAddress="http://somesite.com:55555/LoginService/" />
                    </baseAddresses>
                </host>
                <endpoint name="LoginService"
                          address=""
                          binding="basicHttpBinding"
                          contract="WcfTest.ILoginService" />

                <endpoint name="LoginServiceMex"
                          address="mex"
                          binding="mexHttpBinding"
                          contract="IMetadataExchange" />
            </service>
        </services>
    </system.serviceModel>
</configuration>

(Las cosas de MEX son opcionales para la producción, pero se necesitan para probar con WcfTestClient.exe y para exponer los metadatos del servicio).

Tendrá que modificar su código Java para PUBLICAR un mensaje SOAP al servicio. WCF puede ser un poco exigente cuando interactúa con clientes que no son WCF, por lo que tendrá que meterse un poco con los encabezados POST para que funcione. Una vez que lo haga, puede comenzar a investigar la seguridad para el inicio de sesión (es posible que deba usar un enlace diferente para obtener una mejor seguridad), o posiblemente usar WCF REST para permitir inicios de sesión con GET en lugar de SOAP / POST.

A continuación se muestra un ejemplo de cómo debería verse HTTP POST a partir del código Java. Existe una herramienta llamada " Fiddler " que puede ser realmente útil para depurar servicios web.

POST /LoginService HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://mycompany.com/LoginService/ILoginService/Login"
Host: somesite.com:55555
Content-Length: 216
Expect: 100-continue
Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<Login xmlns="http://mycompany.com/LoginService">
<username>Blah</username>
<password>Blah2</password>
</Login>
</s:Body>
</s:Envelope>
Andy White
fuente
1
¿Alguna idea de cómo obtener comunicación wcf dúplex? No importa el sondeo o el verdadero empujón.
Alxandr
1
Recomendaría la opción REST, SOAP te traerá más problemas que ventajas. Si utiliza REST con cifrado SSL, su servicio web será muy seguro.
Rafa
4
Sí, también recomendaría REST ahora, esta respuesta fue de hace unos años cuando REST / JSON no eran tan frecuentes como ahora.
Andy White
por favor vea la publicación stackoverflow.com/questions/33183506/…
kartheeki j
7

Otra opción podría ser evitar WCF por completo y simplemente usar un .NET HttpHandler. HttpHandler puede tomar las variables de cadena de consulta de su GET y simplemente escribir una respuesta al código Java.

Andy White
fuente
6
Podría hacer esto, pero sin un marco adecuado, parece que esto sería frágil y difícil de mantener. ¿Cómo documentaría la interfaz REST para los clientes? ¿Y si quieres JSON? etc., etc.
Cheeso
6

Necesitará algo más que una solicitud http para interactuar con un servicio WCF A MENOS QUE su servicio WCF tenga una interfaz REST. Busque una API de servicio web SOAP que se ejecute en Android o haga que su servicio sea RESTful. Necesitará .NET 3.5 SP1 para realizar los servicios WCF REST:

http://msdn.microsoft.com/en-us/netframework/dd547388.aspx

Jonathan Parker
fuente
4

Desde mi experiencia reciente, recomendaría la biblioteca ksoap para consumir un servicio WCF de jabón, es realmente muy fácil, este hilo anddev también podría ayudarlo.

Necronet
fuente
ksoap usa XML y se recomienda REST para operaciones como esta.
Sreekanth Karumanaghat
3

Si estuviera haciendo esto, probablemente usaría WCF REST en el servidor y una biblioteca REST en el cliente Java / Android.

Cheeso
fuente