Solicitud REST al Agente de servicios web desde Visual Basic .NET

Objetivo

JSON
El manejo de JSON en el lenguaje de Visual Basic .NET se puede realizar mediante la librería llamada "Newtonsoft.Json" la cual se encuentra disponible en la dll "Newtonsoft.Json.dll". Esta librería ofrece diferentes funcionalidades para el manejo de JSON a través de objetos de tipo "Dictionary" como también permite la manipulación de JSON con los objetos JObject, JArray y JToken, y es una de la más recomendada por los programadores por su desempeño.
Para la implementación de este documento se ha utilizado la manipulación de JSON a través de listas Dictionary.
 
Instalación de la librería para trabajar con JSON (desde C# Microsoft Visual Studio).
Primero necesitamos descargar la dll llamada Newtonsoft.Json.dll de su web oficial aquí https://www.newtonsoft.com/json, paso seguido debemos incorporarla a nuestro proyecto, para esto realizamos los siguientes pasos:

Objetos JSON
El manejo de objetos JSON se puede realizar mediante la clase llamada JObject, la cual ofrece métodos para agregar (add), remover (remove), verificar (TryGetValue) y obtener (Property y Properties) propiedades. Pero los objetos JSON también se pueden representar en Diccionarios cuya llave sea una cadena y el valor un objeto en los cuales podremos utilizar los métodos ya conocidos de los diccionarios y en caso de necesitar la representación de un diccionario a un JSON utilizar la función "JsonConvert.SerializeObject".
Código Visual Basic .NET Representación en JSONObject
Obj = new Dictionary(Of String, Object)
Obj.add("name","foo")
Obj.add("num",100)
Obj.add("balance",1000.21)
Obj.add("italia",true)
JsonConvert.SerializeObject(Obj)
{ "name": " foo ", "num": 100, "balance": 1000.21, "Italia": true }
Arreglos JSON
La clase JArray representa una secuencia ordenada de valores indexados donde los valores pueden ser de cualquier combinación (JSONObject, JSONArray, Integer, Double, Boolean, String), el uso de la librería ofrece una serie de funciones para agregar (add), quitar (remove) y obtener (indexOf) ítems de la lista. Pero los JSONArray también los podremos definir como arreglos donde podremos utilizar los métodos y funciones ya conocidos de estos.
Código Visual Basic .NET Representación en JSONArray
Dim arr(4) as Object
arr(0) = "foo"
arr(1) = 100
arr(2) = 1000.21
arr(3) = true
arr(4) = new Object()
Dim str as String = JsonConvert.SerializeObject(arr)
{ "name": " foo ", "num": 100, "balance": 1000.21, "Italia": true }
Serializar y de serializar un JSON
La librería también ofrece funcionalidades que permiten convertir una cadena de texto en un objeto JSON la cual será muy útil para convertir la respuesta de la petición, para esto podremos usar la propiedad DeserializeObject del objeto JsonConvert:
Código C# para decodificar un JSON
Dim str as String = '{
"name":"foo",
"num":100,
"balance": 1000.21,
"Italia":true,
"obj":{……}
}'
Dim obj as Jbject = JsonConvert.DeserializeObject DeserializeObject(Of JObject)(str)
La serialización que podemos definir como el proceso para convertir un JSON a una cadena de texto, la cual será muy útil para convertir un objeto JSON o Dictionary a un string para enviarlo en una petición la podremos realizar mediante el método SerializeObject de la clase JsonConvert.
Código Visual Basic .NET Representación del JSON
Dim Obj as As New Dictionary(Of String, Object)
Obj.add("name","foo")
Obj.add("num",100)
Obj.add("balance",1000.21)
Obj.add("italia",true)
Obj.add("child",new Dictionary(of string, Object));
Dim Str as String = JsonConvert.SerializeObject(Obj)
{ "name": " foo ", "num": 100, "balance": 1000.21, "is_vip": true, "child":{} }
Request
Objeto WebClient
Este objeto es utilizado para realizar las solicitudes de recursos a un servidor, para esto proporciona propiedades y método comunes para enviar y recibir datos de un recurso identificado por una URL o URI.
Código JAVA para abrir una solicitud HTTP
//Se crea el Objeto para realizar la petición
Dim webClient as new WebClient()
//En esta variable llegará la respuesta en un arreglo de Bytes
Dim resByte as Byte()
//Se define la URL a donde se realizará la solicitud
Dim URL as String = 'http://exapmple.com/idrecurso'
//Se definen los datos que se enviaran a la solicitud
Dim reqString as Byte = Encoding.Default.GetBytes('key=valor')
//Se genera la solicitud con los datos previos
resByte = webClient.UploadData(URL, "post", reqString);
//Por último se convierte la respuesta a un String
Dim resString as String = Encoding.Default.GetString(resByte);
Ejemplo funcional
El siguiente ejemplo realiza una petición que muestra el listado de terceros obtenidos de un agente de servicios web de ContaPyme (ASW) en una tabla de tipo JTable. Para esto primero se debe hacer GetAuth contra el agente para obtener el KeyAgent con el cual se realizara la solicitud de listado de terceros.
RequestPOST
El objetivo de esta función es realizar una petición POST a una URL que recibe como parámetro, para esto la función también recibe un objeto de tipo Dictionary que será el que enviará en el cuerpo de la petición, la función después de hacer la solicitud retornara un objeto JObject que se ha entregado como respuesta.
Private Function RequestPost(ByVal URL As String, ByVal JSonData As Dictionary(Of String, Object)) As JObject
   'Se crea el Objeto que realizará la solicitud REST
   Dim webClient As New WebClient()
   Try
      'Se convierte el dictionary que representa los datos en un String
      Dim strJSON As String = JsonConvert.SerializeObject(JSonData, Formatting.None)
      'El String con el JSON se convierte a un arreglo de Bytes
      Dim reqString() As Byte = Encoding.Default.GetBytes(strJSON)
      'Se realiza la solicitud por el verbo POST enviando el JSON representado en Bytes
      Dim resByte As Byte() = webClient.UploadData(URL, "post", reqString)
      'Se convierte la respuesta que es un arreglo de Bytes a un String
      Dim resString As String = Encoding.Default.GetString(resByte)
      'Se libera el Objeto de la conexión
      webClient.Dispose()
      'Se retorna la respuestaString en formato JObject
      Return JsonConvert.DeserializeObject(Of JObject)(resString)
   Catch ex As Exception
      'Se imprime en consola el error generado
      Console.WriteLine(ex.Message)
   End Try
   'Se envía una respuesta vacia en caso de no pederse realizar la solicitud
   Return JsonConvert.DeserializeObject(Of JObject)("{}")
End Function
SendRequestGetAuth
Esta función construirá el JSON necesario para la autenticación contra el Agente de servicios web (ASW), paso seguido realizará la solicitud de GetAuth, y retornará el KeyAgente entregado por el servidor. Para esto tomará los valores de usuario y contraseña de los dos textbox creados en diseño y utilizaremos la función MD5 para encriptar la contraseña.
Private Function SendRequestGetAuth() As String
   'Se define la URL a donde se realizará la peticion de GetAuth
   Dim URLPost As String =    "http://local.insoft.co:9000/datasnap/rest/TBasicoGeneral/""GetAuth""/"
   'Se define el Objeto que se enviará para ser la autenticación
   Dim ObjSend As New Dictionary(Of String, Object)
   'Se define el Objeto que tendrá los datos de autenticación
   Dim ObjParams As New Dictionary(Of String, Object)
   'Se adiciona el email al objeto a enviar
   ObjParams.Add("email", EdEmail.Text)
   'Se envia la contraseña encriptada en MD5
   ObjParams.Add("password", MD5EncryptPass(UCase(EdClave.Text)))
   'Se adiciona el identificador de la maquina
   ObjParams.Add("idmaquina", "1")
   'Se construye el arreglo donde se enviaran los 4 parámetros de tipo String
   Dim arrParams(3) As String
   'El primer parámetro es un String con los datos de autenticación
   arrParams(0) = JsonConvert.SerializeObject(ObjParams, Formatting.None)
   'El segundo parámetro es el key agente que no aplica pues es el dato que estamos pidiendo
   arrParams(1) = ""
   'El tercer parámetro es el código del APP configurado
   arrParams(2) = "1001"
   'El cuarto parámetro es un random
   arrParams(3) = "5555"
   'Se adiciona el arreglo de paramatros al objeto a enviar
   ObjSend.Add("_parameters", arrParams)
   'Se realiza la solicitud REST y se almacena en el ObjResult
   Dim ObjResult As JObject = RequestPost(URLPost, ObjSend)
   'Se definen variables temporales que se usaran para acceder al JSON
   Dim arrTemp As JArray
   Dim objTemp As JObject
   Dim str As String = ""
   Dim b = False
   'Se extrae el arreglo que se encuentra en la llave result y se valida que tenga un valor
   If ObjResult.TryGetValue("result", arrTemp) And Not IsNothing(arrTemp) And arrTemp.Count > 0    Then
      'Se extreae el primer objeto que tiene este arreglo
      objTemp = arrTemp.Item(0)
      'Se valida que no se haya generado una eventualidad en la respuesta
      If objTemp.TryGetValue("encabezado", objTemp) And Not IsNothing(arrTemp) And
      objTemp.TryGetValue("mensaje", str) And str <> "" Then
         MessageBox.Show(str, "Prueba de petición", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End If
      objTemp = arrTemp.Item(0)
      'Se obtiene el key agetne
      b = objTemp.TryGetValue("respuesta", objTemp) And objTemp.TryGetValue("datos",       objTemp) And objTemp.TryGetValue("keyagente", str)
   End If
   'Se valida si se ha podido obtener el key agente
   If Not b Then
      MessageBox.Show("No se ha podido iniciar sesión con el servidor", "", MessageBoxButtons.OK,       MessageBoxIcon.Error)
   End If
   'Se retorna el keyAgente
   Return str
End Function
getListaTerceros
Esta función recibe el keyAgente obtenido anteriormente y construye el JSON para realizar la petición de obtener el listado de terceros, como resultado esta función retornara un JSONArray con el listado de terceros.
Private Function GetListTerceros(ByVal keyAgent As String) As JArray
   'Se define la URL donde se realizará la peticion de solicitud de listado de terceros
   Dim URLPost As String =    "http://local.insoft.co:9000/datasnap/rest/TCatTerceros/""GetListaTerceros""/"
   'Se define el Objeto que se enviará en el cuerpo de la petición
   Dim ObjSend As New Dictionary(Of String, Object)
   'Se define el Objeto que tendrá los datos de autenticación
   Dim ObjParams As New Dictionary(Of String, Object)
   'Se define el Objeto con los datos de página
   Dim ObjDatosPagina = New Dictionary(Of String, String)
   ObjDatosPagina.Add("cantidadregistros", "999")
   ObjDatosPagina.Add("pagina", "1")
   'Se agrega el objeto de los datos de la página
   ObjParams.Add("datospagina", ObjDatosPagina)
   'Se agrega el arreglo con los datos que se solicitaran en la lista
   ObjParams.Add("camposderetorno", New String() {"init", "ntercero", "napellido"})
   'Se construye el arreglo donde se enviaran los 4 parámetros
   Dim arrParams(3) As String
   'El primer parámetro es el JSON con los datos a envíar
   arrParams(0) = JsonConvert.SerializeObject(ObjParams, Formatting.None)
   'El segundo parámetro es el KeyAgente entregado enla funcion de GetAuth
   arrParams(1) = keyAgent
   'El tercer parámetro es el código del APP configurado
   arrParams(2) = "1001"
   'El cuarto parámetro es un random
   arrParams(3) = "5555"
   'Se adiciona el arreglo de paramatros al objeto a enviar
   ObjSend.Add("_parameters", arrParams)
   'Se realiza la solicitud REST y se almacena en el ObjResult con la respuesta de la petición
   Dim ObjResult As JObject = RequestPost(URLPost, ObjSend)
   'Se definen variables temporales que se usaran para acceder al JSON
   Dim arrTemp As JArray
   Dim objTemp As JObject
   Dim str As String = ""
   Dim b = False
   'Se valida si existe y se extrae el arreglo del JSON del result y se verifica que no este    vacio
   If ObjResult.TryGetValue("result", arrTemp) And Not IsNothing(arrTemp) And arrTemp.Count > 0    Then
      'Se obtiene el primer objeto del arreglo
      objTemp = arrTemp.Item(0)
      'Se obtiene el arreglo con los terceros que esta en datos de la llave respuesta
      b = objTemp.TryGetValue("respuesta", objTemp) And objTemp.TryGetValue("datos", arrTemp)
   End If
   'Se retorna el arreglo de terceros
   Return arrTemp
End Function
Implementación de las funciones
La implementación se realiza sobre el evento clic del botón, en este lo primero que se hace es obtener el keyAgente y validar que este sea diferente de vacío, paso seguido se crean los diferentes objetos que se necesitaran para mostrar la tabla con los datos y obtiene el listado de terceros el cual es almacenado en un JArray el cual se recorrerá para obtener cada uno de los objetos que se encuentran definidos en este y agregarlos al control DataRow que finalmente se agregará a la tabla.
Private Sub BtnRequest_Click(sender As Object, e As EventArgs) Handles ButtonGetAuth.Click
   'Se solicita el keyAgente
   Dim sKey As String = SendRequestGetAuth()
   'Se verifica que el keyAgent tenga un valor
   If sKey <> "" Then
      'Se escribe el keyAgente en el label
      LblControlKey.Text = "Key de autorización: " + sKey
      'Se desactivan los controles para no volver a solicitar inicio sesión
      ButtonGetAuth.Enabled = False
      EdEmail.Enabled = False
      EdClave.Enabled = False
      'Se crea una nueva tabla llamada terceros
      Dim tbl = New DataTable("Terceros")
      'Se adicionan las columnas a la tabla con su respectivo tipo
      tbl.Columns.Add(New DataColumn("ID", System.Type.GetType("System.String")))
      tbl.Columns.Add(New DataColumn("Nombre", System.Type.GetType("System.String")))
      tbl.Columns.Add(New DataColumn("Apellido", System.Type.GetType("System.String")))
      'Se agrega la tabla al DataSet
      DataSetJSON.Tables.Add(tbl)
      'Se define a la grid que muestre la tabla llamada terceros
      DataGridView.DataSource = DataSetJSON.Tables("Terceros")
      'Se define una variable de tipo registro
      Dim registro As DataRow
      'Se obtiene el listado de terceros enviando el KeyAgente obtenido previamente
      Dim arrTerceros = GetListTerceros(sKey)
      'Se define un Objeto temporal para el momento de recorrer el arreglo
      Dim JRecord As JObject
      'Se recorre el arreglo con el listado de terceros
      For i As Integer = 0 To arrTerceros.Count - 1
         'Se extrea el objeto que viene la posicion i del arreglo
         JRecord = arrTerceros.Item(i)
         'Se verifica que si exista un objeto dentro del record
         If Not IsNothing(JRecord) Then
            'Se define que el registro será una nueva fila
            registro = DataSetJSON.Tables("Terceros").NewRow()
            'Se adicionan los datos
            registro("ID") = JRecord.GetValue("init")
            registro("Nombre") = JRecord.GetValue("ntercero")
            registro("Apellido") = JRecord.GetValue("napellido")
            'Se agrega el registro a la tabla creada
            DataSetJSON.Tables("Terceros").Rows.Add(registro)
         End If
      Next
   End If
End Sub
Resultado de la implementación
©2016 InSoft Todos los derechos reservados.