Xamarin.Forms – Clase genérica para consumir servicios REST

Tal vez has visto en internet, videos y tutoriales para consumir un servicio web tipo REST, utilizando el paquete de NuGet Microsoft.Net.Http, en conjunto con Json.Net. Nosotros, ya en una entrada anterior hemos visto cómo llevar a cabo el consumo de un servicio de este tipo desde Xamarin.Forms. El motivo de esta entrada es para mostrar cómo crear una clase genérica, con la que puedas consumir cualquier servicio tipo REST.

¡Adquiere el Máster en Xamarin Forms!

Antes de iniciar, te invito a visitar la página de la Membresía de mi academia, donde podrás encontrar:

Cursos y talleres de Xamarin
Cursos y talleres en C#
Cursos y talleres de Blazor
– Cursos y talleres de ASP.NET
– Cursos y talleres en muchas otras tecnologías

¡Todo al precio más bajo posible por tiempo limitado!

curso de xamarin

Refactorizando el método:

1.- En primer lugar, nos basaremos en el código visto en una entrada anterior, el cual es:

public async Task GetWeatherAsync(string url)
        {
            //Creamos una instancia de HttpClient
            var client = new HttpClient();
            //Asignamos la URL
            client.BaseAddress = new Uri(url);
            //Llamada asíncrona al sitio
            var response = await client.GetAsync(client.BaseAddress);
            //Nos aseguramos de recibir una respuesta satisfactoria
            response.EnsureSuccessStatusCode();
            //Convertimos la respuesta a una variable string
            var jsonResult = response.Content.ReadAsStringAsync().Result;
            //Se deserializa la cadena y se convierte en una instancia de WeatherResult
            var weather = JsonConvert.DeserializeObject<WeatherResult>(jsonResult);
            //Asignamos el nuevo valor de las propiedades
            SetValue(weather);
        }

2.- Aislaremos el método en una clase independiente llamada “HttpHelper”

using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace RESTGenerico1.Helpers
{
    public class HttpHelper
    {
        public async Task GetWeatherAsync(string url)
        {
            //Creamos una instancia de HttpClient
            var client = new HttpClient();
            //Asignamos la URL
            client.BaseAddress = new Uri(url);
            //Llamada asíncrona al sitio
            var response = await client.GetAsync(client.BaseAddress);
            //Nos aseguramos de recibir una respuesta satisfactoria
            response.EnsureSuccessStatusCode();
            //Convertimos la respuesta a una variable string
            var jsonResult = response.Content.ReadAsStringAsync().Result;
            //Se deserializa la cadena y se convierte en una instancia de WeatherResult
            var weather = JsonConvert.DeserializeObject<WeatherResult>(jsonResult);
            //Asignamos el nuevo valor de las propiedades
            SetValue(weather);
        }
    }
}

3.- Cambiamos el nombre del método “GetWeatherAsync” por “GetRestServiceDataAsync”

4.- Eliminamos la llamada al método “SetValue(weather)”

5.- En este punto, seguramente tendremos un problema diciendo que el tipo “WeatherResult” no existe, por lo que podremos preguntarnos, ¿Qué podemos hacer? Básicamente, debemos hacer que cuando la clase sea creada, podamos pasarle el tipo de dato que se utilizará como tipo genérico en la clase, en este caso, será la definición de nuestro modelo de datos extraído del archivo json obtenido de nuestro servicio web, tal como lo hemos hecho anteriormente. Para resolver esto, añadiremos la sintaxis “<T>” al final de la definición de la clase:

public class HttpHelper<T>

6.- Sustituimos la palabra “WeatherResult” por una T, para que se lleve a cabo la deserialización del tipo T, que podrá ser cualquier clase que definamos, y no de una clase específica.

7.- Finalmente, después de algunos pequeños cambios, nuestra clase queda de la siguiente forma:

using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace RESTGenerico1.Helpers
{
    public class HttpHelper<T>
    {
        public async Task<T> GetRestServiceDataAsync(string serviceAddress)
        {
            //Creamos una instancia de HttpClient
            var client = new HttpClient();
            //Asignamos la URL
            client.BaseAddress = new Uri(serviceAddress);
            //Llamada asíncrona al sitio
            var response = await client.GetAsync(client.BaseAddress);
            //Nos aseguramos de recibir una respuesta satisfactoria
            response.EnsureSuccessStatusCode();
            //Convertimos la respuesta a una variable string
            var jsonResult = response.Content.ReadAsStringAsync().Result;
            //Se deserializa la cadena y se convierte en una instancia de WeatherResult
            var result = JsonConvert.DeserializeObject<T>(jsonResult);
        }
    }
}

¡Probemos nuestra clase!

1.- Buscamos un servicio rest, en mi caso, será un servicio que te permite ingresar una dirección IP, y ubicar el país donde se encuentra.

2.- Copiemos el contenido en formato JSON:

{
  "RestResponse" : {
    "result" : {
      "countryIso2" : "US",
      "stateAbbr" : "CA",
      "postal" : "94043",
      "continent" : "North America",
      "state" : "California",
      "longitude" : "-122.0574",
      "latitude" : "37.4192",
      "ds" : "II",
      "network" : "AS15169 Google Inc.",
      "city" : "Mountain View",
      "country" : "United States",
      "ip" : "172.217.3.14"
    }
  }
}

3.- Lo pegamos en VS, con la opción Paste JSON as classes

4.- Creamos una página sencilla:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:RESTGenerico1"
             x:Class="RESTGenerico1.MainPage">
    <StackLayout Margin="10">
        <Label Text="Ingrese la IP: "/>
        <Entry x:Name="txtIP"/>
        <Button x:Name="btnObtenerDatos" Text="¡Obtener Datos!"/>
        <Label Text="Resultados: "/>
        <Entry x:Name="edtResults"/>
    </StackLayout>
</ContentPage>

5.- Escribimos el código para ejecutar el proceso:

btnObtenerDatos.Clicked += async (sender, e) =>
              {
                  var url = "http://geo.groupkt.com/ip/172.217.3.14/json";
                  var servicio = new HttpHelper<Rootobject>();
                  var result = await servicio.GetRestServiceDataAsync(url);
                  var mensaje = $"País: {result.RestResponse.result.country}, Ciudad: {result.RestResponse.result.city}";
                  edtResults.Text = mensaje;
              };

6.- Si todo ha salido bien, debemos ver algo como lo siguiente:

Servicio Web consumido
Servicio Web consumido

Saludos.

6 comentarios en “Xamarin.Forms – Clase genérica para consumir servicios REST”

  1. amigo me sirvio la clase generica gracias..pero como hago para consumir varios servicos rest dentro del mismo proyecto,, esa misma clase generica me serviria para todos?

  2. Buen Día. Intenté acceder al link de la entrada anterior donde comentas que llevaron a cabo el consumo de un servicio rest desde Xamarin.Forms y no me funcionaron ninguno de los dos. Comento que no estoy suscrito, no se si esto haya influido en que no pudiera acceder, por favor, te pido me apoyes con la url si fuese este un recurso gratuito. Saludos desde Monterrey, Nuevo Leon, Mexico.

Deja un comentario

Tu dirección de correo electrónico no será publicada.