1. 程式人生 > 其它 >[by暴走的山交君][劍指Offer系列] 05 替換空格

[by暴走的山交君][劍指Offer系列] 05 替換空格

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Http;
using System.Web;
using System.Net;
using System.IO;
using Utility.Extensions;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

namespace Utility.Http { /// <summary> /// 自定義HTTP客戶端 /// </summary> public class HttpClient { /// <summary> /// 根據URL獲取返回資料 /// </summary> /// <returns></returns> public static string Get(string uri,string encoding="GB2312") {
string strBuff = string.Empty; Uri httpURL = new Uri(uri); HttpWebRequest webRequest = null; HttpWebResponse response = null; try { webRequest = (HttpWebRequest)WebRequest.Create(httpURL); webRequest.ServicePoint.Expect100Continue
= false; //取消100-Continue對話模式,直接發起請求 webRequest.ServicePoint.ConnectionLimit = int.MaxValue; webRequest.ServicePoint.UseNagleAlgorithm = false; webRequest.Proxy = null; //關閉代理 response = (HttpWebResponse)webRequest.GetResponse(); using (Stream respStream = response.GetResponseStream()) { using (StreamReader respStreamReader = new StreamReader(respStream, Encoding.GetEncoding(encoding))) { strBuff = respStreamReader.ReadToEnd(); } } response.Close(); webRequest.Abort(); } catch (Exception ex) { if (null != response) { response.Close(); } if (null != webRequest) { webRequest.Abort(); } strBuff = string.Empty; } return strBuff; } /// <summary> /// POST傳送資料到指定Url /// </summary> /// <param name="uri"></param> /// <param name="postData">需要傳送的資料[鍵值對 a=1&amp;c=1]</param> /// <param name="encoding"></param> /// <param name="basicAuthString"> /// Basic 認證的帳號密碼 /// Convert.ToBase64String(Encoding.UTF8.GetBytes(ID + ":" + PWD)) /// </param> /// <returns></returns> public static string Post(string uri, string postData, string encoding = "GB2312",string basicAuthString="",bool contentTypeIsJson = false,Dictionary<string,string> headers=null) { string strBuff = string.Empty; byte[] byteArray =Encoding.GetEncoding(encoding).GetBytes(postData); HttpWebRequest webRequest = null; HttpWebResponse response = null; try { webRequest = WebRequest.Create(new Uri(uri)) as HttpWebRequest; webRequest.ServicePoint.ConnectionLimit = int.MaxValue; webRequest.ServicePoint.UseNagleAlgorithm = false; webRequest.ServicePoint.Expect100Continue = false; //取消100-Continue對話模式,直接發起請求 //如果是傳送HTTPS請求 if (uri.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); webRequest.ProtocolVersion = HttpVersion.Version10; } webRequest.Method = "post"; webRequest.Proxy = null;//關閉代理 if (contentTypeIsJson) { webRequest.ContentType = "application/json;charset=" + encoding; } else { webRequest.ContentType = "application/x-www-form-urlencoded;charset=" + encoding; } webRequest.ContentLength = byteArray.Length; if (!string.IsNullOrEmpty(basicAuthString)) {//webRequest.Headers.Add("Authorization", "Basic " + "YXRsX2dkcHBsdXNfaW50ZWdyYXRpb246YXRsMTIzNCFAIyQ="); webRequest.Headers.Add(HttpRequestHeader.Authorization, "Basic " + basicAuthString); } if (null != headers && headers.Count > 0) { foreach (string key in headers.Keys) { webRequest.Headers.Add(key, headers[key]); } } System.IO.Stream newStream = webRequest.GetRequestStream(); newStream.Write(byteArray, 0, byteArray.Length); newStream.Close(); response = (HttpWebResponse)webRequest.GetResponse(); using (Stream respStream = response.GetResponseStream()) { using (StreamReader respStreamReader = new StreamReader(respStream, Encoding.GetEncoding(encoding))) { strBuff = respStreamReader.ReadToEnd(); } } response.Close(); webRequest.Abort(); } catch (Exception ex) { if (null != response) { response.Close(); } if (null != webRequest) { webRequest.Abort(); } strBuff = string.Empty; } return strBuff; } /// <summary> /// Post form表單資料(可以新增檔案) /// </summary> /// <param name="uri">提交的url地址</param> /// <param name="formData"> /// form表單鍵值對資訊 /// </param> /// <param name="filesData"> /// 表單中檔案資訊 /// </param> /// <param name="encodingStr">字元編碼</param> /// <param name="objx509">證書例項</param> /// <returns></returns> public static string Post(string uri, Dictionary<string, string> formData, List<FormFile> filesData, string encodingStr = "utf-8", X509Certificate objx509 = null) { string strBuff = string.Empty; Encoding encoding = Encoding.GetEncoding(encodingStr); string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); byte[] endbytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); try { //1.HttpWebRequest HttpWebRequest webRequest = WebRequest.Create(new Uri(uri)) as HttpWebRequest; webRequest.ServicePoint.ConnectionLimit = 1024;//提升系統外聯的最大併發web訪問數 webRequest.ServicePoint.Expect100Continue = false; if (uri.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { //certFilePath 絕對路徑 if (null != objx509) { webRequest.ClientCertificates.Add(objx509); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; } ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); webRequest.ProtocolVersion = HttpVersion.Version10; } else { webRequest.Credentials = CredentialCache.DefaultCredentials; } webRequest.ContentType = "multipart/form-data; boundary=" + boundary; webRequest.Method = "POST"; webRequest.KeepAlive = true; using (Stream stream = webRequest.GetRequestStream()) { //1.1 key/value string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; if (formData != null) { foreach (string key in formData.Keys) { stream.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, formData[key]); byte[] formitembytes = encoding.GetBytes(formitem); stream.Write(formitembytes, 0, formitembytes.Length); } } if (filesData != null && filesData.Count > 0) { //1.2 file string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n"; byte[] buffer = new byte[4096]; int bytesRead = 0; foreach (FormFile fileInfo in filesData) { stream.Write(boundarybytes, 0, boundarybytes.Length); string header = string.Empty; if (string.IsNullOrEmpty(fileInfo.FileName) && !string.IsNullOrEmpty(fileInfo.FileSrc)) { fileInfo.FileName = fileInfo.FileSrc.Substring(fileInfo.FileSrc.LastIndexOf("\\")); } header = string.Format(headerTemplate, fileInfo.FormFileName, fileInfo.FileName); byte[] headerbytes = encoding.GetBytes(header); stream.Write(headerbytes, 0, headerbytes.Length); if (!string.IsNullOrEmpty(fileInfo.FileSrc)) { using (FileStream fileStream = new FileStream(fileInfo.FileSrc, FileMode.Open, FileAccess.Read)) { while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { stream.Write(buffer, 0, bytesRead); } } } else { stream.Write(fileInfo.FileBytes, 0, fileInfo.FileBytes.Length); } } } //1.3 form end stream.Write(endbytes, 0, endbytes.Length); } //2.WebResponse HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); using (Stream respStream = response.GetResponseStream()) { using (StreamReader respStreamReader = new StreamReader(respStream, encoding)) { strBuff = respStreamReader.ReadToEnd(); } } response.Close(); webRequest.Abort(); } catch (Exception ex) { strBuff = string.Empty; } return strBuff; } /// <summary> /// 接收https認證結果 /// </summary> /// <param name="sender"></param> /// <param name="certificate"></param> /// <param name="chain"></param> /// <param name="errors"></param> /// <returns></returns> private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; //總是接受 } /// <summary> /// POST傳送資料到指定Url /// </summary> /// <param name="uri"></param> /// <param name="data">動態型別,傳入Class型別的物件,自動轉url引數[鍵值對 a=1&amp;c=1]</param> /// <param name="encoding"></param> /// <returns></returns> public static string Post(string uri,dynamic data, string encoding = "GB2312") { if (data is string) { StringBuilder strBuilder = new StringBuilder(); strBuilder = GetParameter(strBuilder, data); return Post(uri, strBuilder.ToString(), encoding); } else { return PostAsJsonAsync(uri, data); } } /// <summary> /// Post form表單資料(可以新增檔案) /// </summary> /// <param name="uri">提交的url地址</param> /// <param name="formData"> /// form表單鍵值對資訊 /// </param> /// <param name="filesData"> /// 表單中檔案資訊 /// </param> /// <param name="encodingStr">字元編碼</param> /// <param name="certFilePath">證書的絕對路徑</param> /// <returns></returns> public static string Post(string uri, Dictionary<string, string> formData, List<FormFile> filesData, string encodingStr = "utf-8", string certFilePath = "") { string strBuff = string.Empty; Encoding encoding = Encoding.GetEncoding(encodingStr); string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); byte[] endbytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); HttpWebRequest webRequest = null; HttpWebResponse response = null; try { //1.HttpWebRequest webRequest = WebRequest.Create(new Uri(uri)) as HttpWebRequest; webRequest.ServicePoint.Expect100Continue = false; //取消100-Continue對話模式,直接發起請求 webRequest.ServicePoint.ConnectionLimit = int.MaxValue; webRequest.ServicePoint.UseNagleAlgorithm = false; if (uri.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { //certFilePath 絕對路徑 if (!string.IsNullOrEmpty(certFilePath)) { X509Certificate objx509 = X509Certificate.CreateFromCertFile(certFilePath); webRequest.ClientCertificates.Add(objx509); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; } ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); webRequest.ProtocolVersion = HttpVersion.Version10; } else { webRequest.Credentials = CredentialCache.DefaultCredentials; } webRequest.ContentType = "multipart/form-data; boundary=" + boundary; webRequest.Method = "POST"; webRequest.KeepAlive = true; using (Stream stream = webRequest.GetRequestStream()) { //1.1 key/value string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; if (formData != null) { foreach (string key in formData.Keys) { stream.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, formData[key]); byte[] formitembytes = encoding.GetBytes(formitem); stream.Write(formitembytes, 0, formitembytes.Length); } } if (filesData != null && filesData.Count > 0) { //1.2 file string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n"; byte[] buffer = new byte[4096]; int bytesRead = 0; foreach (FormFile fileInfo in filesData) { stream.Write(boundarybytes, 0, boundarybytes.Length); string header = string.Empty; if (string.IsNullOrEmpty(fileInfo.FileName) && !string.IsNullOrEmpty(fileInfo.FileSrc)) { fileInfo.FileName = fileInfo.FileSrc.Substring(fileInfo.FileSrc.LastIndexOf("\\")); } header = string.Format(headerTemplate, fileInfo.FormFileName, fileInfo.FileName); byte[] headerbytes = encoding.GetBytes(header); stream.Write(headerbytes, 0, headerbytes.Length); if (!string.IsNullOrEmpty(fileInfo.FileSrc)) { using (FileStream fileStream = new FileStream(fileInfo.FileSrc, FileMode.Open, FileAccess.Read)) { while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { stream.Write(buffer, 0, bytesRead); } } } else { stream.Write(fileInfo.FileBytes, 0, fileInfo.FileBytes.Length); } } } //1.3 form end stream.Write(endbytes, 0, endbytes.Length); } //2.WebResponse response = (HttpWebResponse)webRequest.GetResponse(); using (Stream respStream = response.GetResponseStream()) { using (StreamReader respStreamReader = new StreamReader(respStream, encoding)) { strBuff = respStreamReader.ReadToEnd(); } } response.Close(); webRequest.Abort(); } catch (Exception ex) { if (null != response) { response.Close(); } if (null != webRequest) { webRequest.Abort(); } strBuff = string.Empty; } return strBuff; } /// <summary> /// HttpClient物件 /// </summary> static System.Net.Http.HttpClient m_HttpClient = null; static object m_lockObject = new object(); /// <summary> /// 採用 HttpClient 傳送資料 /// (使用同一個httpclient進行提高效率,優化拋送速率) /// </summary> /// <param name="uri">需傳送的URL地址</param> /// <param name="formData">表單鍵值對資訊</param> /// <param name="filesData">表單檔案資訊</param> /// <param name="encodingStr">編碼格式</param> /// <param name="objx509">證書物件</param> /// <returns></returns> public static async Task<string> PostAsync(string uri, Dictionary<string, string> formData, List<FormFile> filesData, string encodingStr = "utf-8", X509Certificate objx509 = null) { Encoding encoding = Encoding.GetEncoding(encodingStr); string strBuff = string.Empty; try { if (null == m_HttpClient) { lock (m_lockObject) { if (null == m_HttpClient) { System.Net.ServicePointManager.DefaultConnectionLimit = 1024; System.Net.Http.WebRequestHandler handler = new WebRequestHandler(); if (null != objx509) { handler.ClientCertificates.Add(objx509); } m_HttpClient = new System.Net.Http.HttpClient(handler); m_HttpClient.DefaultRequestHeaders.Connection.Add("keep-alive"); if (uri.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); } } } } using (var form = new MultipartFormDataContent()) { if (formData != null && formData.Count > 0) { foreach (string key in formData.Keys) { ByteArrayContent bac = new ByteArrayContent(encoding.GetBytes(formData[key])); form.Add(bac, key); } } if (filesData != null && filesData.Count > 0) { foreach (FormFile fileInfo in filesData) { ByteArrayContent bac = new ByteArrayContent(fileInfo.FileBytes); bac.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); form.Add(bac, fileInfo.FormFileName, fileInfo.FileName); } } var response = await m_HttpClient.PostAsync(uri, form); if (response.IsSuccessStatusCode) { strBuff = response.Content.ReadAsStringAsync().Result; } else { strBuff = string.Empty; } } } catch (Exception ex) { strBuff = string.Empty; } return strBuff; } /// <summary> /// POST傳送資料到指定[會將物件資料轉換成json資料進行傳送,對於字串型別的Json資料,自動採用HttpContent封裝Json資料進行拋送]Url /// </summary> /// <typeparam name="T">引數型別</typeparam> /// <param name="uri">post地址</param> /// <param name="data">引數</param> /// <param name="encoding"></param> /// <param name="authorization"> /// DefaultRequestHeaders.Authorization 認證 /// AuthenticationHeaderValue headerValue = new AuthenticationHeaderValue("Basic", Newtonsoft.Json.JsonConvert.SerializeObject(convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(config.AUTIH_ID + ":" + config.AUTH_PWD))); /// </param> /// <param name="headers"> /// 頭部引數 /// </param> /// <returns>返回Json資料</returns> public static string PostAsJsonAsync<T>(string uri, T data, string encoding = "utf-8", AuthenticationHeaderValue authorization = null,Dictionary<string,string> headers = null) { using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient()) { try { client.Timeout = new TimeSpan(0, 1, 0); if (uri.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); } client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Accept-Charset", encoding); if (null != authorization) { client.DefaultRequestHeaders.Add("User-Agent", "Quick.Framework Snail"); client.DefaultRequestHeaders.Authorization = authorization; } if (data is string) { using (HttpContent httpContent = new StringContent(data as string, Encoding.GetEncoding(encoding))) { if (null != headers && headers.Keys.Count > 0) { foreach (string key in headers.Keys) { httpContent.Headers.Add(key, headers[key]); } } HttpResponseMessage msg = client.PostAsync(uri, httpContent).Result; if (msg.IsSuccessStatusCode) { return msg.Content.ReadAsStringAsync().Result; } else { return string.Empty; } } } else { string dataJson = data.ToJsonString(); using (HttpContent httpContent = new StringContent(dataJson, Encoding.GetEncoding(encoding),"application/json")) { if (null != headers && headers.Keys.Count > 0) { foreach (string key in headers.Keys) { httpContent.Headers.Add(key, headers[key]); } } HttpResponseMessage msg = client.PostAsync(uri, httpContent).Result; if (msg.IsSuccessStatusCode) { return msg.Content.ReadAsStringAsync().Result; } else { return string.Empty; } } /* //不使用 client.PostAsJsonAsync<T>(uri, data).Result; 方法的原因是如果class 有可序列化標記, POST方法會將所有屬性增加上k__BackingField 標識,導致介面不識別資料 var response = client.PostAsJsonAsync<T>(uri, data).Result; if (response.IsSuccessStatusCode) { return response.Content.ReadAsStringAsync().Result; } else { return string.Empty; } */ } } catch (Exception ex) { return string.Empty; } } } /// <summary> /// POST傳送資料到指定[會將物件資料轉換成json資料進行傳送,對於字串型別的Json資料,自動採用HttpContent封裝Json資料進行拋送]Url /// </summary> /// <typeparam name="TRequst">傳入引數型別</typeparam> /// <typeparam name="TResponse">返回資料型別</typeparam> /// <param name="uri">post地址</param> /// <param name="data">引數[將T型別按照json資料Post到伺服器]</param> /// <param name="encoding"></param> /// <param name="authorization">DefaultRequestHeaders.Authorization 認證</param> /// <returns>返回TResponse型別資料[從Json資料內容轉換成T型別]</returns> public static TResponse PostAsJsonAsync<TRequst, TResponse>(string uri, TRequst data,string encoding = "utf-8" ,AuthenticationHeaderValue authorization = null) { var result = PostAsJsonAsync(uri, data, encoding, authorization); return result.FromJsonString<TResponse>(); } private static StringBuilder GetParameter(StringBuilder strBuilder, dynamic data) { Type t = data.GetType(); if (typeof(string) == t) { return new StringBuilder(data); } // 獲取類的所有公共屬性 System.Reflection.PropertyInfo[] pInfo = t.GetProperties(); // 遍歷公共屬性 foreach (System.Reflection.PropertyInfo pio in pInfo) { if (strBuilder.Length > 0) { strBuilder.Append("&"); } string fieldName = pio.Name; // 公共屬性的Name Type pioType = pio.PropertyType; // 公共屬性的型別 var v = pio.GetValue(data); string value = string.Empty; if ((pioType == typeof(String)) || (pioType == typeof(int) || pioType == typeof(int?) || pioType == typeof(Nullable<int>)) || (pioType == typeof(double) || pioType == typeof(double?) || pioType == typeof(Nullable<double>)) || (pioType == typeof(decimal) || pioType == typeof(decimal?) || pioType == typeof(Nullable<decimal>)) || (pioType == typeof(short) || pioType == typeof(short?) || pioType == typeof(Nullable<short>)) || (pioType == typeof(byte) || pioType == typeof(byte?) || pioType == typeof(Nullable<byte>)) || (pioType == typeof(long) || pioType == typeof(long?) || pioType == typeof(Nullable<long>)) ) { value = Convert.ToString(v); } else if ((pioType == typeof(DateTime) || pioType == typeof(DateTime?) || pioType == typeof(Nullable<DateTime>))) { if (string.IsNullOrEmpty(Convert.ToString(v))) { value = ""; } else { value = Convert.ToDateTime(v).ToString("yyyy-MM-dd HH:mm:ss"); } } else { try { strBuilder = GetParameter(strBuilder, v); } catch (Exception) { } continue; } strBuilder.AppendFormat("{0}={1}", fieldName, HttpUtility.UrlEncode(value)); } return strBuilder; } /// <summary> /// 下載檔案 /// </summary> /// <param name="uri">下載檔案地址</param> /// <param name="fileName">下載後另存為(全路徑)</param> public static bool DownloadFile(string uri, string fileName) { System.Net.HttpWebRequest request = null; System.Net.HttpWebResponse response = null; try { string path = fileName.Substring(0, fileName.LastIndexOf("\\")); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(uri); response = (System.Net.HttpWebResponse)request.GetResponse(); using (System.IO.Stream st = response.GetResponseStream()) { using (System.IO.Stream so = new System.IO.FileStream(fileName, System.IO.FileMode.Create)) { byte[] by = new byte[1024]; int osize = st.Read(by, 0, (int)by.Length); while (osize > 0) { so.Write(by, 0, osize); osize = st.Read(by, 0, (int)by.Length); } so.Close(); st.Close(); } } response.Close(); request.Abort(); return true; } catch (System.Exception e) { if (null != response) { response.Close(); } if (null != request) { request.Abort(); } return false; } } #region FormFile Class /// <summary> /// form 表單檔案內容 /// </summary> public class FormFile { /// <summary> /// form 表單中 file input 的name /// </summary> public string FormFileName { get; set; } /// <summary> /// 檔名, 如: 1.txt /// </summary> public string FileName { get; set; } /// <summary> /// 檔案路徑(檔案路徑與FileBytes,二選一,) /// 如: c:\\1.txt /// </summary> public string FileSrc { get; set; } /// <summary> /// 檔案的位元組流(檔案內容資料流) /// </summary> public byte[] FileBytes { get; set; } } #endregion } }