none
Respuesta indeseada en un servicio REST, como eliminarla? RRS feed

  • Pregunta

  • Hola.

    Como se puede ver en el archivo adjunto este es un servicio WSDL SOAP.

    En "IOS 5", y otros entornos móviles, la mejor opción es usar un servicio de estilo "REST", donde las consultas se hacen directamente a una URL, y no por un descriptor WSDL.

    En este caso, el servicio web devuelve el contenido en formato JSON, pero están envueltos en una estructura XML, que en IOS y otros dispositivos móviles es más difícil de interpretar.

    ¿Cómo cambiar este servicio Web para ser de tipo "REST"?

    Alguien me podría ayudar por favor?

    Gracias de antemano,

    Luigggye

     

    Adjunto el Web Service del tipo WSDL / SOAP

     

    Imports My
    Imports System.Web
    Imports System.Web.Services
    Imports System.Web.Services.Protocols
    Imports System.Web.Script.Services
    Imports System.Xml
    Imports System.Data
    Imports System.IO
    Imports System.Windows.Forms
    Imports Microsoft.AnalysisServices
    Imports Utilities.Utilities
    Imports System.Diagnostics
    
    <WebService(Namespace:="http://tempuri.org/")> _
    <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
    <System.Web.Script.Services.ScriptService()> _
    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Public Class DPNetServices
        Inherits System.Web.Services.WebService
    
        ' Web Services para mobiles
    
        <WebMethod(EnableSession:=True)> _
        <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
        Public Function ManageMobileUsers(ByVal UsrNmb As String, ByVal UsrPwd As String, ByVal Release As String) As String
    
            Dim appm As AppMembers = New AppMembers(True, UsrNmb, Release)
    
            Return appm.DBProc.ManageMobileUsers(UsrNmb, UsrPwd) ' This function return a JSON text
    
        End Function
    
    End Class
    
    
    

     

     



    My web.config file:



    <?xml version="1.0"?>
    <configuration>

    <system.web>
    <compilation debug="true" targetFramework="4.0" />
    </system.web>

    <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
    <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
    </system.webServer>

    <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
    <webHttpEndpoint>
    <!--
    Configure the WCF REST service base address via the global.asax.vb file and the default endpoint
    via the attributes on the <standardEndpoint> element below
    -->
    <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
    </webHttpEndpoint>
    </standardEndpoints>
    </system.serviceModel>

    </configuration>

     

    • Editado JonyTolengo sábado, 17 de diciembre de 2011 14:42 aclaracion
    lunes, 12 de diciembre de 2011 17:11

Respuestas

Todas las respuestas

  • Lo mens costoso probablemente sea convertir el servicio web en un servicio WCF. Es razonablemente sencillo, basta que añadas al proyecto un .svc en lugar del .asmx, y luego retoques el contenido que se te autogenera, cambiando los métodos de muestra por los métodos que ahora tienes dentro del .asmx.vb. Después, en los métodos que quieras exponer como REST, los decoras con el atributo <Webinvoke(Method:="GET",...)>, (o usa <WebGet>), y otros similares si quieres otros verbos en lugar del GET. Dependiendo de cómo lo hayas generado puede que tengas que añadir algunas entradas en el web.config para habilitarlo y/o modificar la cabecera del .svc. Hay un montonazo de ejemplos en la Web, no tienes más que buscar uno y copiar la configuración. Por ejemplo, mira este artículo:

    http://www.techbubbles.com/wcf/rest-based-wcf-service-in-aspnet-35/

     

     

    miércoles, 14 de diciembre de 2011 18:02
  • Hola,

    Antes que todo, MUCHAS GRACIAS por la respuesta anterior.

    La función por ahora quedo así:

    Namespace MobileRestServices

    <ServiceContract()>
    <AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
    <ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerCall)>
    Public Class MobileRestServices

       <WebGet(UriTemplate:="ManageMobileUsers/{UsrNmb}/{UsrPwd}/{Device}", ResponseFormat:=WebMessageFormat.Json, BodyStyle:=WebMessageBodyStyle.Bare)>
       Public Function ManageMobileUsers(ByVal UsrNmb As String, ByVal UsrPwd As String, ByVal Device As String) As String

          Dim Sample As String = "{'status':'ok','userId':23847,'name':'Marco Casario','rol':0,'options':[{'id':1,'title':'Ventas'},{'id':2,'title':'Compras'},{'id':3,'title':'Recursos Humanos'}]}"

          Return Sample  ‘ después hago lo que realmente tiene que hacer para obtener este string JSON.

       End Function

      End Class

    End Namespace


    Solo HAY UN PROBLEMA, que seguro es de configuración del IIS, o del servicio REST (web.config, etc).

    Fíjate en esto:

    Como puedes ver, este llamado desde Google Crome: http://50.63.24.135:81/MobileRestServices/ManageMobileUsers/USRNMB/USRPWD/DEVICE

    (puedes llamarlo pues es una direccion real)

    Retorna:

    {'status':'ok','userId':23847,'name':'Marco Casario','rol':0,'options':[{'id':1,'title':'Ventas'},{'id':2,'title':'Compras'},{'id':3,'title':'Recursos Humanos'}]}


    Lo que a simple vista está bien y es lo que espero en el dispositivo móvil. Mira lo que retorna el Google Crome en la imagen adjunta, aparentemente esta OK.

    Pero en realidad, hay algo más “oculto” que viene, pero que solo lo puedes ver si pides para ver el “source” en el navegador.

    Entonces verás esto: (ver imagen adjunta).

    Es decir, a la respuesta de la función se le agrega automáticamente esto que te agrego en ROJO:

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{'status':'ok','userId':23847,'name':'Marco Casario','rol':0,'options':[{'id':1,'title':'Ventas'},{'id':2,'title':'Compras'},{'id':3,'title':'Recursos Humanos'}]}</string>

    Eso es lo que me llega como resultado al cliente móvil y obviamente, como no espera ese “adicional”  no puede deserializar la respuesta JSON y pincha.

    Estoy seguro que es una pabada, algo de configuración del IIS o en el propio servicio REST, algún “tag” o en el Web.config.

    Agradezco cualquier ayuda, pues no consigo recibir el text puro en el cliente movil.

    Y muchas gracias de nuevo….!!!

    Saludos.

    Luigggye

     


    Luigye
    jueves, 15 de diciembre de 2011 20:59
  • No me explico lo que puede estarte pasando en Chrome, ya que no uso ese navegador. Pero he probado a conectar a la URL que indicas desde Internet Explorer y me ofrece descargar los datos a un archivo. Abriendo el archivo, tiene el JSON completamente limpio, como cabía esperar.

    Es más, he probado a escribir un fragmento de código para conectar al servicio, con unas líneas como las siguientes (que me imagino que serán muy similares a las que usas en el dispositivo móvil):

    WebClient wc = new WebClient();
    string datos = wc.DownloadString("http://50.63.24.135:81/MobileRestServices/ManageMobileUsers/USRNMB/USRPWD/DEVICE");
    Console.WriteLine(datos);
    Console.ReadLine();
    

    Y me descarga correctamente el JSON, como cabía esperar, sin ningún prefijo en forma de XML como el que indicas en tu mensaje.

     

    viernes, 16 de diciembre de 2011 6:53
  • Hola, gracias por tu respuesta.

    Un especialista en Microsoft, me ha comentado que en el internet explorer (mismo la ultima version), suele suceder eso, es decir, te lo intenta bajar, no lo interpreta, en otros navegadores no pasa eso, te lo muestra bien como un resultado.

    Fijate este link.

    http://www.iis.net/ConfigReference/system.webServer/staticContent/mimeMap    ( Adding Static Content MIME Mappings <mimeMap> )

    Yo tuve que agregar una extension "json" para evitar que cuando hago algo asi http://xx.xx.xx.xx/Archivo.json no me haga el download y me lo muestre como resultado.

    El problema es que en el dispositivo movil, tanto en IOS 5, como en Android que es onde estoy probando ahora, me llega el string con el encabezado que te muestra el Crome cuando pedis ver el source, y entonces no consigo deserializarlo.

    Con un framework de Microsoft (como probaste vos) ese encabezado se "filtra" y te llega el resultado limpio.

    Hasta donde me han comentado, parece que es algun tag que hay que poner en el servicio rest, para que no mande ese encabezado, pero no encuentro que exactamente debo poner aún.

    Si se te ocurre algo, avisame.

    Gracias.

    Luigggye

     

     

     


    Luigye
    viernes, 16 de diciembre de 2011 10:47
    • Marcado como respuesta JonyTolengo jueves, 22 de diciembre de 2011 22:26
    jueves, 22 de diciembre de 2011 22:26