Cómo crear un cliente C# para un Web API de ASP.NET Core (III)

En los anteriores artículos de este Blog: Cómo crear un cliente C# para un Web API de ASP.NET Core (I) y (II), vimos como generar un cliente C# para consumir un Web API de ASP.NET Core, con la ayuda de la herramienta NSwag Studio a partir de la especificación OpenAPI/Swagger.

Seguramente, muchos de los Web APIs que tengamos que consumir en entornos de producción, no dispongan de una interfaz Swagger que nos permita auto-generar un cliente C# con NSwag Studio. Para estos casos, debemos tener clara una estrategia de desarrollo, que nos permita construir clientes de Web API de una manera óptima, rápida y eficiente.

En este Artículo veremos cómo desarrollar un cliente C# empaquetado en una biblioteca de clases .NET Standard, para consumir un Web API tipo CRUD de ASP.NET Core.

 

El Web API tipo CRUD de ASP.NET Core

Para realizar este ejemplo, reutilizaremos el Web API ya desarrollado en el artículo JSON Web Token - Seguridad en servicios Web API de .NET Core.

Este Web API consta de un CRUD básico (GET, POST, PUT, DELETE) sobre una entidad de Modelo Pais.cs, y autenticación de usuarios basada en JSON Web Token.

Los Controladores de API son los siguientes:

LoginController : Se encarga de validar al usuario en el sistema de información, y devolver un Token JWT de acceso.

PaisController: Se encarga de realizar las operaciones CRUD sobre la base de datos. Requiere del Token JWT de acceso para funcionar, en caso contrario devolverá un HTTP 401 Unauthorized (acceso no autorizado).

 

Creando el Cliente C# - biblioteca de clases (dll)

Comenzaremos creando un nuevo proyecto en Visual Studio (WebApiClient.csproj) del tipo Biblioteca de clases (.NET Standard)

Nota: La razón por la cual utilizamos una biblioteca .NET Standard, radica en poder mantener la compatibilidad de nuestro cliente de Web API, a la hora de poder ser integrado tanto en aplicaciones .NET Core como en aplicaciones .NET Framework.

net-standard-prj

En esta biblioteca de clases, desarrollaremos el código C# para para el cliente de nuestro Web API, "empaquetando" toda la funcionalidad para que pueda ser reutilizada posteriormente en cualquier aplicación que la requiera. 

 

Definición de los Modelos

En primer lugar, definiremos los Modelos de datos necesarios para la comunicación con el Web API: UsuarioLogin.cs y Pais.cs.

    public class UsuarioLogin
    {
        [JsonProperty("usuario", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
        public string Usuario { get; set; }

        [JsonProperty("password", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
        public string Password { get; set; }
    }
    public class Pais
    {
        [JsonProperty("id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Guid Id { get; set; }

        [JsonProperty("nombre", Required = Newtonsoft.Json.Required.Always)]
        public string Nombre { get; set; }

        [JsonProperty("habitantes", Required = Newtonsoft.Json.Required.Always)]
        public int Habitantes { get; set; }
    }

 

Definiendo las Interfaces 

Seguidamente definiremos las interfaces para los Clientes de Web APIILoginClient.cs y IPaisClient.cs .

    public interface ILoginClient
    {
        string BaseUrl { get; set; }

        Task<object> LoginAsync(UsuarioLogin usuarioLogin);
    }
    public interface IPaisClient
    {
        string BaseUrl { get; set; }
        string BearerTokenJWT { get; set; }

        Task<Pais> DeletePaisAsync(Guid id, Pais pais);
        Task<Pais> GetPaisAsync(Guid id);
        Task<List<Pais>> GetPaisesAsync();
        Task<Pais> PostPaisAsync(Pais pais);
        Task<Pais> PutPaisAsync(Guid id, Pais pais);
    }

 

El Cliente de acceso - LoginClient

El Cliente LoginClient(), a través de su método LoginAsync(), se encargará de validar un usuario en el sistema de información del Web API, y devolver un Token JWT de acceso en el caso de ser un usuario autenticado.

El método LoginAsync() será del tipo POST, y recibirá como parámetro un objeto del tipo UsuarioLogin (Usuario y Contraseña). La respuesta esperada será del tipo HTTP Status OK 200, devolviendo un objeto anónimo en formato Json con el Token JWT de acceso:

{
"token": 
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2MTc4MzM0Mi1jNGYyLTQ1Y2QtODhmZi1mMWMxZTA2
MGE3YWUiLCJuYW1laWQiOiJiNWQyMzNmMC02ZWMyLTQ5NTAtOGNkNy1mNDRkMTZlYzg3OGYiLCJub21icmUiOiJOb2
1icmUgVXN1YXJpbyIsImFwZWxsaWRvcyI6IkFwZWxsaWRvcyBVc3VhcmlvIiwiZW1haWwiOiJlbWFpbC51c3Vhcmlv
QGRvbWluaW8uY29tIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYW
ltcy9yb2xlIjoiQWRtaW5pc3RyYWRvciIsIm5iZiI6MTU3MjE0MjI1NSwiZXhwIjoxNTcyMTQzMTU1LCJpc3MiOiJ3
d3cucmFmYWVsYWNvc3RhLm5ldCIsImF1ZCI6Ind3dy5yYWZhZWxhY29zdGEubmV0L2FwaS9taXdlYmFwaSJ9.Oo3ob
WEdOHCWxp3j8530huRJrZz69lkur7ABwXhxYBo"
}

El código del cliente LoginClient() será el siguiente:

    public class LoginClient : ILoginClient
    {
        // DEFINICIÓN DE VARIABLES PRIVADAS.
        private string _baseUrl = "https://localhost:5001";

        private HttpClient _httpClient;

        // OBTENEMOS A TRAVÉS DE CONSTRUCTOR EL HttpClient.
        public LoginClient(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }

        // PROPIEDAD PUBLICA PARA ASIGNAR O LEER
        // LA URL-BASE DEL WEB-API.
        public string BaseUrl
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }

        //////////////////////////////////////
        // ACCIONES/OPERACIONES DEL WEB-API //
        //////////////////////////////////////

        /////////////////
        // ACCIÓN POST //
        /////////////////
        public async Task<object> LoginAsync(UsuarioLogin usuarioLogin)
        {
            // CONSTRUIMOS LA URL DE LA ACCIÓN
            var urlBuilder_ = new StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "")
                       .Append("/api/Login");
            var url_ = urlBuilder_.ToString();

            // RECUPERAMOS EL HttpClient
            var client_ = _httpClient;

            try
            {                
                using (var request_ = new HttpRequestMessage())
                {
                    ///////////////////////////////////////
                    // CONSTRUIMOS LA PETICIÓN (REQUEST) //
                    ///////////////////////////////////////
                    // DEFINIMOS EL Content CON EL OBJETO A ENVIAR SERIALIZADO.
                    request_.Content = new StringContent(JsonConvert.SerializeObject(usuarioLogin));

                    // DEFINIMOS EL ContentType, EN ESTE CASO ES "application/json"
                    request_.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                    // DEFINIMOS EL MÉTODO HTTP
                    request_.Method = new HttpMethod("POST");

                    // DEFINIMOS LA URI
                    request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);

                    // DEFINIMOS EL Accept, EN ESTE CASO ES "application/json"
                    request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));

                    /////////////////////////////////////////
                    // CONSTRUIMOS LA RESPUESTA (RESPONSE) //
                    /////////////////////////////////////////
                    // Utilizamos ConfigureAwait(false) para evitar el DeadLock.
                    var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);

                    // OBTENEMOS EL Content DEL RESPONSE como un String
                    // Utilizamos ConfigureAwait(false) para evitar el DeadLock.
                    var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // SI ES LA RESPUESTA ESPERADA !! ...
                    if (response_.StatusCode == System.Net.HttpStatusCode.OK) // 200
                    {
                        // DESERIALIZAMOS Content DEL RESPONSE
                        var responseBody_ = JsonConvert.DeserializeObject<object>(responseText_);
                        return responseBody_;
                    }
                    else
                    // SI NO SE ESTÁ AUTORIZADO ...
                    if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
                    {
                        throw new Exception("401 Unauthorized. Las credenciales de acceso del usuario son incorrectas. " +
                            responseText_);
                    }
                    else
                    // CUALQUIER OTRA RESPUESTA ...
                    if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
                        response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
                    {
                        throw new Exception((int)response_.StatusCode + ". No se esperaba el código de estado HTTP de la respuesta. " +
                            responseText_);
                    }

                    // RETORNAMOS EL OBJETO POR DEFECTO ESPERADO
                    return default(object);
                }
            }
            finally
            {
                // NO UTILIZAMOS CATCH, 
                // PASAMOS LA EXCEPCIÓN A LA APP.
            }
        }
    }

 

El Cliente CRUD - PaisClient

El cliente PaisClient(), será el encargado de realizar las operaciones CRUD sobre la base de datos.

Lo mas importante a destacar en la implementación de este cliente, es la inclusión de la propiedad BearerTokenJWT. A través de esta propiedad, debemos enviar el Token JWT de acceso al Web API en cada operación HTTP que realicemos.

El código común a todos los métodos del cliente PaisClient() sería el siguiente:

    ///////////////////////////////
    // CLASE CLIENTE DEL WEB-API //
    ///////////////////////////////
    public class PaisClient : IPaisClient
    {
        //////////////////////////////////////
        // DEFINICIÓN DE VARIABLES PRIVADAS //
        //////////////////////////////////////
        private string _baseUrl = "https://localhost:5001";

        // DEFINIMOS EL TOKEN JWT A NIVEL DE CLASE.
        private string _bearerTokenJWT = string.Empty;

        // DEFINIMOS EL CLIENTE HTTP A NIVELDE CLASE.
        private HttpClient _httpClient;

        // OBTENEMOS A TRAVÉS DE CONSTRUCTOR EL HttpClient
        // (POR INYECCIÓN DE DEPENDENCIAS).
        public PaisClient(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }

        // PROPIEDAD PUBLICA PARA ASIGNAR O LEER
        // LA URL-BASE DEL WEB-API.
        public string BaseUrl
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }

        // PROPIEDAD PUBLICA PARA ASIGNAR O LEER
        // EL TOKEN JWT DE ACCESO
        public string BearerTokenJWT
        {
            get { return _bearerTokenJWT; }
            set { _bearerTokenJWT = value; }
        }

        //////////////////////////////////////
        // ACCIONES/OPERACIONES DEL WEB-API //
        //////////////////////////////////////

        ...
    }

 

Método GET - GetPaisesAsync()

El método GetPaisesAsync() será del tipo GET sin parámetros, hacia la URL del Web API /api/Pais.

La respuesta esperada será del tipo HTTP Status OK 200, devolviendo una lista de objetos del tipo List<Pais> :

        public async Task<List<Pais>> GetPaisesAsync()
        {
            // CONSTRUIMOS LA URL DE LA ACCIÓN
            var urlBuilder_ = new StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "")
                       .Append("/api/Pais");
            var url_ = urlBuilder_.ToString();

            // RECUPERAMOS EL HttpClient
            var client_ = _httpClient;

            try
            {
                using (var request_ = new HttpRequestMessage())
                {
                    ///////////////////////////////////////
                    // CONSTRUIMOS LA PETICIÓN (REQUEST) //
                    ///////////////////////////////////////
                    // DEFINIMOS EL MÉTODO HTTP
                    request_.Method = new HttpMethod("GET");

                    // DEFINIMOS LA URI
                    request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);

                    // DEFINIMOS EL Accept, EN ESTE CASO ES "application/json"
                    request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));

                    // ASIGNAMOS A LA CABECERA DE LA PETICIÓN EL TOKEN JWT.
                    if (!string.IsNullOrEmpty(_bearerTokenJWT))
                        request_.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerTokenJWT);

                    /////////////////////////////////////////
                    // CONSTRUIMOS LA RESPUESTA (RESPONSE) //
                    /////////////////////////////////////////
                    // Utilizamos ConfigureAwait(false) para evitar el DeadLock.
                    var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);

                    // OBTENEMOS EL Content DEL RESPONSE como un String
                    // Utilizamos ConfigureAwait(false) para evitar el DeadLock.
                    var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // SI ES LA RESPUESTA ESPERADA !! ...
                    if (response_.StatusCode == System.Net.HttpStatusCode.OK) // 200
                    {
                        // DESERIALIZAMOS Content DEL RESPONSE
                        var responseBody_ = JsonConvert.DeserializeObject<List<Pais>>(responseText_);
                        return responseBody_;
                    }
                    else
                    // SI NO SE ESTÁ AUTORIZADO ...
                    if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
                    {
                        throw new Exception("401 Unauthorized. No se ha indicado o es incorrecto el Token JWT de acceso. " +
                            responseText_);
                    }
                    else
                    // CUALQUIER OTRA RESPUESTA ...
                    if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
                        response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
                    {
                        throw new Exception((int)response_.StatusCode + ". No se esperaba el código de estado HTTP de la respuesta. " +
                            responseText_);
                    }

                    // RETORNAMOS EL OBJETO POR DEFECTO ESPERADO
                    return default(List<Pais>);
                }
            }
            finally
            {
                // NO UTILIZAMOS CATCH, 
                // PASAMOS LA EXCEPCIÓN A LA APP.
            }
        }

 

Método GET - GetPaisAsync(Guid id)

El método GetPaisAsync() será del tipo GET hacia la URL del Web API /api/Pais/id. Como parámetro de entrada recibirá el id del objeto a recuperar de la base de datos.

La respuesta esperada será del tipo HTTP Status OK 200, devolviendo el objeto solicitado del tipo Pais :

        public async Task<Pais> GetPaisAsync(Guid id)
        {
            if (id == null)
                throw new System.ArgumentNullException("id");

            // CONSTRUIMOS LA URL //
            var urlBuilder_ = new StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "")
                       .Append("/api/Pais/{id}");
            urlBuilder_.Replace("{id}", Uri.EscapeDataString(id.ToString()));
            var url_ = urlBuilder_.ToString();

            // RECUPERAMOS EL HttpClient
            var client_ = _httpClient;

            try
            {
                using (var request_ = new HttpRequestMessage())
                {
                    // CONSTRUIMOS LA PETICIÓN (REQUEST) //
                    request_.Method = new HttpMethod("GET");
                    request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
                    request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
                    if (!string.IsNullOrEmpty(_bearerTokenJWT))
                        request_.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerTokenJWT);

                    // CONSTRUIMOS LA RESPUESTA (RESPONSE) //
                    var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
                    var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // RESPUESTA ESPERADA !! //
                    if (response_.StatusCode == System.Net.HttpStatusCode.OK) // 200
                    {
                        var responseBody_ = JsonConvert.DeserializeObject<Pais>(responseText_);
                        return responseBody_;
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
                    {
                        throw new Exception("401 Unauthorized. No se ha indicado o es incorrecto el Token JWT de acceso. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.NotFound) // 404
                    {
                        throw new Exception("404 NotFound. No se ha encontrado el objeto solicitado. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
                        response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
                    {
                        throw new Exception((int)response_.StatusCode + ". No se esperaba el código de estado HTTP de la respuesta. " +
                            responseText_);
                    }
                    return default(Pais);
                }
            }
            finally
            {
                // NO UTILIZAMOS CATCH, 
                // PASAMOS LA EXCEPCIÓN A LA APP.
            }
        }

 

Método POST - PostPaisAsync(Pais pais)

El método PostPaisAsync() será del tipo POST hacia la URL del Web API /api/Pais. Como parámetro de entrada recibirá un objeto del tipo Pais el cual será insertado en la base de datos.

La respuesta esperada será del tipo HTTP Status Created 201, devolviendo el objeto creado del tipo Pais :

        public async Task<Pais> PostPaisAsync(Pais pais)
        {
            // CONSTRUIMOS LA URL //
            var urlBuilder_ = new StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "")
                       .Append("/api/Pais");
            var url_ = urlBuilder_.ToString();

            // RECUPERAMOS EL HttpClient
            var client_ = _httpClient;

            try
            {
                using (var request_ = new HttpRequestMessage())
                {
                    // CONSTRUIMOS LA PETICIÓN (REQUEST) //
                    // DEFINIMOS EL Content (CUERPO) CON EL OBJETO A ENVIAR SERIALIZADO.
                    request_.Content = new StringContent(JsonConvert.SerializeObject(pais));
                    // DEFINIMOS EL ContentType (CUERPO), EN ESTE CASO ES "application/json"
                    request_.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                    request_.Method = new HttpMethod("POST");
                    request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
                    request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
                    if (!string.IsNullOrEmpty(_bearerTokenJWT))
                        request_.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerTokenJWT);

                    // CONSTRUIMOS LA RESPUESTA (RESPONSE) //
                    var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
                    var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // RESPUESTA ESPERADA !! //
                    if (response_.StatusCode == System.Net.HttpStatusCode.Created) // 201
                    {
                        var responseBody_ = JsonConvert.DeserializeObject<Pais>(responseText_);
                        return responseBody_;
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
                    {
                        throw new Exception("401 Unauthorized. No se ha indicado o es incorrecto el Token JWT de acceso. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.BadRequest) // 400
                    {
                        throw new Exception("400 BadRequest. No se ha creado el objeto en la BD. Formato del objeto incorrecto. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
                        response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
                    {
                        throw new Exception((int)response_.StatusCode + ". No se esperaba el código de estado HTTP de la respuesta. " +
                            responseText_);
                    }
                    return default(Pais);
                }
            }
            finally
            {
                // NO UTILIZAMOS CATCH, 
                // PASAMOS LA EXCEPCIÓN A LA APP.
            }
        }

 

Método PUT - PutPaisAsync(Guid id, Pais pais)

El método PutPaisAsync() será del tipo PUT hacia la URL del Web API /api/Pais/id. Como parámetro de entrada recibirá el id del objeto a modificar en la base de datos, y un objeto del tipo Pais con los nuevos datos.

La respuesta esperada será del tipo HTTP Status NoContent 204, devolviendo el objeto modificado del tipo Pais :

        public async Task<Pais> PutPaisAsync(Guid id, Pais pais)
        {
            if (id == null)
                throw new System.ArgumentNullException("id");

            // CONSTRUIMOS LA URL //
            var urlBuilder_ = new StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "")
                       .Append("/api/Pais/{id}");
            urlBuilder_.Replace("{id}", Uri.EscapeDataString(id.ToString()));
            var url_ = urlBuilder_.ToString();

            // RECUPERAMOS EL HttpClient
            var client_ = _httpClient;

            try
            {
                using (var request_ = new HttpRequestMessage())
                {
                    // CONSTRUIMOS LA PETICIÓN (REQUEST) //
                    // DEFINIMOS EL Content (CUERPO) CON EL OBJETO A ENVIAR SERIALIZADO.
                    request_.Content = new StringContent(JsonConvert.SerializeObject(pais));
                    // DEFINIMOS EL ContentType (CUERPO), EN ESTE CASO ES "application/json"
                    request_.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                    request_.Method = new HttpMethod("PUT");
                    request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
                    request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
                    if (!string.IsNullOrEmpty(_bearerTokenJWT))
                        request_.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerTokenJWT);

                    // CONSTRUIMOS LA RESPUESTA (RESPONSE) //
                    var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
                    var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // RESPUESTA ESPERADA !! //
                    if (response_.StatusCode == System.Net.HttpStatusCode.NoContent) // 204
                    {
                        // COMO EL WEB-API NO VEVUELVE NADA EN LA RESPUESTA ESPERADA,
                        // DEVOLVEMOS EL OBJETO MODIFICADO
                        return pais;
                        //var responseBody_ = JsonConvert.DeserializeObject<Pais>(responseText_);
                        //return responseBody_;
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
                    {
                        throw new Exception("401 Unauthorized. No se ha indicado o es incorrecto el Token JWT de acceso. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.BadRequest) // 400
                    {
                        throw new Exception("400 BadRequest. No se ha creado el objeto en la BD. Formato del objeto incorrecto. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.NotFound) // 404
                    {
                        throw new Exception("404 NotFound. No se ha encontrado el objeto a modificar. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
                        response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
                    {
                        throw new Exception((int)response_.StatusCode + ". No se esperaba el código de estado HTTP de la respuesta. " +
                            responseText_);
                    }
                    return default(Pais);
                }
            }
            finally
            {
                // NO UTILIZAMOS CATCH, 
                // PASAMOS LA EXCEPCIÓN A LA APP.
            }
        }

 

Método DELETE - DeletePaisAsync(Guid id, Pais pais)

El método DeletePaisAsync() será del tipo DELETE hacia la URL del Web API /api/Pais/id. Como parámetro de entrada recibirá el id del objeto a eliminar de la base de datos, y un objeto del tipo Pais con los datos.

La respuesta esperada será del tipo HTTP Status OK 200, devolviendo el objeto eliminado del tipo Pais :

        public async Task<Pais> DeletePaisAsync(Guid id, Pais pais)
        {
            if (id == null)
                throw new System.ArgumentNullException("id");

            // CONSTRUIMOS LA URL //
            var urlBuilder_ = new StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "")
                       .Append("/api/Pais/{id}");
            urlBuilder_.Replace("{id}", Uri.EscapeDataString(id.ToString()));
            var url_ = urlBuilder_.ToString();

            // RECUPERAMOS EL HttpClient
            var client_ = _httpClient;

            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    // CONSTRUIMOS LA PETICIÓN (REQUEST) //
                    request_.Method = new HttpMethod("DELETE");
                    request_.RequestUri = new Uri(url_, System.UriKind.RelativeOrAbsolute);
                    request_.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
                    if (!string.IsNullOrEmpty(_bearerTokenJWT))
                        request_.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerTokenJWT);

                    // CONSTRUIMOS LA RESPUESTA (RESPONSE) //
                    var response_ = await client_.SendAsync(request_, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
                    var responseText_ = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // RESPUESTA ESPERADA !! //
                    if (response_.StatusCode == System.Net.HttpStatusCode.OK) // 200
                    {
                        var responseBody_ = JsonConvert.DeserializeObject<Pais>(responseText_);
                        return responseBody_;
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.Unauthorized) // 401
                    {
                        throw new Exception("401 Unauthorized. No se ha indicado o es incorrecto el Token JWT de acceso. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode == System.Net.HttpStatusCode.NotFound) // 404
                    {
                        throw new Exception("404 NotFound. No se ha encontrado el objeto a eliminar. " +
                            responseText_);
                    }
                    else
                    if (response_.StatusCode != System.Net.HttpStatusCode.OK && // 200
                        response_.StatusCode != System.Net.HttpStatusCode.NoContent) // 204
                    {
                        throw new Exception((int)response_.StatusCode + ". No se esperaba el código de estado HTTP de la respuesta. " +
                            responseText_);
                    }
                    return default(Pais);
                }
            }
            finally
            {
                // NO UTILIZAMOS CATCH, 
                // PASAMOS LA EXCEPCIÓN A LA APP.
            }
        }

 

La biblioteca de clases (dll)

En este punto, ya tendríamos finalizado nuestro proyecto WebApiClient.csproj con toda la funcionalidad necesaria para consumir el Web API de ASP.NET Core. 

Ahora solo quedaría compilar el proyecto para generar la dll correspondiente WebApiClient.dll, que posteriormente reutilizaríamos en nuestra aplicación .NET.

web-api-client

 

   EtiquetasWeb API C# .NET Standard ASP.NET Core

  Compartir


  Nuevo comentario

El campo Comentario es obligatorio.
El campo Nombre es obligatorio.

  Comentarios

Salvador Salvador

Tengo una duda, en el caso del acceso que tengo, me pide loguear con la siguiente cadena:
{"info":"U2FsdGVkX18Emf26eqn8fyOr+g3HwJNgmn6j0g135oG8Ot22lXfXLKtvMxKoDwbEzmWBJTm+fcmOX+PNWa0z7A=="}
En postman me funciona bien, pero no se como pasarlo por c# consola.
Rafael Acosta Administrador Rafael Acosta

@Roberto:

En el artículo Cómo crear un cliente C# para un Web API de ASP.NET Core (II), puedes ver cómo integrar un cliente C# creado con NSwag en una aplicación ASP.NET MVC Core. Básicamente es lo mismo que integrar el cliente C# creado en el ejemplo de este artículo, posiblemente tengas que realizar algunas modificaciones.


Para cualquier duda, no dudes en preguntar. 


 


 


Roberto Roberto

Como implementamos esta clase en un controlador y vista, es decir dentro de un proyecto mvc de net core ?
Roberto Roberto

How do we implement this class in a controller and view?

Perfil para Rafael Acosta en Stack Overflow en español, preguntas y respuestas para programadores y profesionales de la informática.

  Etiquetas

.NET Core .NET Framework .NET MVC .NET Standard AJAX ASP.NET ASP.NET Core ASP.NET MVC Bootstrap Buenas prácticas C# Cookies Entity Framework Gráficos JavaScript jQuery JSON JWT PDF Pruebas Unitarias Seguridad SEO SOAP Sql Server SqLite Swagger Validación Web API Web Forms Web Services WYSIWYG

  Nuevos


  Populares















Utilizamos cookies propias y de terceros para mejorar nuestros servicios y ofrecerle una mejor experiencia de navegación. Si continúa navegando consideramos que acepta su uso. Más información   Acepto