从 .NET 客户端调用 Web API (C#)

您所在的位置:网站首页 webapi接口测试 从 .NET 客户端调用 Web API (C#)

从 .NET 客户端调用 Web API (C#)

2023-06-21 18:01| 来源: 网络整理| 查看: 265

从 .NET 客户端 (C#) 调用 Web API 项目 09/21/2022

此内容适用于早期版本的 .NET。 新开发应使用 ASP.NET Core。 有关使用 ASP.NET Core Web API 的详细信息,请参阅:

教程:使用 ASP.NET Core 创建 Web API 从 .NET 客户端调用 HTTP 终结点

下载已完成的项目。

本教程介绍如何使用 System.Net.Http.HttpClient 从 .NET 应用程序调用 Web API。

在本教程中,将编写使用以下 Web API 的客户端应用:

操作 HTTP 方法 相对 URI 根据 ID 获取产品 GET /api/products/id 创建新产品 POST /api/products 更新产品 PUT /api/products/id 删除产品 DELETE /api/products/id

若要了解如何通过 ASP.NET Web API实现此 API,请参阅创建支持 CRUD 操作的 Web API。

为简单起见,本教程中的客户端应用程序是 Windows 控制台应用程序。 Windows Phone和 Windows 应用商店应用也支持 HttpClient。 有关详细信息,请参阅 使用可移植库为多个平台编写 Web API 客户端代码

注意: 如果将基 URL 和相对 URI 作为硬编码值传递,请注意使用 HttpClient API 的规则。 该 HttpClient.BaseAddress 属性应设置为具有尾随正斜杠 () / 的地址。 例如,将硬编码的资源 URI HttpClient.GetAsync 传递给方法时,不包括前导正斜杠。 若要按 ID 获取:Product

设置 client.BaseAddress = new Uri("https://localhost:5001/"); 请求 a Product. 例如,client.GetAsync("api/products/4");。

创建控制台应用程序

在 Visual Studio 中,创建新的名为 HttpClientSample 的 Windows 控制台应用,并粘贴以下代码:

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 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 GetProductAsync(string path) { Product product = null; HttpResponseMessage response = await client.GetAsync(path); if (response.IsSuccessStatusCode) { product = await response.Content.ReadAsAsync(); } return product; } static async Task 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(); return product; } static async Task 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(); } } }

前面的代码是完整的客户端应用。

RunAsync 运行并阻止,直到它完成。 大多数 HttpClient 方法都是异步方法,因为它们执行网络 I/O。 所有异步任务都在内部 RunAsync完成。 通常,应用不会阻止主线程,但此应用不允许任何交互。

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(); }

安装 Web API 客户端库

使用 NuGet 包管理器安装 Web API 客户端库包。

在“工具”菜单中,选择“NuGet 包管理器”>“包管理器控制台”。 在包管理器控制台 (PMC) 中,键入以下命令:

Install-Package Microsoft.AspNet.WebApi.Client

上述命令将以下 NuGet 包添加到项目中:

Microsoft.AspNet.WebApi.Client Newtonsoft.Json

Newtonsoft.Json (也称为 Json.NET) 是适用于 .NET 的常用高性能 JSON 框架。

添加模型类

检查 Product 类:

public class Product { public string Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; } }

此类与 Web API 使用的数据模型匹配。 应用可以使用 HttpClient 从 HTTP 响应读取 Product 实例。 应用无需编写任何反序列化代码。

创建和初始化 HttpClient

检查静态 HttpClient 属性:

static HttpClient client = new HttpClient();

HttpClient 旨在实例化一次,并在应用程序的整个生命周期内重复使用。 以下条件可能导致 SocketException 错误:

为每个请求创建新的 HttpClient 实例。 负载过重的服务器。

为每个请求创建新的 HttpClient 实例可能会耗尽可用套接字。

以下代码初始化 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"));

前面的代码:

设置 HTTP 请求的基本 URI。 将端口号更改为服务器应用中使用的端口。 除非使用服务器应用的端口,否则应用将不起作用。 将 Accept 标头设置为“application/json”。 设置此标头会告知服务器以 JSON 格式发送数据。

发送 GET 请求以检索资源

以下代码发送产品的 GET 请求:

static async Task GetProductAsync(string path) { Product product = null; HttpResponseMessage response = await client.GetAsync(path); if (response.IsSuccessStatusCode) { product = await response.Content.ReadAsAsync(); } return product; }

GetAsync 方法发送 HTTP GET 请求。 方法完成后,它将返回包含 HTTP 响应的 HttpResponseMessage 。 如果响应中的状态代码为成功代码,则响应正文包含产品的 JSON 表示形式。 调用 ReadAsAsync 以反序列化 JSON 有效负载到 Product 实例。 ReadAsAsync 方法是异步的,因为响应正文可以任意大。

当 HTTP 响应包含错误代码时,HttpClient 不会引发异常。 相反,如果状态为错误代码, IsSuccessStatusCode 属性为 false 。 如果想要将 HTTP 错误代码视为异常,请对响应对象调用 HttpResponseMessage.EnsureSuccessStatusCode 。 EnsureSuccessStatusCode 如果状态代码超出范围 200–299,则引发异常。 请注意, HttpClient 可能会出于其他原因引发异常,例如,如果请求超时。

Media-Type格式化程序反序列化

在没有参数的情况下调用 ReadAsAsync 时,它使用默认的 一组媒体格式化程序 来读取响应正文。 默认格式化程序支持 JSON、XML 和表单 URL 编码数据。

可以向 ReadAsAsync 方法提供格式化程序列表,而不是使用默认格式化程序。 如果你有自定义媒体类型格式化程序,则使用格式化程序列表非常有用:

var formatters = new List() { new MyCustomFormatter(), new JsonMediaTypeFormatter(), new XmlMediaTypeFormatter() }; resp.Content.ReadAsAsync(formatters);

有关详细信息,请参阅 ASP.NET Web API 2 中的媒体格式化程序

发送 POST 请求以创建资源

以下代码发送一个 POST 请求,其中包含 Product JSON 格式的实例:

static async Task CreateProductAsync(Product product) { HttpResponseMessage response = await client.PostAsJsonAsync( "api/products", product); response.EnsureSuccessStatusCode(); // return URI of the created resource. return response.Headers.Location; }

PostAsJsonAsync 方法:

将对象序列化为 JSON。 在 POST 请求中发送 JSON 有效负载。

如果请求成功:

它应返回 201 (已创建) 响应。 响应应包括 Location 标头中创建资源的 URL。

发送 PUT 请求以更新资源

以下代码发送 PUT 请求以更新产品:

static async Task 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(); return product; }

PutAsJsonAsync 方法的工作方式类似于 PostAsJsonAsync,只不过它发送 PUT 请求而不是 POST。

发送 DELETE 请求以删除资源

以下代码发送 DELETE 请求以删除产品:

static async Task DeleteProductAsync(string id) { HttpResponseMessage response = await client.DeleteAsync( $"api/products/{id}"); return response.StatusCode; }

与 GET 一样,DELETE 请求没有请求正文。 无需使用 DELETE 指定 JSON 或 XML 格式。

测试示例

若要测试客户端应用,请执行以下操作:

下载 并运行服务器应用。 验证服务器应用是否正常工作。 例如, http://localhost:64195/api/products 应返回产品列表。

设置 HTTP 请求的基本 URI。 将端口号更改为服务器应用中使用的端口。

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"));

运行客户端应用。 将生成以下输出:

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)


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3