C#網絡編程之Http請求

本片篇分享簡單介紹C#中的Http請求,前幾天幫朋友的項目封裝ApiHelper,我粗糙的結果就以下,想一想我真的是差的太遠了。還有一位架構師也在封裝這個Helper , 因此最後的結果固然是使用大牛的封裝,這篇分享後,準備學習下他的封裝,配置,錯誤處理機制等思想。不過此次也使我對C#網絡編程瞭解的更多,算是一次學習經歷吧。真心喜歡和老司機合做,下一階段將會持續跟這位朋友學習項目底層的封裝,和他謙虛的態度,有這樣的機會也是幸運的。html

 

你能夠將其封裝成本身的HttpHelper,經朋友建議,統一Http請求的入參和出參。在HttpClient方面也參考了dudu的關於httpclient預熱的文章。C#中HttpClient使用注意:預熱與長鏈接。web

爲了作到統一入參和出參,定義了Req<T>泛型類和Resp<T>泛型類。你能夠根據本身的須要進行拓展。編程

 1   public class Req<T>
 2     {
 3         /// <summary>
 4         /// 傳入數據
 5         /// </summary>
 6         public T Input { get; set; }
 7         /// <summary>
 8         /// 請求地址
 9         /// </summary>
10         public string Url { get; set; }
11     }
 1 public class Resp<T>
 2     {
 3         /// <summary>
 4         /// 錯誤消息
 5         /// </summary>
 6         public string ErrorMsg { get; set; }
 7         /// <summary>
 8         /// 狀態碼
 9         /// </summary>
10         public int StatusCode { get; set; }
11         /// <summary>
12         /// 返回數據
13         /// </summary>
14         public T RespData { get; set; }
15     }

雖然保持了httpClient對象複用,但須要注意的是,在設置了httpClient,而且發生了一次請求以後,不能再對其屬性進行從新設置。這也正是我又定義了一個fileClient的理由。json

  1   #region HttpClient版本
  2         private static readonly string _baseAddress = ConfigurationManager.AppSettings["api-server"];//配置BaseUrl eg.http://localhost:1234
  3         private static readonly HttpClient _httpClient;
  4         private static readonly HttpClient _fileClient;
  5 
  6         static ApiHelper()
  7         {
  8             #region 初始化和預熱 httpClient
  9             _httpClient = new HttpClient();
 10             _httpClient.BaseAddress = new Uri(_baseAddress);
 11             _httpClient.Timeout = TimeSpan.FromMilliseconds(2000);
 12             _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");//application/xml  想Accept的數據格式
 13 
 14             _httpClient.SendAsync(new HttpRequestMessage
 15             {
 16                 Method = new HttpMethod("HEAD"),
 17                 RequestUri = new Uri(_baseAddress + "/api/test/HttpClientHot")
 18             })
 19             .Result.EnsureSuccessStatusCode();
 20             #endregion
 21 
 22             #region 初始化和預熱 fileClient
 23 
 24             _fileClient = new HttpClient();
 25             _fileClient.BaseAddress = new Uri(_baseAddress + "/api/test/HttpClientHot");
 26             _fileClient.MaxResponseContentBufferSize = 256000;
 27 
 28             #endregion
 29         }
 30 
 31         /// <summary>
 32         /// http Get請求
 33         /// </summary>
 34         /// <typeparam name="T">入參類型</typeparam>
 35         /// <typeparam name="TResult">出參類型</typeparam>
 36         /// <param name="req">入參對象</param>
 37         /// <returns></returns>
 38         public static async Task<Resp<TResult>> GetAsync<T, TResult>(Req<T> req)
 39         {
 40             try
 41             {
 42                 var result =await _httpClient.GetAsync(req.Url).Result.Content.ReadAsStringAsync();
 47                 return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
 48             }
 49             catch(Exception ex)
 50             {
 51 
 52             }
 53                 return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>("") };
 54             
 55         }
 56 
 57         /// <summary>
 58         ///  http Post請求
 59         /// </summary>
 60         /// <typeparam name="T">入參類型</typeparam>
 61         /// <typeparam name="TResult">出參類型</typeparam>
 62         /// <param name="req">入參對象</param>
 63         /// <returns></returns>
 64         public static async Task<Resp<TResult>> PostAsJsonAsync<T, TResult>(Req<T> req)
 65         {
 66             var result = await _httpClient.PostAsJsonAsync(req.Url, req.Input).Result.Content.ReadAsStringAsync();
 67             return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
 68         }
 69 
 70         /// <summary>
 71         /// 上傳文件
 72         /// </summary>
 73         /// <typeparam name="T"></typeparam>
 74         /// <typeparam name="TResult"></typeparam>
 75         /// <param name="req"></param>
 76         /// <param name="filePath"></param>
 77         /// <returns></returns>
 78         public static async Task<Resp<TResult>> SendFile<T, TResult>(Req<T> req, string filePath)//D:\\white.jpg
 79         {
 80             //_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");//設置請求頭
 81             // 讀文件流
 82             FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
 83             HttpContent fileContent = new StreamContent(fs);//爲文件流提供的HTTP容器
 84             fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");//設置媒體類型
 85             MultipartFormDataContent mulContent = new MultipartFormDataContent("----");//建立用於可傳遞文件的容器
 86             string fileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
 87             mulContent.Add(fileContent, "form", fileName);//第二個參數是表單名,第三個是文件名。
 88             HttpResponseMessage response = await _fileClient.PostAsync(req.Url, mulContent);
 89             response.EnsureSuccessStatusCode();
 90             string result = await response.Content.ReadAsStringAsync();
 91             return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
 92         }
 93 
 94         /// <summary>
 95         /// 下載
 96         /// </summary>
 97         /// <param name="url"></param>
 98         /// <returns></returns>
 99         public static async Task<Resp<byte[]>> HttpDownloadData<T>(Req<T> req)
100         {
101             var byteres = await _fileClient.GetByteArrayAsync(req.Url);
102             return new Resp<byte[]>() { Data = byteres };
103         }
104 
105         #endregion
106 }

另外分享下HttpWebRequest來實現的請求。HttpWebRequest須要你自行設置不少內容,固然這也證實其內容豐富。下面代碼包含了post,get,以及上傳。api

        /// <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();//發送請求,獲得響應流
                    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();
         }
相關文章
相關標籤/搜索