Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Este contenido es para una versión anterior de .NET. El nuevo desarrollo debe usar ASP.NET Core. Para obtener más información sobre el uso de ASP.NET Core Web API, consulte:
- Tutorial: Creación de una API web con ASP.NET Core
- Llamada a un punto de conexión HTTP desde un cliente .NET
Descargar proyecto completado.
En este tutorial se muestra cómo llamar a una API web desde una aplicación .NET mediante System.Net.Http.HttpClient.
En este tutorial, se escribe una aplicación cliente que consume la siguiente API web:
| Acción | Método HTTP | URI relativo |
|---|---|---|
| Obtener un producto según el id. | OBTÉN | /api/products/id |
| Crear un nuevo producto | POST | /api/products |
| Actualización de un producto | PONER | /api/products/id |
| Eliminar un producto | DELETE | /api/products/id |
Para obtener información sobre cómo implementar esta API con ASP.NET API web, consulte Creación de una API web que admita operaciones CRUD.
Para simplificar, la aplicación cliente de este tutorial es una aplicación de consola de Windows. HttpClient también es compatible con las aplicaciones de la Tienda Windows y Windows Phone. Para más información, consulte Escritura de código de cliente de API web para varias plataformas mediante bibliotecas portátiles.
NOTA: Si pasa direcciones URL base y URI relativas como valores codificados de forma rígida, tenga en cuenta las reglas para usar la HttpClient API. La HttpClient.BaseAddress propiedad debe establecerse en una dirección con una barra diagonal final (/). Por ejemplo, al pasar URI de recursos codificados de forma rígida al HttpClient.GetAsync método , no incluya una barra diagonal inicial. Para obtener un Product por identificador:
- Establecer
client.BaseAddress = new Uri("https://localhost:5001/"); - Solicite un
Product. Por ejemplo:client.GetAsync<Product>("api/products/4");.
Creación de la aplicación de consola
En Visual Studio, cree una nueva aplicación de consola de Windows denominada HttpClientSample y pegue el código siguiente:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace HttpClientSample
{
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
class Program
{
static HttpClient client = new HttpClient();
static void ShowProduct(Product product)
{
Console.WriteLine($"Name: {product.Name}\tPrice: " +
$"{product.Price}\tCategory: {product.Category}");
}
static async Task<Uri> CreateProductAsync(Product product)
{
HttpResponseMessage response = await client.PostAsJsonAsync(
"api/products", product);
response.EnsureSuccessStatusCode();
// return URI of the created resource.
return response.Headers.Location;
}
static async Task<Product> GetProductAsync(string path)
{
Product product = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product;
}
static async Task<Product> UpdateProductAsync(Product product)
{
HttpResponseMessage response = await client.PutAsJsonAsync(
$"api/products/{product.Id}", product);
response.EnsureSuccessStatusCode();
// Deserialize the updated product from the response body.
product = await response.Content.ReadAsAsync<Product>();
return product;
}
static async Task<HttpStatusCode> DeleteProductAsync(string id)
{
HttpResponseMessage response = await client.DeleteAsync(
$"api/products/{id}");
return response.StatusCode;
}
static void Main()
{
RunAsync().GetAwaiter().GetResult();
}
static async Task RunAsync()
{
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:64195/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
// Create a new product
Product product = new Product
{
Name = "Gizmo",
Price = 100,
Category = "Widgets"
};
var url = await CreateProductAsync(product);
Console.WriteLine($"Created at {url}");
// Get the product
product = await GetProductAsync(url.PathAndQuery);
ShowProduct(product);
// Update the product
Console.WriteLine("Updating price...");
product.Price = 80;
await UpdateProductAsync(product);
// Get the updated product
product = await GetProductAsync(url.PathAndQuery);
ShowProduct(product);
// Delete the product
var statusCode = await DeleteProductAsync(product.Id);
Console.WriteLine($"Deleted (HTTP Status = {(int)statusCode})");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
}
}
El código anterior es la aplicación cliente completa.
RunAsync se ejecuta y se bloquea hasta que se completa. La mayoría de los métodos HttpClient son asincrónicos, ya que realizan E/S de red. Todas las tareas asincrónicas se realizan dentro de RunAsync. Normalmente, una aplicación no bloquea el subproceso principal, pero esta aplicación no permite ninguna interacción.
static async Task RunAsync()
{
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:64195/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
// Create a new product
Product product = new Product
{
Name = "Gizmo",
Price = 100,
Category = "Widgets"
};
var url = await CreateProductAsync(product);
Console.WriteLine($"Created at {url}");
// Get the product
product = await GetProductAsync(url.PathAndQuery);
ShowProduct(product);
// Update the product
Console.WriteLine("Updating price...");
product.Price = 80;
await UpdateProductAsync(product);
// Get the updated product
product = await GetProductAsync(url.PathAndQuery);
ShowProduct(product);
// Delete the product
var statusCode = await DeleteProductAsync(product.Id);
Console.WriteLine($"Deleted (HTTP Status = {(int)statusCode})");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
Instalación de las bibliotecas cliente de API web
Use el Administrador de paquetes NuGet para instalar el paquete de bibliotecas cliente de API web.
En el menú Tools, seleccione NuGet Package Manager>Package Manager Console. En la Consola del Administrador de paquetes (PMC), escriba el siguiente comando:
Install-Package Microsoft.AspNet.WebApi.Client
El comando anterior agrega los siguientes paquetes NuGet al proyecto:
- Microsoft.AspNet.WebApi.Client
- Newtonsoft.Json
Newtonsoft.Json (también conocido como Json.NET) es un conocido marco JSON de alto rendimiento para .NET.
Agregar una clase de modelo
Examine la Product clase :
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
Esta clase coincide con el modelo de datos usado por la API web. Una aplicación puede usar HttpClient para leer una Product instancia de una respuesta HTTP. La aplicación no tiene que escribir ningún código de deserialización.
Creación e inicialización de HttpClient
Examine la propiedad HttpClient estática:
static HttpClient client = new HttpClient();
HttpClient está pensado para ser instanciado una vez y reutilizarse a lo largo de la vida de una aplicación. Las condiciones siguientes pueden dar lugar a errores de SocketException :
- Creación de una nueva instancia de HttpClient por solicitud.
- Servidor bajo carga pesada.
La creación de una nueva instancia de HttpClient por solicitud puede agotar los sockets disponibles.
El código siguiente inicializa la instancia httpClient :
static async Task RunAsync()
{
// Update port # in the following line.
client.BaseAddress = new Uri("http://localhost:64195/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
El código anterior:
- Establece el URI base para las solicitudes HTTP. Cambie el número de puerto al puerto usado en la aplicación de servidor. La aplicación no funcionará a menos que se use el puerto de la aplicación de servidor.
- Establece el encabezado Accept en "application/json". Al establecer este encabezado, se indica al servidor que envíe datos en formato JSON.
Envío de una solicitud GET para recuperar un recurso
El código siguiente envía una solicitud GET para un producto:
static async Task<Product> GetProductAsync(string path)
{
Product product = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product;
}
El método GetAsync envía la solicitud HTTP GET. Cuando se completa el método, devuelve un HttpResponseMessage que contiene la respuesta HTTP. Si el código de estado de la respuesta es un código de éxito, el cuerpo del mensaje de respuesta contiene la representación JSON de un producto. Llame a ReadAsAsync para deserializar la carga JSON en una Product instancia. El método ReadAsAsync es asincrónico porque el cuerpo de la respuesta puede ser arbitrariamente grande.
HttpClient no produce una excepción cuando la respuesta HTTP contiene un código de error. En su lugar, la propiedad IsSuccessStatusCode es false si el estado es un código de error. Si prefiere tratar los códigos de error HTTP como excepciones, llame a HttpResponseMessage.EnsureSuccessStatusCode en el objeto de respuesta.
EnsureSuccessStatusCode produce una excepción si el código de estado está fuera del intervalo comprendido entre 200 y 299. Tenga en cuenta que HttpClient puede producir excepciones por otros motivos; por ejemplo, si la solicitud agota el tiempo de espera.
Formateadores de tipo de medio para deserializar
Cuando se llama a ReadAsAsync sin parámetros, utiliza un conjunto predeterminado de formateadores de medios para leer el cuerpo de la respuesta. Los formateadores predeterminados admiten datos con codificación JSON, XML y Form-url.
En lugar de usar los formateadores predeterminados, puede proporcionar una lista de formateadores al método ReadAsAsync . El uso de una lista de formateadores es útil si tiene un formateador de tipo multimedia personalizado:
var formatters = new List<MediaTypeFormatter>() {
new MyCustomFormatter(),
new JsonMediaTypeFormatter(),
new XmlMediaTypeFormatter()
};
resp.Content.ReadAsAsync<IEnumerable<Product>>(formatters);
Para obtener más información, consulte Formateadores multimedia en ASP.NET Web API 2.
Envío de una solicitud POST para crear un recurso
El código siguiente envía una solicitud POST que contiene una Product instancia en formato JSON:
static async Task<Uri> CreateProductAsync(Product product)
{
HttpResponseMessage response = await client.PostAsJsonAsync(
"api/products", product);
response.EnsureSuccessStatusCode();
// return URI of the created resource.
return response.Headers.Location;
}
El método PostAsJsonAsync :
- Serializa un objeto en JSON.
- Envía la carga JSON en una solicitud POST.
Si la solicitud se realiza correctamente:
- Debe devolver una respuesta 201 (Creada).
- La respuesta debe incluir la dirección URL de los recursos creados en el encabezado Ubicación.
Envío de una solicitud PUT para actualizar un recurso
El código siguiente envía una solicitud PUT para actualizar un producto:
static async Task<Product> UpdateProductAsync(Product product)
{
HttpResponseMessage response = await client.PutAsJsonAsync(
$"api/products/{product.Id}", product);
response.EnsureSuccessStatusCode();
// Deserialize the updated product from the response body.
product = await response.Content.ReadAsAsync<Product>();
return product;
}
El método PutAsJsonAsync funciona como PostAsJsonAsync, excepto que envía una solicitud PUT en lugar de POST.
Envío de una solicitud DELETE para eliminar un recurso
El código siguiente envía una solicitud DELETE para eliminar un producto:
static async Task<HttpStatusCode> DeleteProductAsync(string id)
{
HttpResponseMessage response = await client.DeleteAsync(
$"api/products/{id}");
return response.StatusCode;
}
Al igual que GET, una solicitud DELETE no tiene un cuerpo de solicitud. No es necesario especificar el formato JSON o XML con DELETE.
Pruebe el ejemplo
Para probar la aplicación cliente:
Descargue y ejecute la aplicación de servidor. Compruebe que la aplicación de servidor funciona. Por ejemplo,
http://localhost:64195/api/productsdebe devolver una lista de productos.Establezca el URI base para las solicitudes HTTP. Cambie el número de puerto al puerto usado en la aplicación de servidor.
static async Task RunAsync() { // Update port # in the following line. client.BaseAddress = new Uri("http://localhost:64195/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json"));Ejecute la aplicación cliente. Se produce el siguiente resultado:
Created at http://localhost:64195/api/products/4 Name: Gizmo Price: 100.0 Category: Widgets Updating price... Name: Gizmo Price: 80.0 Category: Widgets Deleted (HTTP Status = 204)