android 调用 asp.net web api,从 .NET 客户端调用 Web API (C#)

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

11/24/2017

本文内容

此内容适用于以前版本的 .NET。 新开发应该使用 ASP.NET Core。 有关使用 Core Web API ASP.NET,请参阅:

本教程演示如何使用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

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

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

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

字符集 client.BaseAddress = new Uri("https://localhost:5001/");

请求 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 包添加到项目中:

WebApi。

Newtonsoft.Json

(也称为 Json.NET 的 Newtonsoft.Js) 是适用于 .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 从 Product HTTP 响应中读取实例。 应用不必编写任何反序列化代码。

创建和初始化 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 如果状态代码不在 200 299 范围内,则会引发异常 – 。 请注意, HttpClient 可能会出于其他原因 — (例如,如果请求超时)而引发异常。

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

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

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

var formatters = new List() {

new MyCustomFormatter(),

new JsonMediaTypeFormatter(),

new XmlMediaTypeFormatter()

};

resp.Content.ReadAsAsync>(formatters);

发送 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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值