ASP.NET API接口使用HttpClient进行测试和验证,以保证我们的接口的可用性。
参考Github开源项目:https://github.com/MikeWasson/HttpClientSample
编写一个Model实例
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; }
}
}
编写API Controller接口
using ProductApi.Models;
using System;
using System.Collections.Concurrent;
using System.Net;
using System.Web.Http;
using System.Web.Http.Results;
namespace ProductApi.Controllers
{
[RoutePrefix("api/products")]
public class ProductsController : ApiController
{
private static ConcurrentDictionary<string, Product> _products = new ConcurrentDictionary<string, Product>();
[Route("{id}", Name = "GetById")]
public IHttpActionResult Get(string id)
{
Product product = null;
if (_products.TryGetValue(id, out product))
{
return Ok(product);
}
else
{
return NotFound();
}
}
[HttpPost]
[Route("")]
public IHttpActionResult Post(Product product)
{
if (product == null)
{
return BadRequest("Product cannot be null");
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
product.Id = Guid.NewGuid().ToString();
_products[product.Id] = product;
return CreatedAtRoute("GetById", new { id = product.Id }, product);
}
[HttpPut]
[Route("{id}")]
public IHttpActionResult Put(string id, Product product)
{
if (product == null)
{
return BadRequest("Product cannot be null");
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (product.Id != id)
{
return BadRequest("product.id does not match id parameter");
}
if (!_products.Keys.Contains(id))
{
return NotFound();
}
_products[id] = product;
return new StatusCodeResult(HttpStatusCode.NoContent, this);
}
[HttpDelete]
[Route("{id}")]
public IHttpActionResult Delete(string id)
{
Product product = null;
_products.TryRemove(id, out product);
return new StatusCodeResult(HttpStatusCode.NoContent, this);
}
}
}
编写HttpClient测试
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace HttpClientSample
{
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<Uri> 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<Product> GetProductAsync(string path)
{
Product product = null;
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product;
}
static async Task<Product> 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<Product>();
return product;
}
static async Task<HttpStatusCode> DeleteProductAsync(string id)
{
HttpResponseMessage response = await client.DeleteAsync($"api/products/{id}");
return response.StatusCode;
}
static void Main()
{
RunAsync().Wait();
}
static async Task RunAsync()
{
client.BaseAddress = new Uri("http://localhost:55268/");
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();
}
}
}
封装一个简单的HttpClientUtil工具类
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml.Serialization;
namespace RTVSApi.Utils
{
/// <summary>
/// HttpClient工具类
/// </summary>
public class HttpClientUtil
{
/// <summary>
/// post请求
/// </summary>
/// <param name="url"></param>
/// <param name="postData">post数据</param>
/// <returns></returns>
public static string PostResponse(string url, string postData)
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpContent httpContent = new StringContent(postData);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
return result;
}
return null;
}
/// <summary>
/// 发起post请求
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url">url</param>
/// <param name="postData">post数据</param>
/// <returns></returns>
public static string PostResponse<T>(string url, T postData) where T : class, new()
{
string result = "0";
var format = new IsoDateTimeConverter();
format.DateTimeFormat = "yyyyMMddHHmmssSSS";
var dataJson = JsonConvert.SerializeObject(postData, Newtonsoft.Json.Formatting.Indented, format);
var content = new StringContent(dataJson, Encoding.UTF8, "application/json");
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = httpClient.PostAsync(url, content).Result;
if (response.IsSuccessStatusCode)
{
//Task<string> t = response.Content.ReadAsStringAsync();
//string s = t.Result;
//T ss = JsonConvert.DeserializeObject<T>(s);
result = "1";
}
return result;
}
/// <summary>
/// 发起post请求主键返回
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url">url</param>
/// <param name="postData">post数据</param>
/// <returns>主键</returns>
public static string PostResponseKey<T>(string url, T postData) where T : class, new()
{
string ret = "0";
var format = new IsoDateTimeConverter();
format.DateTimeFormat = "yyyyMMddHHmmssSSS";
var dataJson = JsonConvert.SerializeObject(postData, Newtonsoft.Json.Formatting.Indented, format);
var content = new StringContent(dataJson, Encoding.UTF8, "application/json");
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = httpClient.PostAsync(url, content).Result;
if (response.IsSuccessStatusCode)
{
Task<string> t = response.Content.ReadAsStringAsync();
ret = t.Result;
}
return ret;
}
/// <summary>
/// 发起post请求
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url">url</param>
/// <param name="postData">post数据</param>
/// <returns></returns>
public static T PostResponse<T>(string url, string postData) where T : class, new()
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpContent httpContent = new StringContent(postData);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
T result = default(T);
HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;
if (response.IsSuccessStatusCode)
{
Task<string> t = response.Content.ReadAsStringAsync();
string s = t.Result;
result = JsonConvert.DeserializeObject<T>(s);
}
return result;
}
/// <summary>
/// V3接口全部为Xml形式,故有此方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="xmlString"></param>
/// <returns></returns>
public static T PostXmlResponse<T>(string url, string xmlString) where T : class, new()
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpContent httpContent = new StringContent(xmlString);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
T result = default(T);
HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;
if (response.IsSuccessStatusCode)
{
Task<string> t = response.Content.ReadAsStringAsync();
string s = t.Result;
result = XmlDeserialize<T>(s);
}
return result;
}
/// <summary>
/// 反序列化Xml
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xmlString"></param>
/// <returns></returns>
public static T XmlDeserialize<T>(string xmlString) where T : class, new()
{
try
{
XmlSerializer ser = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(xmlString))
{
return (T)ser.Deserialize(reader);
}
}
catch (Exception ex)
{
throw new Exception("XmlDeserialize发生异常:xmlString:" + xmlString + "异常信息:" + ex.Message);
}
}
/// <summary>
/// get请求
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string GetResponse(string url)
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = httpClient.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
return result;
}
return null;
}
/// <summary>
/// get请求
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <returns></returns>
public static T GetResponse<T>(string url) where T : class, new()
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromMilliseconds(3000);
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = httpClient.GetAsync(url).Result;
T result = default(T);
if (response.IsSuccessStatusCode)
{
Task<string> t = response.Content.ReadAsStringAsync();
string s = t.Result;
result = JsonConvert.DeserializeObject<T>(s);
}
return result;
}
/// <summary>
/// Get请求返回List集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <returns>List<T></returns>
public static List<T> GetResponseList<T>(string url) where T : class, new()
{
if (url.StartsWith("https"))
{
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
}
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = httpClient.GetAsync(url).Result;
List<T> result = default(List<T>);
if (response.IsSuccessStatusCode)
{
Task<string> t = response.Content.ReadAsStringAsync();
string s = t.Result;
if (s != null && !s.StartsWith("["))
{
s = "[" + s + "]";
}
result = JsonConvert.DeserializeObject<List<T>>(s);
}
return result;
}
/// <summary>
/// Delete请求
/// </summary>
/// <param name="url"></param>
/// <param name="postData">post数据</param>
/// <returns></returns>
public static string DeleteResponse(string url)
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = httpClient.DeleteAsync(url).Result;
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
return "1";
}
return "0";
}
/// <summary>
/// 发起put请求 List格式数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url">url</param>
/// <param name="postData">put数据</param>
/// <returns></returns>
public static string PutListDataResponse<T>(string url, List<T> postData) where T : class, new()
{
string result = "0";
if (postData != null && postData.Count > 0)
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
var format = new IsoDateTimeConverter();
format.DateTimeFormat = "yyyyMMddHHmmssSSS";
var dataJson = JsonConvert.SerializeObject(postData[0], Newtonsoft.Json.Formatting.Indented, format);
var content = new StringContent(dataJson, Encoding.UTF8, "application/json");
HttpResponseMessage response = httpClient.PutAsync(url, content).Result;
if (response.IsSuccessStatusCode)
{
result = "1";
}
}
else
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = httpClient.PutAsync(url, null).Result;
if (response.IsSuccessStatusCode)
{
result = "1";
}
}
return result;
}
/// <summary>
/// 发起put请求 (修改时候用)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url">url</param>
/// <param name="postData">put数据</param>
/// <returns></returns>
public static string PutDataResponse<T>(string url, T postData) where T : class, new()
{
string result = "0";
if (postData != null)
{
if (url.StartsWith("https"))
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
HttpClient httpClient = new HttpClient();
var format = new IsoDateTimeConverter();
format.DateTimeFormat = "yyyyMMddHHmmssSSS";
var dataJson = JsonConvert.SerializeObject(postData, Newtonsoft.Json.Formatting.Indented, format);
var content = new StringContent(dataJson, Encoding.UTF8, "application/json");
HttpResponseMessage response = httpClient.PutAsync(url, content).Result;
if (response.IsSuccessStatusCode)
{
result = "1";
}
}
else
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = httpClient.PutAsync(url, null).Result;
if (response.IsSuccessStatusCode)
{
result = "1";
}
}
return result;
}
}
}