从 .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)

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

  1. 用ASP.NET Core 2.1 建立规范的 REST API -- HATEOAS

    本文所需的一些预备知识可以看这里:  用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识 和  用ASP.NET Core 2.0 建立规范的 REST API -- 预 ...

  2. EXT调用ASP.NET AJAX WebService

    在asp.net ajax中,使客户端调用WebService变得非常的简单,而且非常有用(个人觉得这个功能是asp.net ajax的核心,很多与客户端的交互都需要个功能来辅助实现).那在EXT中, ...

  3. JAVA客户端调用SAP提供的接口(保姆级教程)

    目前接触到SAP提供了两种不同的接口,对应也有两种不同的调用方式:1.Restful接口,支持直接通过post请求调用:2.WSDL接口,需要使用SoapUI测试并生成代码调用.大家在对接前要先确认接 ...

  4. 连接Android与ASP.NET Core Web API的完整教程

    目录 准备数据库 ASP.NET Core Web API项目 创建新的ASP.NET Core Web API项目 实体 导入EF Core 创建DbContext 将连接字符串添加到appsett ...

  5. jquery ajax跨域asp,jQuery跨域调用Asp.Net Web API

    Asp.Net Web API是一个轻量级的Web服务,当Web API和Web程序不是部署在同一域的时候,要使用jQuery来实现调用API的接口就存在跨域的问题.下面介绍两种方式来解决jQuery ...

  6. 生成用于ASP.NET Web API的TypeScript客户端API

    目录 介绍 备注 背景 推定(Presumptions) 使用代码 步骤0:将NuGet package WebApiClientGen和WebApiClientGen.jQuery安装到Web AP ...

  7. 返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API

    返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API 原文:返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 ...

  8. Asp.Net Web API 2第七课——Web API异常处理

    Asp.Net Web API 2第七课--Web API异常处理 原文:Asp.Net Web API 2第七课--Web API异常处理 前言 阅读本文之前,您也可以到Asp.Net Web AP ...

  9. ASP.NET AJAX1.0尝鲜试用:Web Service调用

    系统环境:Windows Server 2003 + IIS6 开发环境:Visual Web Developer 2005速成版 + ASP.NET AJAX 1.0 使用目的:无刷新调用服务器端的 ...

最新文章

  1. 送一台27寸高清显示器
  2. c语言折半查找法_C语言学习|选择法排序及折半查找法查找
  3. leeds计算机科学理学硕士,利兹大学数学及计算机科学理学硕士研究生申请要求及申请材料要求清单...
  4. python会议室系统预定_python项目篇-酒店(会议室,电影)预定
  5. TCP通信的服务器端代码实现
  6. Excel数据生成SQL insert语句
  7. html用a标签怎么提交表单?
  8. OpenCV_01 简介+无版权安装+模块分析
  9. Java springboot访问templates的html和静态资源
  10. java数组_Java数组
  11. C语言基础5-预编译部分知识(#include+.h文件和.c文件的区别
  12. 本科毕业论文答辩ppt模板
  13. [VS]网页连接数据库
  14. JS之 动态控制checkbo选中状态
  15. ArcGIS Server 10.8.1安装
  16. 【故障|监听】TNS-12518、TNS-00517和 Linux Error:32:Broken pipe
  17. 【数据结构】-大二数据结构与算法课程设计实训报告
  18. 上海智慧城市发展研究院领导一行莅临闪马智能,调研视频智能分析技术应用能力
  19. 移动电力猫HG260GT pon实现路由拨号
  20. 【Linux】fork之后,子进程继承了父进程哪些内容

热门文章

  1. 通俗易懂!视觉slam第四部分——slam刚体三维空间运动
  2. 跨境电商ERP是什么?
  3. c语言程序设计实验8,C语言程序设计实验八结构体.doc
  4. java final 函数_JAVA中Final的用法
  5. 花书+吴恩达深度学习(九)优化方法之二阶近似方法(牛顿法, CG, BFGS, L-BFGS)
  6. 吴恩达机器学习(四)逻辑回归(二分类与多分类)
  7. mysql主从同步读写分离
  8. Google code android开源项目(五)
  9. 用OSSIM平台轻松发现“心脏出血”漏洞
  10. php整么去掉时间的年月日,php强大的时间转换函数strtotime