解析C#網絡編程中的Http請求
本篇分享簡單介紹C#中的Http請求,前幾天幫朋友的項目封裝ApiHelper,我粗糙的結果就如下,想想我真的是差的太遠了。還有一位架構師也在封裝這個Helper , 所以最后的結果當然是使用大牛的封裝,這篇分享后,準備學習下他的封裝,配置,錯誤處理機制等思想。不過這次也使我對C#網絡編程了解的更多,算是一次學習經歷吧。真心喜歡和老司機合作,下一階段將會持續(xù)跟這位朋友學習項目底層的封裝,和他謙虛的態(tài)度,有這樣的機會也是幸運的。
你可以將其封裝成自己的HttpHelper,經朋友建議,統(tǒng)一Http請求的入參和出參。在HttpClient方面也參考了dudu的關于httpclient預熱的文章。C#中HttpClient使用注意:預熱與長連接。
為了做到統(tǒng)一入參和出參,定義了Req<T>泛型類和Resp<T>泛型類。你可以根據自己的需要進行拓展。
public class Req<T>
{
/// <summary>
/// 傳入數據
/// </summary>
public T Input { get; set; }
/// <summary>
/// 請求地址
/// </summary>
public string Url { get; set; }
}public class Resp<T>
{
/// <summary>
/// 錯誤消息
/// </summary>
public string ErrorMsg { get; set; }
/// <summary>
/// 狀態(tài)碼
/// </summary>
public int StatusCode { get; set; }
/// <summary>
/// 返回數據
/// </summary>
public T RespData { get; set; }
}雖然保持了httpClient對象復用,但需要注意的是,在設置了httpClient,并且發(fā)生了一次請求之后,不能再對其屬性進行重新設置。這也正是我又定義了一個fileClient的理由。
#region HttpClient版本
private static readonly string _baseAddress = ConfigurationManager.AppSettings["api-server"];//配置BaseUrl eg.http://localhost:1234
private static readonly HttpClient _httpClient;
private static readonly HttpClient _fileClient;
static ApiHelper()
{
#region 初始化和預熱 httpClient
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri(_baseAddress);
_httpClient.Timeout = TimeSpan.FromMilliseconds(2000);
_httpClient.DefaultRequestHeaders.Add("Accept", "application/json");//application/xml 想Accept的數據格式
_httpClient.SendAsync(new HttpRequestMessage
{
Method = new HttpMethod("HEAD"),
RequestUri = new Uri(_baseAddress + "/api/test/HttpClientHot")
})
.Result.EnsureSuccessStatusCode();
#endregion
#region 初始化和預熱 fileClient
_fileClient = new HttpClient();
_fileClient.BaseAddress = new Uri(_baseAddress + "/api/test/HttpClientHot");
_fileClient.MaxResponseContentBufferSize = 256000;
#endregion
}
/// <summary>
/// http Get請求
/// </summary>
/// <typeparam name="T">入參類型</typeparam>
/// <typeparam name="TResult">出參類型</typeparam>
/// <param name="req">入參對象</param>
/// <returns></returns>
public static async Task<Resp<TResult>> GetAsync<T, TResult>(Req<T> req)
{
try
var result =await _httpClient.GetAsync(req.Url).Result.Content.ReadAsStringAsync();
return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
}
catch(Exception ex)
}
return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>("") };
}
/// <summary>
/// http Post請求
/// </summary>
/// <typeparam name="T">入參類型</typeparam>
/// <typeparam name="TResult">出參類型</typeparam>
/// <param name="req">入參對象</param>
/// <returns></returns>
public static async Task<Resp<TResult>> PostAsJsonAsync<T, TResult>(Req<T> req)
var result = await _httpClient.PostAsJsonAsync(req.Url, req.Input).Result.Content.ReadAsStringAsync();
return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
}
/// 上傳文件
/// <typeparam name="T"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="req"></param>
/// <param name="filePath"></param>
public static async Task<Resp<TResult>> SendFile<T, TResult>(Req<T> req, string filePath)//D:\\white.jpg
//_fileClient.DefaultRequestHeaders.Add("user-agent", "User-Agent Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; MALNJS; rv:11.0) like Gecko");//設置請求頭
// 讀文件流
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
HttpContent fileContent = new StreamContent(fs);//為文件流提供的HTTP容器
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");//設置媒體類型
MultipartFormDataContent mulContent = new MultipartFormDataContent("----");//創(chuàng)建用于可傳遞文件的容器
string fileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
mulContent.Add(fileContent, "form", fileName);//第二個參數是表單名,第三個是文件名。
HttpResponseMessage response = await _fileClient.PostAsync(req.Url, mulContent);
response.EnsureSuccessStatusCode();
string result = await response.Content.ReadAsStringAsync();
return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
}
/// 下載
/// <param name="url"></param>
/// <returns></returns>
public static async Task<Resp<byte[]>> HttpDownloadData<T>(Req<T> req)
var byteres = await _fileClient.GetByteArrayAsync(req.Url);
return new Resp<byte[]>() { Data = byteres };
#endregion
}另外分享下HttpWebRequest來實現的請求。HttpWebRequest需要你自行設置很多內容,當然這也證明其內容豐富。下面代碼包含了post,get,以及上傳。
/// <summary>
/// Post Http請求
/// </summary>
/// <param name="url">請求地址</param>
/// <param name="postData">傳輸數據</param>
/// <param name="timeout">超時時間</param>
/// <param name="contentType">媒體格式</param>
/// <param name="encode">編碼</param>
/// <returns>泛型集合</returns>
public static List<T> PostAndRespList<T>(string url, string postData, int timeout = 5000, string contentType = "application/json;", string encode = "UTF-8")
{
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
{
// webRequest.Headers.Add("Authorization", "Bearer " + "SportApiAuthData");
HttpWebResponse webResponse = null;
Stream responseStream = null;
Stream requestStream = null;
StreamReader streamReader = null;
try
{
string respstr = GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
return JsonHelper.JsonDeserialize<List<T>>(respstr);
}
catch (Exception ex)
{
}
finally
{
if (responseStream != null) responseStream.Dispose();
if (webResponse != null) webResponse.Dispose();
if (requestStream != null) requestStream.Dispose();
if (streamReader != null) streamReader.Dispose();
}
}
return null;
}
/// <summary>
/// Post Http請求
/// </summary>
/// <param name="url">請求地址</param>
/// <param name="postData">傳輸數據</param>
/// <param name="timeout">超時時間</param>
/// <param name="contentType">媒體格式</param>
/// <param name="encode">編碼</param>
/// <returns>泛型集合</returns>
public static T PostAndRespSignle<T>(string url, int timeout = 5000, string postData = "", string contentType = "application/json;", string encode = "UTF-8")
{
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
{
// webRequest.Headers.Add("Authorization", "Bearer " + "SportApiAuthData");
HttpWebResponse webResponse = null;
Stream responseStream = null;
Stream requestStream = null;
StreamReader streamReader = null;
try
{
string respstr = GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
return JsonHelper.JsonDeserialize<T>(respstr);
}
catch (Exception ex)
{
}
finally
{
if (responseStream != null) responseStream.Dispose();
if (webResponse != null) webResponse.Dispose();
if (requestStream != null) requestStream.Dispose();
if (streamReader != null) streamReader.Dispose();
}
}
return default(T);
}
/// <summary>
/// Post Http請求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="timeout"></param>
/// <param name="contentType"></param>
/// <param name="encode"></param>
/// <returns>響應流字符串</returns>
public static string PostAndRespStr(string url, int timeout = 5000, string postData = "", string contentType = "application/json;", string encode = "UTF-8")
{
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
{
HttpWebResponse webResponse = null;
Stream responseStream = null;
Stream requestStream = null;
StreamReader streamReader = null;
try
{
return GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
}
catch (Exception ex)
{
}
finally
{
if (responseStream != null) responseStream.Dispose();
if (webResponse != null) webResponse.Dispose();
if (requestStream != null) requestStream.Dispose();
if (streamReader != null) streamReader.Dispose();
}
}
return null;
}
private static string GetStreamReader(string url, Stream responseStream, Stream requestStream, StreamReader streamReader, WebResponse webResponse, int timeout, string encode, string postData, string contentType)
{
byte[] data = Encoding.GetEncoding(encode).GetBytes(postData);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
SetAuth(webRequest);
webRequest.Method = "POST";
webRequest.ContentType = contentType + ";" + encode;
webRequest.ContentLength = data.Length;
webRequest.Timeout = timeout;
requestStream = webRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
webResponse = (HttpWebResponse)webRequest.GetResponse();
responseStream = webResponse.GetResponseStream();
if (responseStream == null) { return ""; }
streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode));
return streamReader.ReadToEnd();
}
/// <summary>
/// Post文件流給指定Url
/// </summary>
/// <param name="url">url</param>
/// <param name="filePath">文件路徑</param>
/// <returns>響應流字符串</returns>
public static string PostFile(string url, string filePath, string contentType = "application/octet-stream", string encode = "UTF-8")
{
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && !string.IsNullOrEmpty(filePath))
{
Stream requestStream = null;
Stream responseStream = null;
StreamReader streamReader = null;
FileStream fileStream = null;
try
{
// 設置參數
HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
SetAuth(webRequest);
webRequest.AllowAutoRedirect = true;
webRequest.Method = "POST";
string boundary = DateTime.Now.Ticks.ToString("X"); // 隨機分隔線
webRequest.ContentType = "multipart/form-data;charset=" + encode + ";boundary=" + boundary;
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");//消息開始
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");//消息結尾
var fileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
//請求頭部信息
string postHeader = string.Format("Content-Disposition:form-data;name=\"media\";filename=\"{0}\"\r\nContent-Type:{1}\r\n\r\n", fileName, contentType);
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] fileByteArr = new byte[fileStream.Length];
fileStream.Read(fileByteArr, 0, fileByteArr.Length);
fileStream.Close();
requestStream = webRequest.GetRequestStream();
requestStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
requestStream.Write(fileByteArr, 0, fileByteArr.Length);
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
requestStream.Close();
responseStream = webRequest.GetResponse().GetResponseStream();//發(fā)送請求,得到響應流
if (responseStream == null) return string.Empty;
streamReader = new StreamReader(responseStream, Encoding.UTF8);
return streamReader.ReadToEnd();
}
catch (Exception ex)
{
}
finally
{
}
}
return null;
}
/// <summary>
/// Get http請求
/// </summary>
/// <param name="url">請求地址</param>
/// <param name="timeout">超時時間</param>
/// <param name="encode">編碼</param>
/// <returns>返回單個實體</returns>
public static T GetSingle<T>(string url, int timeout = 5000, string encode = "UTF-8")
{
//HttpWebRequest對象
//HttpClient->dudu 調用預熱處理
//Stream—>Model
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode))
{
Stream responseStream = null;
StreamReader streamReader = null;
WebResponse webResponse = null;
try
{
string respStr = GetRespStr(url, responseStream, streamReader, webResponse, timeout, encode);
return JsonHelper.JsonDeserialize<T>(respStr);
}
catch (Exception ex)
{
}
finally
{
if (responseStream != null) responseStream.Dispose();
if (streamReader != null) streamReader.Dispose();
if (webResponse != null) webResponse.Dispose();
}
}
return default(T);
}
/// <summary>
/// Get http請求
/// </summary>
/// <param name="url"></param>
/// <param name="timeout"></param>
/// <param name="encode"></param>
/// <returns>響應流字符串</returns>
public static string GetResponseString(string url, int timeout = 5000, string encode = "UTF-8")
{
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode))
{
Stream responseStream = null;
StreamReader streamReader = null;
WebResponse webResponse = null;
try
{
return GetRespStr(url, responseStream, streamReader, webResponse, timeout, encode);
}
catch (Exception ex)
{
}
finally
{
if (responseStream != null) responseStream.Dispose();
if (streamReader != null) streamReader.Dispose();
if (webResponse != null) webResponse.Dispose();
}
}
return null;
}
private static string GetRespStr(string url, Stream responseStream, StreamReader streamReader, WebResponse webResponse, int timeout, string encode)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "GET";
webRequest.Timeout = timeout;
webResponse = webRequest.GetResponse();
responseStream = webResponse.GetResponseStream();
if (responseStream == null) { return ""; }
streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode));
return streamReader.ReadToEnd();
}到此這篇關于C#網絡編程中的Http請求的文章就介紹到這了,更多相關C#網絡編程Http請求內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

