文章目录
4.HttpClient、MultipartFormDataContent扩展类
一、简介
在HttpClient原生类的基础上,封装GET、POST、PUT、DELETE请求方法,简化客户端程序对RESTful API接口的调用。
二、源码
1.HttpClientHelper帮助类
public class HttpClientHelper
{
#region GET 请求
/// <summary>
/// GET 请求
/// </summary>
/// <param name="url">地址</param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<string> GetStringAsync(string url, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
//Uri urlObj = new Uri(url);
HttpResponseMessage response = await httpClient.GetAsync(url);
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// GET 请求,请求参数放在paramDic里,拼接成完整URL
/// </summary>
/// <param name="url"></param>
/// <param name="paramDic"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<string> GetStringAsync(string url, Dictionary<string, string> paramDic, string token = null)
{
try
{
string _url = url + "?" + paramDic.ToQueryString();
string content = await GetStringAsync(_url, token);
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// GET 请求
/// </summary>
/// <param name="url"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<byte[]> GetByteArrayAsync(string url, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
byte[] content = await httpClient.GetByteArrayAsync(url);
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// GET 请求,请求参数放在paramDic里,拼接成完整URL
/// </summary>
/// <param name="url"></param>
/// <param name="paramDic"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<byte[]> GetByteArrayAsync(string url, Dictionary<string, string> paramDic, string token = null)
{
try
{
string _url = url + "?" + paramDic.ToQueryString();
byte[] content = await GetByteArrayAsync(_url, token);
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// GET 请求
/// </summary>
/// <param name="url"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<T> GetObjectAsync<T>(string url, string token = null)
{
try
{
string content = await GetStringAsync(url, token);
return content.ToObject<T>();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
}
/// <summary>
/// GET 请求,请求参数放在paramDic里,拼接成完整URL
/// </summary>
/// <param name="url"></param>
/// <param name="paramDic"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<T> GetObjectAsync<T>(string url, Dictionary<string, string> paramDic, string token = null)
{
try
{
string _url = url + "?" + paramDic.ToQueryString();
T content = await GetObjectAsync<T>(_url, token);
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
}
#endregion
#region POST 请求
/// <summary>
/// 利用Post提交json字符串或文本数据
/// </summary>
/// <param name="url">Web API地址</param>
/// <param name="data">RequestPayload</param>
/// <param name="contentType">消息类型</param>
/// <param name="token">token</param>
/// <returns>返回响应内容[string]</returns>
public async static Task<string> PostStringAsync(string url, string data, ContentTypeEnum contentType = ContentTypeEnum.application_json, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
HttpContent httpContent = new StringContent(data);
httpContent.Headers.ContentType = new MediaTypeHeaderValue(contentType.ToContentTypeString());
HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// 利用Post提交json字符串或文本数据
/// </summary>
/// <param name="url">Web API地址</param>
/// <param name="data">RequestPayload</param>
/// <param name="contentType">消息类型</param>
/// <param name="token">token</param>
/// <returns>返回响应内容[T]</returns>
public async static Task<T> PostStringAsync<T>(string url, string data, ContentTypeEnum contentType = ContentTypeEnum.application_json, string token = null)
{
try
{
string content = await PostStringAsync(url, data, contentType, token);
T result = content.ToObject<T>();
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
}
/// <summary>
/// 利用Post提交表单数据 [FromForm]
/// </summary>
/// <param name="url"></param>
/// <param name="formData"></param>
/// <param name="token">token</param>
/// <returns>返回响应内容[string]</returns>
public async static Task<string> PostFormAsync(string url, List<HttpFormItem> formItems, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
foreach (HttpFormItem formItem in formItems)
{
multipartFormDataContent.Add(formItem);
}
var response = await httpClient.PostAsync(url, multipartFormDataContent);
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// 利用Post提交表单数据 [FromForm]
/// </summary>
/// <param name="url">Web API地址</param>
/// <param name="formItems">表单项列表</param>
/// <param name="token">token</param>
/// <returns>返回响应内容[T]</returns>
public async static Task<T> PostFormAsync<T>(string url, List<HttpFormItem> formItems, string token = null)
{
try
{
string content = await PostFormAsync(url, formItems, token);
T result = content.ToObject<T>();
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
}
#endregion
#region PUT 请求
/// <summary>
/// 利用Put提交json字符串或文本数据
/// </summary>
/// <param name="url">Web API地址</param>
/// <param name="data">RequestPayload</param>
/// <param name="contentType">消息类型</param>
/// <param name="token">token</param>
/// <returns>返回响应内容[string]</returns>
public async static Task<string> PutStringAsync(string url, string data, ContentTypeEnum contentType = ContentTypeEnum.application_json, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
HttpContent httpContent = new StringContent(data);
httpContent.Headers.ContentType = new MediaTypeHeaderValue(contentType.ToContentTypeString());
HttpResponseMessage response = await httpClient.PutAsync(url, httpContent);
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// 利用Post提交json字符串或文本数据
/// </summary>
/// <param name="url">Web API地址</param>
/// <param name="data">RequestPayload</param>
/// <param name="contentType">消息类型</param>
/// <param name="token">token</param>
/// <returns>返回响应内容[T]</returns>
public async static Task<T> PutStringAsync<T>(string url, string data, ContentTypeEnum contentType = ContentTypeEnum.application_json, string token = null)
{
try
{
string content = await PutStringAsync(url, data, contentType, token);
T result = content.ToObject<T>();
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
}
/// <summary>
/// 利用Post提交表单数据 [FromForm]
/// </summary>
/// <param name="url"></param>
/// <param name="formData"></param>
/// <param name="token">token</param>
/// <returns>返回响应内容[string]</returns>
public async static Task<string> PutFormAsync(string url, List<HttpFormItem> formItems, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
foreach (HttpFormItem formItem in formItems)
{
multipartFormDataContent.Add(formItem);
}
var response = await httpClient.PutAsync(url, multipartFormDataContent);
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// 利用Post提交表单数据 [FromForm]
/// </summary>
/// <param name="url">Web API地址</param>
/// <param name="formItems">表单项列表</param>
/// <param name="token">token</param>
/// <returns>返回响应内容[T]</returns>
public async static Task<T> PutFormAsync<T>(string url, List<HttpFormItem> formItems, string token = null)
{
try
{
string content = await PutFormAsync(url, formItems, token);
T result = content.ToObject<T>();
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
}
#endregion
#region DELETE 请求
/// <summary>
/// DELETE 请求
/// </summary>
/// <param name="url">地址</param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<string> DeleteStringAsync(string url, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
//Uri urlObj = new Uri(url);
HttpResponseMessage response = await httpClient.DeleteAsync(url);
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// DELETE 请求,请求参数放在paramDic里,拼接成完整URL
/// </summary>
/// <param name="url"></param>
/// <param name="paramDic"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<string> DeleteStringAsync(string url, Dictionary<string, string> paramDic, string token = null)
{
try
{
string _url = url + "?" + paramDic.ToQueryString();
string content = await DeleteStringAsync(_url, token);
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// DELETE 请求
/// </summary>
/// <param name="url"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<T> DeleteStringAsyncObjectAsync<T>(string url, string token = null)
{
try
{
string content = await DeleteStringAsync(url, token);
return content.ToObject<T>();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return default(T);
}
}
/// <summary>
/// DELETE 请求,请求参数放在paramDic里,拼接成完整URL
/// </summary>
/// <param name="url"></param>
/// <param name="paramDic"></param>
/// <param name="token">token</param>
/// <returns></returns>
public async static Task<T> DeleteStringAsyncObjectAsync<T>(string url, Dictionary<string, string> paramDic, string token = null)
{
string _url = url + "?" + paramDic.ToQueryString();
T content = await DeleteStringAsyncObjectAsync<T>(_url, token);
return content;
}
/// <summary>
/// 利用Delete提交json字符串
/// </summary>
/// <param name="url">Web API地址</param>
/// <param name="data">RequestPayload</param>
/// <param name="token">token</param>
/// <returns>返回响应内容[string]</returns>
public async static Task<string> DeleteStringAsync(string url, string data, string token = null)
{
try
{
HttpClient httpClient = new HttpClient();
httpClient.AddAuthorization(token);
HttpContent httpContent = new StringContent(data);
httpContent.Headers.ContentType = new MediaTypeHeaderValue(ContentTypeEnum.application_json.ToContentTypeString());
HttpRequestMessage httpRequest = new HttpRequestMessage();
httpRequest.Method = HttpMethod.Delete;
httpRequest.RequestUri = new Uri(url);
httpRequest.Content = httpContent;
HttpResponseMessage response = await httpClient.SendAsync(httpRequest);
string content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
#endregion
}
2.ContentType枚举类
public enum ContentTypeEnum
{
text_html,
text_plain,
text_xml,
image_gif,
image_jpeg,
image_png,
application_json,
application_pdf,
application_msword,
application_octet_stream,
application_x_www_form_urlencoded,
application_xhtml_xml,
application_xml,
application_atom_xml,
multipart_form_data
}
public enum HttpContentEnum
{
HttpContent,
StringContent,
JsonContent,
MultipartContent,
MultipartFormDataContent,
ByteArrayContent,
StreamContent,
ReadOnlyMemoryContent
}
public static class EnumExtensions
{
public static string ToContentTypeString(this ContentTypeEnum item)
{
string[] parts = item.ToString().Split('_');
int partsCount = parts.Length;
string contentType = parts[0]+"/"+parts[1];
for (int i = 2; i < partsCount; i++)
{
if(parts[i] == "xml")
{
contentType += "+" + parts[i];
}
else
{
contentType += "-" + parts[i];
}
}
return contentType;
}
}
3.表单Form元素类
/// <summary>
/// HTTP 表单Form元素类
/// </summary>
public class HttpFormItem
{
/// <summary>
/// 构造文本参数,备注:也可以放json字符串(contentType=ContentTypeEnum.application_json)
/// </summary>
/// <param name="name"></param>
/// <param name="content"></param>
/// <param name="contentType"></param>
public HttpFormItem(string name, string content, ContentTypeEnum contentType=ContentTypeEnum.text_plain)
{
this.isFile = false;
this.name = name;
this.content = content;
this.contentType = contentType;
}
/// <summary>
/// 构造文件或二进制参数
/// </summary>
/// <param name="name"></param>
/// <param name="fileName"></param>
/// <param name="fileBytes"></param>
/// <param name="contentType"></param>
public HttpFormItem(string name, string fileName, byte[] fileBytes, ContentTypeEnum contentType = ContentTypeEnum.application_octet_stream)
{
this.isFile = true;
this.name = name;
this.fileName = fileName;
this.fileBytes = fileBytes;
this.contentType = contentType;
}
/// <summary>
/// 参数名,此名字用于与后端匹配
/// </summary>
public string name { get; set; }
/// <summary>
/// 参数值(非文件参数才有此值)
/// </summary>
public string content { get; set; }
/// <summary>
/// 指示是否是文件或二进制数据
/// </summary>
public bool isFile { get; set; }
/// <summary>
/// 文件或二进制(仅文件或二进制参数具备此值)
/// </summary>
public string fileName { get; set; }
/// <summary>
/// 文件或二进制的二进制表达,比特数组(仅文件或二进制参数具备此值)
/// </summary>
public byte[] fileBytes { get; set; }
/// <summary>
/// 参数类型
/// </summary>
public ContentTypeEnum contentType { get; set; }
public HttpContent ToHttpContent()
{
HttpContent httpContent=null;
// 判断是否为文件、二进制等
if (isFile)
{
httpContent= new ByteArrayContent(fileBytes);
httpContent.Headers.ContentType = new MediaTypeHeaderValue(contentType.ToContentTypeString());
}
else
{
httpContent = new StringContent(content);
httpContent.Headers.ContentType = new MediaTypeHeaderValue(contentType.ToContentTypeString());
}
return httpContent;
}
}
4.HttpClient、MultipartFormDataContent扩展类
public static class HttpFormExtension
{
public static void AddAuthorization(this HttpClient httpClient,string token)
{
if (token != null)
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token);
}
public static void Add(this MultipartFormDataContent multipartFormDataContent, HttpFormItem httpParamItem)
{
if (httpParamItem.isFile)
{
multipartFormDataContent.Add(httpParamItem.name, httpParamItem.fileName, httpParamItem.fileBytes, httpParamItem.contentType);
}
else
{
multipartFormDataContent.Add(httpParamItem.name, httpParamItem.content);
}
}
public static void Add(this MultipartFormDataContent multipartFormDataContent, string name, string fileName, byte[] fileBytes, ContentTypeEnum contentType)
{
HttpContent byteContent = new ByteArrayContent(fileBytes);
byteContent.Headers.ContentType = new MediaTypeHeaderValue(contentType.ToContentTypeString());
multipartFormDataContent.Add(byteContent, name, fileName);
}
public static void Add(this MultipartFormDataContent multipartFormDataContent, string name, string content)
{
multipartFormDataContent.Add(new StringContent(content), name);
}
public static string ToQueryString(this Dictionary<string,string> paramDic)
{
string queryString = "";
int index = 0;
foreach(var kv in paramDic)
{
string param = kv.Key + "=" + kv.Value;
if (index == 0)
{
queryString += param;
}
else
{
queryString += "&" + param;
}
index++;
}
return queryString;
}
}
三、使用示例
class Program
{
static async Task Main(string[] args)
{
string token = "";
// GET 方法使用例子
string getUrl = "http://localhost:8083/api/User/GetUserList1";
string getUrlContent = await HttpClientHelper.GetStringAsync(getUrl);
Console.WriteLine(getUrlContent);
// POST 方法使用例子
string postUrl = "http://localhost:8083/api/User/AddUser";
LoginForm loginForm = new LoginForm();
loginForm.account = "0001";
loginForm.password = "0001";
// 提交json数据
string postUrlContent = await HttpClientHelper.PostStringAsync(postUrl, loginForm.ToJson(), ContentTypeEnum.application_json);
Console.WriteLine(postUrlContent);
string postFormUrl = "http://192.168.101.71:5000/Tensorflow/Predict";
FileStream fs = new FileStream("373751.png", FileMode.OpenOrCreate, FileAccess.ReadWrite);
BinaryReader br = new BinaryReader(fs);
byte[] imageByte = br.ReadBytes(Convert.ToInt32(fs.Length));
// 提交表单数据
List<HttpFormItem> formItems = new List<HttpFormItem>();
formItems.Add(new HttpFormItem("account", "0001"));
formItems.Add(new HttpFormItem("password", "0001"));
formItems.Add(new HttpFormItem("file", "373751.png", imageByte, ContentTypeEnum.image_png));
var content2 = await HttpClientHelper.PostFormAsync(postFormUrl, formItems);
Console.WriteLine(content2);
// PUT 方法使用例子
string putUrl = "http://localhost:8083/api/Login/LoginWithoutCode";
var putConten = await HttpClientHelper.PutStringAsync<ValidateMessage>(putUrl, loginForm.ToJson());
token = putConten.token;
Console.WriteLine(putConten.token);
// DELETE 方法使用例子
string deleteUrl = "http://localhost:8083/api/User/DeleteUser";
var deleteConten = await HttpClientHelper.DeleteStringAsync(deleteUrl,loginForm.ToJson(),token);
Console.WriteLine(deleteConten);
Console.ReadLine();
}
}