<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本篇分享簡單介紹C#中的Http請求,前幾天幫朋友的專案封裝ApiHelper,我粗糙的結果就如下,想想我真的是差的太遠了。還有一位架構師也在封裝這個Helper , 所以最後的結果當然是使用大牛的封裝,這篇分享後,準備學習下他的封裝,設定,錯誤處理機制等思想。不過這次也使我對C#網路程式設計瞭解的更多,算是一次學習經歷吧。真心喜歡和老司機合作,下一階段將會持續跟這位朋友學習專案底層的封裝,和他謙虛的態度,有這樣的機會也是幸運的。
你可以將其封裝成自己的HttpHelper,經朋友建議,統一Http請求的入參和出參。在HttpClient方面也參考了dudu的關於httpclient預熱的文章。C#中HttpClient使用注意:預熱與長連線。
為了做到統一入參和出參,定義了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> /// 狀態碼 /// </summary> public int StatusCode { get; set; } /// <summary> /// 返回資料 /// </summary> public T RespData { get; set; } }
雖然保持了httpClient物件複用,但需要注意的是,在設定了httpClient,並且發生了一次請求之後,不能再對其屬性進行重新設定。這也正是我又定義了一個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("----");//建立用於可傳遞檔案的容器 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("rn--" + boundary + "rn");//訊息開始 byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("rn--" + boundary + "--rn");//訊息結尾 var fileName = filePath.Substring(filePath.LastIndexOf("/") + 1); //請求頭部資訊 string postHeader = string.Format("Content-Disposition:form-data;name="media";filename="{0}"rnContent-Type:{1}rnrn", 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();//傳送請求,得到響應流 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請求內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45