C#實(shí)現(xiàn)HTTP訪問類HttpHelper的示例詳解
在項(xiàng)目開發(fā)過程中,我們經(jīng)常會訪問第三方接口,如我們需要接入的第三方接口是Web API,這時(shí)候我們就需要使用HttpHelper調(diào)用遠(yuǎn)程接口了。示例中的HttpHelper類使用Log4Net記錄了每次調(diào)用的請求內(nèi)容和響應(yīng)內(nèi)容的日志,并且每條日志都帶上了鏈路ID和標(biāo)識,這樣方便我們在排查問題時(shí)能快速的找到當(dāng)時(shí)的請求和響應(yīng)內(nèi)容,進(jìn)而定位分析問題。大家在使用的時(shí)候如不需要記錄日志,刪除掉即可。
HttpHelper類代碼如下:
public class HttpHelper : IDisposable { private bool _disposable = false; /// <summary> /// 請求編碼格式默認(rèn)utf-8; /// </summary> public Encoding HtmlEncoding = Encoding.UTF8; /// <summary> /// 請求時(shí)間 /// </summary> public int Timeout = 5000; public CookieContainer Cookies = null; /// <summary> /// 是否記錄Cookies /// </summary> public bool IsRecordCookie = false; public string ContentType = "application/x-www-form-urlencoded"; public string AcceptLanguage = "en-US, en; q=0.8, zh-Hans-CN; q=0.5, zh-Hans; q=0.3"; public string KeepAlive = "Keep-Alive"; public string Accept = "*/*"; private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"; private static ILogger Logger = Log4NetLoggerFactory.Instance.Create("remote.info"); public HttpHelper() { //允許最大連接數(shù),突破Http協(xié)議的并發(fā)連接數(shù)限制 ServicePointManager.DefaultConnectionLimit = 512; } /// <summary> /// 上傳圖片 /// </summary> /// <param name="url"></param> /// <param name="bArr"></param> /// <param name="fileName"></param> /// <returns></returns> public HttpRequestEntity RequestFile(string url, byte[] bArr, string fileName = "") { var result = new HttpRequestEntity { IsSuccess = 0 }; //后續(xù)需要再放開,啟用時(shí)需增加日志收集 //if (string.IsNullOrEmpty(url)) // throw new ArgumentNullException("請求Url不能為空值"); //if (bArr == null || bArr.Length <= 0) // throw new AccessViolationException("缺少輸入數(shù)據(jù)"); //Stream requestStream = null; //StreamReader streamReader = null; //HttpWebResponse response = null; //HttpWebRequest request = null; //try //{ // request = WebRequest.Create(url) as HttpWebRequest; // request.AllowAutoRedirect = true; // request.Method = "POST"; // string boundary = DateTime.Now.Ticks.ToString("X"); // 隨機(jī)分隔線 // request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary; // byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n"); // byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); // if (string.IsNullOrEmpty(fileName)) // fileName = DateTime.Now.ToString("yyyyMMddHHmmss"); // //請求頭部信息 // StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName)); // byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString()); // request.Headers.Add("auth", fileName); // Stream postStream = request.GetRequestStream(); // postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length); // postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length); // postStream.Write(bArr, 0, bArr.Length); // postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); // postStream.Close(); // response = request.GetResponse() as HttpWebResponse; // requestStream = response.GetResponseStream(); // if (response.StatusCode == HttpStatusCode.OK) // { // result.IsSuccess = 0; // if (requestStream != null) // { // streamReader = new StreamReader(requestStream, HtmlEncoding); // result.ResponseContent = streamReader.ReadToEnd(); // } // } //} //catch (Exception ex) //{ // result.IsSuccess = 1; // result.ResponseContent = ex.Message; //} //finally //{ // if (requestStream != null) // { // requestStream.Close(); // requestStream.Dispose(); // } // if (streamReader != null) // { // streamReader.Close(); // streamReader.Dispose(); // } // request.Abort(); // if (response != null) // response.Close(); //} return result; } /// <summary> /// 基本請求方法 /// </summary> /// <param name="requestType">HTTP請求類型</param> /// <param name="url">請求的URL</param> /// <param name="requestData">請求參數(shù)</param> /// <param name="traceID">鏈路ID,方便查詢?nèi)罩?lt;/param> /// <param name="markType">請求標(biāo)識,方便查詢?nèi)罩?lt;/param> /// <returns></returns> private HttpRequestEntity BaseRequest(RequestType requestType, string url, string requestData, string traceID,string markType) { var result = new HttpRequestEntity { IsSuccess = 0 }; if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("請求Url不能為空值"); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Dictionary<string, object> resultLog = new Dictionary<string, object>();//log對象 resultLog.Add("logType", "remote"); resultLog.Add("traceID", traceID); resultLog.Add("localIp", IpHelper.LocalIp); resultLog.Add("markType", markType); resultLog.Add("url", url); resultLog.Add("requestContent", HttpUtility.UrlDecode(requestData, Encoding.UTF8)); resultLog.Add("createTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); StackTrace ss = new StackTrace(true); System.Reflection.MethodBase mb = ss.GetFrame(2).GetMethod();//0表示當(dāng)前??臻g,1表示上一級的??臻g,依次類推 resultLog.Add("className", mb.DeclaringType.FullName); resultLog.Add("methodName", mb.Name); HttpStatusCode statusCode = HttpStatusCode.OK; if (IsRecordCookie) Cookies = new CookieContainer(); Stream requestStream = null; StreamReader streamReader = null; HttpWebRequest webRe = null; HttpWebResponse webPos = null; try { if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); webRe = WebRequest.Create(url) as HttpWebRequest; webRe.ProtocolVersion = HttpVersion.Version10; } else { webRe = (HttpWebRequest)WebRequest.Create(url); } webRe.Headers.Add("Accept-Language", AcceptLanguage); webRe.Headers.Add("Keep-Alive", KeepAlive); webRe.UserAgent = UserAgent; webRe.Accept = Accept; webRe.Timeout = Timeout; webRe.ReadWriteTimeout = Timeout; webRe.CookieContainer = Cookies; if (requestType == RequestType.Post) { webRe.ContentType = string.Format("{0}; {1}", ContentType, HtmlEncoding.BodyName); byte[] datas = HtmlEncoding.GetBytes(requestData); webRe.Method = "POST"; webRe.ContentLength = datas.Length; webRe.MaximumResponseHeadersLength = -1; requestStream = webRe.GetRequestStream(); requestStream.Write(datas, 0, datas.Length); requestStream.Flush(); requestStream.Close(); } else webRe.Method = "GET"; webPos = (HttpWebResponse)webRe.GetResponse(); resultLog.Add("requestType", webRe.Method); statusCode = webPos.StatusCode; result.ResponseLength = webPos.ContentLength; result.ResponseEncodingName = webPos.ContentEncoding; requestStream = webPos.GetResponseStream(); if (webPos.StatusCode == HttpStatusCode.OK) { result.IsSuccess = 0; if (requestStream != null) { streamReader = new StreamReader(requestStream, HtmlEncoding); result.ResponseContent = streamReader.ReadToEnd(); } } } catch (Exception ex) { result.IsSuccess = 1; result.ResponseContent = ex.Message; } finally { if (requestStream != null) { requestStream.Close(); requestStream.Dispose(); } if (streamReader != null) { streamReader.Close(); streamReader.Dispose(); } webRe.Abort(); if (webPos != null) webPos.Close(); } if (result.IsSuccess == 1) { resultLog.Add("status", HttpStatusCode.InternalServerError); resultLog.Add("success", false); resultLog.Add("responseContent", result.ResponseContent); stopwatch.Stop(); resultLog.Add("elapseTime", stopwatch.Elapsed.TotalMilliseconds); string log = JsonConvert.SerializeObject(resultLog); Logger.Info(log); Logger.Error(log); } else { resultLog.Add("status", statusCode); resultLog.Add("success", true); resultLog.Add("responseContent", result.ResponseContent); stopwatch.Stop(); resultLog.Add("elapseTime", stopwatch.Elapsed.TotalMilliseconds); string log = JsonConvert.SerializeObject(resultLog); Logger.Info(log); } return result; } private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; //總是接受 } /// <summary> /// Get請求 /// </summary> /// <param name="url">請求地址</param> /// <param name="traceID">鏈路ID,方便查詢?nèi)罩?lt;/param> /// <param name="markType">請求標(biāo)識,方便查詢?nèi)罩?lt;/param> /// <returns></returns> public HttpRequestEntity Request(string url, string traceID, string markType) { return BaseRequest(RequestType.Get, url, string.Empty, traceID, markType); } /// <summary> /// Post請求 /// </summary> /// <param name="url">請求地址Url</param> /// <param name="requestData">請求內(nèi)容參數(shù)</param> /// <param name="traceID">鏈路ID,方便查詢?nèi)罩?lt;/param> /// <param name="markType">請求標(biāo)識,方便查詢?nèi)罩?lt;/param> /// <returns></returns> public HttpRequestEntity Request(string url, string requestData, string traceID, string markType) { return BaseRequest(RequestType.Post, url, requestData, traceID, markType); } ~HttpHelper() { Dispose(false); } #region IDisposable 成員 public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (this._disposable) return; if (disposing) { } _disposable = true; } #endregion } /// <summary> /// HttpHelper請求方式 /// </summary> public enum RequestType { /// <summary> /// Get請求 /// </summary> Get, /// <summary> /// Post請求 /// </summary> Post } /// <summary> /// HttpHelper請求時(shí)返回實(shí)體 /// </summary> public class HttpRequestEntity { /// <summary> /// 請求是否成功 0-成功(返回Http狀態(tài)碼200) 1-失敗(出現(xiàn)異常) /// </summary> public int IsSuccess { get; set; } /// <summary> /// 請求返回內(nèi)容 /// </summary> public string ResponseContent { get; set; } /// <summary> /// 請求返回內(nèi)容長度 /// </summary> public long ResponseLength { get; set; } /// <summary> /// 請求返回編碼類型 /// </summary> public string ResponseEncodingName { get; set; } }
調(diào)用示例如下:
HttpHelper helper = new HttpHelper(); HttpRequestEntity response = helper.Request("需要訪問的URL", "請求需要的參數(shù)", "訪問鏈路ID", "訪問標(biāo)識"); if (response.IsSuccess != 0) { //程序處理異常,請重試! } else { //請求響應(yīng)成功 }
到此這篇關(guān)于C#實(shí)現(xiàn)HTTP訪問類HttpHelper的示例詳解的文章就介紹到這了,更多相關(guān)C# HTTP訪問類HttpHelper內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#多線程開發(fā)實(shí)戰(zhàn)記錄之線程基礎(chǔ)
線程是一個(gè)獨(dú)立的運(yùn)行單元,每個(gè)進(jìn)程內(nèi)部有多個(gè)線程,每個(gè)線程可以各自同時(shí)執(zhí)行指令,每個(gè)線程有自己獨(dú)立的棧,但是與進(jìn)程內(nèi)的其他線程共享內(nèi)存,這篇文章主要給大家介紹了關(guān)于C#多線程開發(fā)實(shí)戰(zhàn)記錄之線程基礎(chǔ)的相關(guān)資料,需要的朋友可以參考下2021-09-09通過實(shí)例解析c# yield關(guān)鍵字使用方法
這篇文章主要介紹了通過實(shí)例解析c# yield關(guān)鍵字使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09C#實(shí)現(xiàn)系統(tǒng)休眠或靜止休眠的方法
這篇文章主要介紹了C#實(shí)現(xiàn)系統(tǒng)休眠或靜止休眠的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05C# winfrom 模擬ftp文件管理實(shí)現(xiàn)代碼
從網(wǎng)上找到的非常好用的模擬ftp管理代碼,整理了一下,希望對需要的人有幫助2014-01-01