本篇体验使用HttpClient对ASP.NET Web API服务实现增删改查。
创建ASP.NET Web API项目
新建项目,选择"ASP.NET MVC 4 Web应用程序"。
选择"Web API"。
在Models文件夹下创建Product类。
public class Product | |
{ | |
public int Id { get; set; } | |
public string Name { get; set; } | |
public string Category { get; set; } | |
public decimal Price { get; set; } | |
} |
在Models文件夹下创建IProductRepository接口。
public interface IProductRepository | |
{ | |
IEnumerable<Product> GetAll(); | |
Product Get(int id); | |
Product Add(Product item); | |
void Remove(int id); | |
bool Update(Product item); | |
} |
在Models文件夹下创建ProductRepository类,实现IProductRepository接口。
public class ProductRepository : IProductRepository | |
{ | |
private List<Product> products = new List<Product>(); | |
private int _nextId = 1; | |
public ProductRepository() | |
{ | |
Add(new Product() {Name = "product1", Category = "sports", Price = 88M}); | |
Add(new Product() { Name = "product2", Category = "sports", Price = 98M }); | |
Add(new Product() { Name = "product3", Category = "toys", Price = 58M }); | |
} | |
public IEnumerable<Product> GetAll() | |
{ | |
return products; | |
} | |
public Product Get(int id) | |
{ | |
return products.Find(p => p.Id == id); | |
} | |
public Product Add(Product item) | |
{ | |
if (item == null) | |
{ | |
throw new ArgumentNullException("item"); | |
} | |
item.Id = _nextId++; | |
products.Add(item); | |
return item; | |
} | |
public bool Update(Product item) | |
{ | |
if (item == null) | |
{ | |
throw new ArgumentNullException("item"); | |
} | |
int index = products.FindIndex(p => p.Id == item.Id); | |
if (index == -1) | |
{ | |
return false; | |
} | |
products.RemoveAt(index); | |
products.Add(item); | |
return true; | |
} | |
public void Remove(int id) | |
{ | |
products.RemoveAll(p => p.Id == id); | |
} | |
} |
在Controllers文件夹下创建空的ProductController。
public class ProductController : ApiController | |
{ | |
static readonly IProductRepository repository = new ProductRepository(); | |
//获取所有 | |
public IEnumerable<Product> GetAllProducts() | |
{ | |
return repository.GetAll(); | |
} | |
//根据id获取 | |
public Product GetProduct(int id) | |
{ | |
Product item = repository.Get(id); | |
if (item == null) | |
{ | |
throw new HttpResponseException(HttpStatusCode.NotFound); | |
} | |
return item; | |
} | |
//根据类别查找所有产品 | |
public IEnumerable<Product> GetProductsByCategory(string category) | |
{ | |
return | |
repository.GetAll().Where(p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase)); | |
} | |
//创建产品 | |
public HttpResponseMessage PostProduct(Product item) | |
{ | |
item = repository.Add(item); | |
var response = Request.CreateResponse(HttpStatusCode.Created, item); | |
string uri = Url.Link("DefaultApi", new {id = item.Id}); | |
response.Headers.Location = new Uri(uri); | |
return response; | |
} | |
//更新产品 | |
public void PutProduct(int id, Product product) | |
{ | |
product.Id = id; | |
if (!repository.Update(product)) | |
{ | |
throw new HttpResponseException(HttpStatusCode.NotFound); | |
} | |
} | |
//删除产品 | |
public void DeleteProduct(int id) | |
{ | |
Product item = repository.Get(id); | |
if (item == null) | |
{ | |
throw new HttpResponseException(HttpStatusCode.NotFound); | |
} | |
repository.Remove(id); | |
} | |
} |
在浏览器中输入:
http://localhost:1310/api/Product 获取到所有产品
http://localhost:1310/api/Product/1 获取编号为1的产品
使用HttpClient查询某个产品
在同一个解决方案下创建一个控制台程序。
依次点击"工具","库程序包管理器","程序包管理器控制台",输入如下:
Install-Package Microsoft.AspNet.WebApi.Client
在控制台程序下添加Product类,与ASP.NET Web API中的对应。
public class Product | |
{ | |
public string Name { get; set; } | |
public double Price { get; set; } | |
public string Category { get; set; } | |
} |
编写如下:
static void Main(string[] args) | |
{ | |
RunAsync().Wait(); | |
Console.ReadKey(); | |
} | |
static async Task RunAsync() | |
{ | |
using (var client = new HttpClient()) | |
{ | |
//设置 | |
client.BaseAddress = new Uri("http://localhost:1310/"); | |
client.DefaultRequestHeaders.Accept.Clear(); | |
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | |
//异步获取数据 | |
HttpResponseMessage response = await client.GetAsync("/api/Product/1"); | |
if (response.IsSuccessStatusCode) | |
{ | |
Product product = await response.Content.ReadAsAsync<Product>(); | |
Console.WriteLine("{0}\t{1}元\t{2}",product.Name, product.Price, product.Category); | |
} | |
} | |
} |
把控制台项目设置为启动项目。
HttpResponseMessage的IsSuccessStatusCode只能返回true或false,如果想让响应抛出异常,需要使用EnsureSuccessStatusCode方法。
try | |
{ | |
HttpResponseMessage response = await client.GetAsync("/api/Product/1"); | |
response.EnsureSuccessStatusCode();//此方法确保响应失败抛出异常 | |
} | |
catch(HttpRequestException ex) | |
{ | |
//处理异常 | |
} |
另外,ReadAsAsync方法,默认接收MediaTypeFormatter类型的参数,支持 JSON, XML, 和Form-url-encoded格式,如果想自定义MediaTypeFormatter格式,参照如下:
var formatters = new List<MediaTypeFormatter>() { | |
new MyCustomFormatter(), | |
new JsonMediaTypeFormatter(), | |
new XmlMediaTypeFormatter() | |
}; | |
resp.Content.ReadAsAsync<IEnumerable<Product>>(formatters); |
使用HttpClient查询所有产品
static void Main(string[] args) | |
{ | |
RunAsync().Wait(); | |
Console.ReadKey(); | |
} | |
static async Task RunAsync() | |
{ | |
using (var client = new HttpClient()) | |
{ | |
//设置 | |
client.BaseAddress = new Uri("http://localhost:1310/"); | |
client.DefaultRequestHeaders.Accept.Clear(); | |
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | |
//异步获取数据 | |
HttpResponseMessage response = await client.GetAsync("/api/Product"); | |
if (response.IsSuccessStatusCode) | |
{ | |
IEnumerable<Product> products = await response.Content.ReadAsAsync<IEnumerable<Product>>(); | |
foreach (var item in products) | |
{ | |
Console.WriteLine("{0}\t{1}元\t{2}", item.Name, item.Price, item.Category); | |
} | |
} | |
} | |
} |
使用HttpClient添加
static void Main(string[] args) | |
{ | |
RunAsync().Wait(); | |
Console.ReadKey(); | |
} | |
static async Task RunAsync() | |
{ | |
using (var client = new HttpClient()) | |
{ | |
//设置 | |
client.BaseAddress = new Uri("http://localhost:1310/"); | |
client.DefaultRequestHeaders.Accept.Clear(); | |
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | |
//添加 | |
var myProduct = new Product() { Name = "myproduct", Price = 88, Category = "other" }; | |
HttpResponseMessage response = await client.PostAsJsonAsync("api/Product", myProduct); | |
//异步获取数据 | |
response = await client.GetAsync("/api/Product"); | |
if (response.IsSuccessStatusCode) | |
{ | |
IEnumerable<Product> products = await response.Content.ReadAsAsync<IEnumerable<Product>>(); | |
foreach (var item in products) | |
{ | |
Console.WriteLine("{0}\t{1}元\t{2}", item.Name, item.Price, item.Category); | |
} | |
} | |
} | |
} |
使用HttpClient修改
static void Main(string[] args) | |
{ | |
RunAsync().Wait(); | |
Console.ReadKey(); | |
} | |
static async Task RunAsync() | |
{ | |
using (var client = new HttpClient()) | |
{ | |
//设置 | |
client.BaseAddress = new Uri("http://localhost:1310/"); | |
client.DefaultRequestHeaders.Accept.Clear(); | |
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | |
//添加 HTTP POST | |
var myProduct = new Product() { Name = "myproduct", Price = 100, Category = "other" }; | |
HttpResponseMessage response = await client.PostAsJsonAsync("api/product", myProduct); | |
if (response.IsSuccessStatusCode) | |
{ | |
Uri pUrl = response.Headers.Location; | |
//修改 HTTP PUT | |
myProduct.Price = 80; // Update price | |
response = await client.PutAsJsonAsync(pUrl, myProduct); | |
} | |
//异步获取数据 | |
response = await client.GetAsync("/api/Product"); | |
if (response.IsSuccessStatusCode) | |
{ | |
IEnumerable<Product> products = await response.Content.ReadAsAsync<IEnumerable<Product>>(); | |
foreach (var item in products) | |
{ | |
Console.WriteLine("{0}\t{1}元\t{2}", item.Name, item.Price, item.Category); | |
} | |
} | |
} | |
} |
使用HttpClient删除
static void Main(string[] args) | |
{ | |
RunAsync().Wait(); | |
Console.ReadKey(); | |
} | |
static async Task RunAsync() | |
{ | |
using (var client = new HttpClient()) | |
{ | |
//设置 | |
client.BaseAddress = new Uri("http://localhost:1310/"); | |
client.DefaultRequestHeaders.Accept.Clear(); | |
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | |
//添加 HTTP POST | |
var myProduct = new Product() { Name = "myproduct", Price = 100, Category = "other" }; | |
HttpResponseMessage response = await client.PostAsJsonAsync("api/product", myProduct); | |
if (response.IsSuccessStatusCode) | |
{ | |
Uri pUrl = response.Headers.Location; | |
//修改 HTTP PUT | |
myProduct.Price = 80; // Update price | |
response = await client.PutAsJsonAsync(pUrl, myProduct); | |
//删除 HTTP DELETE | |
response = await client.DeleteAsync(pUrl); | |
} | |
//异步获取数据 | |
response = await client.GetAsync("/api/Product"); | |
if (response.IsSuccessStatusCode) | |
{ | |
IEnumerable<Product> products = await response.Content.ReadAsAsync<IEnumerable<Product>>(); | |
foreach (var item in products) | |
{ | |
Console.WriteLine("{0}\t{1}元\t{2}", item.Name, item.Price, item.Category); | |
} | |
} | |
} | |
} |