使用 WebApiClient 调用 ASP.NET WebApi 等 RESTful 服务






4.78/5 (11投票s)
在本教程的第一部分,我们将学习如何使用 NuGet 包 WebApiRestService.WebApiClient 调用 Web Api REST 服务。
引言
在本教程的第一部分,我们将学习如何使用 NuGet 包WebApiRestService.WebApiClient调用 Web Api REST 服务。
什么是 WebApiClient?
WebApiClient 是一个简单而强大的 .NET 可移植库,它作为应用程序和RESTful 服务(如 Microsoft WebApi)之间的中间层。它提供使用HttpClient 类发出异步、类型化WebApi 请求的方法。它负责创建请求、等待响应、处理异常并将响应转换为对象的所有逻辑,使您无需编写重复代码。
特点
- 它是可移植的。支持 .NET Framework 4.5+、Windows 8+ 应用、Windows Phone Silverlight 8+
- 支持任何类型的 RESTful 服务,不仅限于 Microsoft WebApi
- 可以与使用 ASP.NET Identity 安全性的服务一起使用
- 使用 NuGet 轻松安装
- 支持 Json 和 Xml 序列化/反序列化
- 支持 GET、POST、PUT 和 DELETE 方法
- 易于扩展功能
- 包含 WindowsIntegratedAuthentication(Negotiate、NTLM、Basic、Kerberos)和 BearerTokenAuthentication
- 易于发送或接收 Cookie
资源
您可以在以下网址找到更多信息和示例:http://webapiclient.azurewebsites.net
要下载 NuGet 包:https://nuget.net.cn/packages/WebApiRestService.WebApiClient
使用代码
首先,您需要设置一个解决方案,至少包含 3 个项目
- 一个 WebApi 项目
- 一个 MVC 项目(您可以选择您想要的项目类型)
- 一个类库项目,用于容纳 DTO 对象
在类库项目中
- 创建以下类
public class Restaurant
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
在 WebApi 项目中
- 添加对您在上一步中创建的 DTO类库项目的引用。
- 创建一个名为 RestaurantController 的控制器,并粘贴此类
public class RestaurantController : ApiController
{
List<Restaurant> restaurants = new List<Restaurant>() {
new Restaurant(){ Id = 1, Name = "Restaurant 1", Address = "1111 Oxford Street" },
new Restaurant(){ Id = 2, Name = "Restaurant 2", Address = "2222 Oxford Street" },
new Restaurant(){ Id = 3, Name = "Restaurant 3", Address = "3333 Oxford Street" },
new Restaurant(){ Id = 4, Name = "Restaurant 4", Address = "4444 Oxford Street" }
};
// GET: api/Restaurant
public IEnumerable<Restaurant> Get()
{
return restaurants;
}
// GET: api/Restaurant/5
public Restaurant Get(int id)
{
return restaurants.SingleOrDefault(r => r.Id == id);
}
// POST: api/Restaurant
public void Post([FromBody]Restaurant value)
{
restaurants.Add(value);
}
// PUT: api/Restaurant/5
public void Put([FromBody]Restaurant value)
{
restaurants.RemoveAll(r => r.Id == value.Id);
restaurants.Add(value);
}
// DELETE: api/Restaurant/5
public void Delete(int id)
{
restaurants.RemoveAll(r => r.Id == id);
}
}
在 MVC 项目中
Install-Package WebApiRestService.WebApiClient
- 创建一个名为 RestaurantsController 的控制器,并粘贴此类
public class RestaurantsController : Controller
{
private WebApiClientOptions options =
new WebApiClientOptions("https://:60214/api", "restaurant");
public async Task<ActionResult> Index()
{
List<Restaurant> list = null;
using(WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
list = await client.GetManyAsync();
}
return View(list);
}
public async Task<ActionResult> IndexOldFashioned()
{
List<Restaurant> list = null;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://:60214/api/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync("restaurant");
if (!response.IsSuccessStatusCode)
{
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
}
list = await response.Content.ReadAsAsync<List<Restaurant>>();
return View("Index", list);
}
public async Task<ActionResult> Details(int? id)
{
Restaurant restaurant = null;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
using (WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
restaurant = await client.GetOneAsync(id);
}
if (restaurant == null)
{
return HttpNotFound();
}
return View(restaurant);
}
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Restaurant restaurant)
{
if (ModelState.IsValid)
{
using (WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
await client.CreateAsync(restaurant);
}
return RedirectToAction("Index");
}
return View(restaurant);
}
public async Task<ActionResult> Edit(int? id)
{
Restaurant restaurant = null;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
using (WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
restaurant = await client.GetOneAsync(id);
}
if (restaurant == null)
{
return HttpNotFound();
}
return View(restaurant);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(Restaurant restaurant)
{
if (ModelState.IsValid)
{
using (WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
await client.EditAsync(restaurant);
}
return RedirectToAction("Index");
}
return View(restaurant);
}
public async Task<ActionResult> Delete(int? id)
{
Restaurant restaurant = null;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
using (WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
restaurant = await client.GetOneAsync(id);
if (restaurant == null)
{
return HttpNotFound();
}
}
return View(restaurant);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(Restaurant restaurant)
{
if (restaurant == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
using (WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
restaurant = await client.GetOneAsync(restaurant.Id);
if (restaurant == null)
{
return HttpNotFound();
}
await client.DeleteAsync(restaurant.Id);
}
return RedirectToAction("Index");
}
}
现在,您可以运行 MVC 项目,指向类似于 https://:60232/restaurants/ 的 URL 并查看结果。
正如您在上面的代码中看到的,使用WebApiClient调用RESTful 服务非常简单。您只需创建一个WebApiClientOptions对象,根据需要进行配置
private WebApiClientOptions options =
new WebApiClientOptions("https://:60214/api", "restaurant");
然后开始使用WebApiClient对象来调用您的服务。请查看 Index 操作方法
public async Task<ActionResult> Index()
{
List<Restaurant> list = null;
using(WebApiClient<Restaurant> client = new WebApiClient<Restaurant>(options))
{
list = await client.GetManyAsync();
}
return View(list);
}
如果您一直在使用HttpClient,请查看下一个操作方法……您应该编写类似这样的代码
public async Task<ActionResult> IndexOldFashioned()
{
List<Restaurant> list = null;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://:60214/api/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync("restaurant");
if (!response.IsSuccessStatusCode)
{
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
}
list = await response.Content.ReadAsAsync<List<Restaurant>>();
return View("Index", list);
}
现在,如果您比较这两个不同的操作方法,您可能会发现传统方法(使用HttpClient)比使用WebApiClient的方法更难阅读和维护。当您添加更多配置(如身份验证)时,代码会变得更加复杂。
其他特性
WebApiClient 库还有许多其他功能,我们将在后续教程中介绍。
- 身份验证
- Cookie
- 继承
- 异常处理
- 线程
- 超时