Solicitud REST al Agente de servicios web desde C#
Objetivo
-
Explicar de forma clara y precisa cómo es el manejo de JSON en el lenguaje C# Visual Studio.
-
Explicar las funciones y objetos que ofrece C# para realizar una petición HTTP por medio del verbo POST.
-
Presentar un ejemplo funcional donde se consuma recursos de la API que ofrece el agente de servicios web de ContaPyme desde el lenguaje de programación C# Visual Studio.
JSON
El manejo de JSON en el lenguaje de 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:
-
Nos posicionamos sobre la solución en el ítem "referencias" de nuestro proyecto y presionamos clic derecho y seleccionamos la opción de "agregar referencia".
-
Se nos abrirá una ventana modal llamada "Administrador de referencias", en esta ventana en la parte inferior derecha encontraremos un botón llamado "Examinar…", presionamos clic sobre él y seleccionamos la dll Newtonsoft.Json.dll de donde la hubiésemos almacenado.
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 C#
|
Representación en JSONObject
|
|
Obj = new Dictionary();
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 C#
|
Representación en JSONArray
|
|
arr = new Object[5];
arr[0] = "foo";
arr[1] = 100;
arr[2] = 1000.21;
arr[3] = true;
arr[4] = new Object();
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
|
|
String str = '{
"name":"foo",
"num":100,
"balance": 1000.21,
"Italia":true,
"obj":{……}
}'
Jbject obj = JsonConvert.DeserializeObject(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 C#
|
Representación del JSON
|
|
Obj = new Dictionary();
Obj.add("name","foo");
Obj.add("num",100);
Obj.add("balance",1000.21);
Obj.add("italia",true);
Obj.add("child",new Dictionary);
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
WebClient webClient = new WebClient();
//En esta variable llegará la respuesta en un arreglo de Bytes
Byte[] resByte;
//Se define la URL a donde se realizará la solicitud
String URL = 'http://exapmple.com/idrecurso'
//Se definen los datos que se enviaran a la solicitud
Byte[] reqString = 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
String resString = 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 realizará 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 JObject RequestPost(String URL, Dictionary JSonData) {
//Se crea el Objeto que realizará la solicitud REST
WebClient webClient = new WebClient();
try {
//Se convierte el dictionary que representa los datos en un String
String strJSON = JsonConvert.SerializeObject(JSonData, Formatting.None);
//El String con el JSON se convierte a un arreglo de Bytes
Byte[] reqString = Encoding.Default.GetBytes(strJSON);
//Se realiza la solicitud por el verbo POST enviando el JSON representado en Bytes
Byte[] resByte = webClient.UploadData(URL, "post", reqString);
//Se convierte la respuesta que es un arreglo de Bytes a un String
String resString = Encoding.Default.GetString(resByte);
//Se libera el Objeto de la conexión
webClient.Dispose();
//Se retorna la respuestaString en formato JObject
return JsonConvert.DeserializeObject(resString);
} catch (Exception ex) {
//Se imprime en consola el error generado
Console.WriteLine(ex.Message);
}
//Se envía una respuesta vacia en caso de no pederse realizar la solicitud
return JsonConvert.DeserializeObject("{}");
}
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 String SendRequestGetAuth() {
//Se define la URL a donde se realizará la peticion de GetAuth
String URLPost = "http://local.insoft.co:9000/datasnap/rest/TBasicoGeneral/\"GetAuth\"/";
//Se define el Objeto que se enviará para ser la autenticación
Dictionary ObjSend = new Dictionary();
//Se define el Objeto que tendrá los datos de autenticación
Dictionary ObjParams = new Dictionary();
//Se adiciona el email al objeto a enviar
ObjParams.Add("email", EdEmail.Text);
//Se adiciona el identificador de la maquina
ObjParams.Add("idmaquina", "1");
//Se envia la contraseña encriptada en MD5
ObjParams.Add("password", MD5EncryptPass(EdClave.Text.ToUpper()));
//Se construye el arreglo donde se enviaran los 4 parámetros
string[] arrParams = new string[4];
//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
JObject ObjResult = RequestPost(URLPost, ObjSend);
//Se definen variables temporales que se usaran para acceder al JSON
JArray arrTemp = null;
JObject objTemp = null;
JToken tokTemp = null;
//Se defien que por defecto la respuesta será vacia
string str = "";
//Se extrae el Result de la respuesta
if (ObjResult.TryGetValue("result", out tokTemp) && (tokTemp != null)) {
//Se convierte a un JSON Array
arrTemp = (JArray)tokTemp;
//Se verifica que no este vacio y tenga un valor
if ((arrTemp != null) && (arrTemp.Count > 0)) {
//Se extreae el objeto que está en la primera posición del arreglo
objTemp = arrTemp[0] as JObject;
//Se extrea el ebjeto de la respuesta y se verifica que tenga valor
if (objTemp.TryGetValue("respuesta", out tokTemp) && (tokTemp != null)) {
//Se parsea el token extraido a un JObject
objTemp = (JObject)tokTemp;
//Se extrae el Objeto datos del objeto y se verifica que tenga valor
if (objTemp.TryGetValue("datos", out tokTemp) && (tokTemp != null)) {
//Se pasea el token a un objeto
objTemp = (JObject)tokTemp;
//Se extrea el key agente y se verifica que tenga valor
if (objTemp.TryGetValue("keyagente", out tokTemp) && (tokTemp != null))
//Se convierte el token a un string
str = (string)tokTemp;
}
}
}
}
//Se verifica si el keyAgente tiene algun valor
if (str == "")
MessageBox.Show("No se ha podido iniciar sesión con el servidor", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
//Se retorna el key agente
return str;
}
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 JArray GetListTerceros(String keyAgent) {
//Se define el Objeto que se enviará en el cuerpo de la petición
Dictionary ObjSend = new Dictionary();
//Se define el Objeto que tendrá los datos de autenticación
Dictionary ObjParams = new Dictionary();
//Se define la URL donde se realizará la peticion de solicitud de listado de terceros
string URLPost = "http://local.insoft.co:9000/datasnap/rest/TCatTerceros/\"GetListaTerceros\"/";
//Se define el Objeto con los datos de página
Dictionary ObjDatosPagina = new Dictionary();
ObjDatosPagina.Add("cantidadregistros", "99");
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
string[] arrParams = new string[4];
//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 peticion
JObject ObjResult = RequestPost(URLPost, ObjSend);
//Se definen variables temporales que se usaran para acceder al JSON
JArray arrTemp = null;
JObject objTemp = null;
JToken tokTemp = null;
//Se extrae el Result de la respuesta
if (ObjResult.TryGetValue("result", out tokTemp) && (tokTemp != null)) {
//Se convierte a un JSON Array
arrTemp = (JArray)tokTemp;
//Se verifica que no este vacio y tenga un valor
if ((arrTemp != null) && (arrTemp.Count > 0)) {
//Se extreae el objeto que está en la primera posición del arreglo
objTemp = arrTemp[0] as JObject;
//Se extrea el ebjeto de la respuesta y se verifica que tenga valor
if (objTemp.TryGetValue("respuesta", out tokTemp) && (tokTemp != null)) {
//Se parsea el token extraido a un JObject
objTemp = (JObject)tokTemp;
//Se extrae el arreglo datos del objeto y se verifica que tenga valor
if (objTemp.TryGetValue("datos", out tokTemp) && (tokTemp != null)) {
//Se parsea el arreglo con los datos
arrTemp = (JArray)tokTemp;
}
}
}
}
//Se retorna el arreglo con los datos
return arrTemp;
}
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 void BtnRequest_Click(object sender, EventArgs e) {
//Se solicita el keyAgente
string sKey = SendRequestGetAuth();
//Se verifica que el keyAgent tenga un valor
if (sKey != "") {
//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
DataTable 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 define una variable de tipo registro
DataRow registro;
//Se obtiene el listado de terceros
JArray arrTerceros = GetListTerceros(sKey);
//Se define un Objeto temporal para el momento de recorrer el arreglo
JObject JRecord = null;
//Se recorre el arreglo con el listado de terceros
for (int i = 0; i < arrTerceros.Count; i++) {
//Se extrea el objeto que viene la posicion i del arreglo
JRecord = (JObject)arrTerceros[i];
//Se define que el registro será una nueva fila
registro = tbl.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
tbl.Rows.Add(registro);
}
//Se agrega la tabla al DataSet
DataSetJSON.Tables.Add(tbl);
//Se define a la grid que muestre la tabla llamada terceros
dataGridViewJSON.DataSource = DataSetJSON.Tables["Terceros"];
}
}
Resultado de la implementación
©2016 InSoft Todos los derechos reservados.