本篇體驗使用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){returnrepository.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 POSTvar 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 PUTmyProduct.Price = 80; // Update priceresponse = 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 POSTvar 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 PUTmyProduct.Price = 80; // Update priceresponse = await client.PutAsJsonAsync(pUrl, myProduct);//刪除 HTTP DELETEresponse = 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);}}}}

完。