1 /// <summary> 2 /// 類說明:HttpHelps類,用來實現Http訪問,Post或者Get方式的,直接訪問,帶Cookie的,帶證書的等方式,能夠設置代理 3 /// 重要提示:請不要自行修改本類,若是由於你本身修改後將沒法升級到新版本。若是確實有什麼問題請到官方網站提建議, 4 /// 咱們必定會及時修改 5 /// 編碼日期:2011-09-20 6 /// 編 碼 人:蘇飛 7 /// 聯繫方式:361983679 8 /// 官方網址:http://www.sufeinet.com/thread-3-1-1.html 9 /// 修改日期:2013-04-14 10 /// </summary> 11 using System; 12 using System.Collections.Generic; 13 using System.Text; 14 using System.Net; 15 using System.IO; 16 using System.Text.RegularExpressions; 17 using System.IO.Compression; 18 using System.Security.Cryptography.X509Certificates; 19 using System.Net.Security; 20 21 namespace Common.PageHelper 22 { 23 /// <summary> 24 /// Http鏈接操做幫助類 25 /// </summary> 26 public class HttpHelper 27 { 28 #region 預約義方法或者變動 29 //默認的編碼 30 private Encoding encoding = Encoding.Default; 31 //HttpWebRequest對象用來發起請求 32 private HttpWebRequest request = null; 33 //獲取影響流的數據對象 34 private HttpWebResponse response = null; 35 /// <summary> 36 /// 根據相傳入的數據,獲得相應頁面數據 37 /// </summary> 38 /// <param name="objhttpitem">參數類對象</param> 39 /// <returns>返回HttpResult類型</returns> 40 private HttpResult GetHttpRequestData(HttpItem objhttpitem) 41 { 42 //返回參數 43 HttpResult result = new HttpResult(); 44 try 45 { 46 #region 獲得請求的response 47 using (response = (HttpWebResponse)request.GetResponse()) 48 { 49 result.StatusCode = response.StatusCode; 50 result.StatusDescription = response.StatusDescription; 51 result.Header = response.Headers; 52 if (response.Cookies != null) 53 result.CookieCollection = response.Cookies; 54 if (response.Headers["set-cookie"] != null) 55 result.Cookie = response.Headers["set-cookie"]; 56 MemoryStream _stream = new MemoryStream(); 57 //GZIIP處理 58 if (response.ContentEncoding != null && response.ContentEncoding.Equals("gzip", StringComparison.InvariantCultureIgnoreCase)) 59 { 60 //開始讀取流並設置編碼方式 61 //new GZipStream(response.GetResponseStream(), CompressionMode.Decompress).CopyTo(_stream, 10240); 62 //.net4.0如下寫法 63 _stream = GetMemoryStream(new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)); 64 } 65 else 66 { 67 //開始讀取流並設置編碼方式 68 //response.GetResponseStream().CopyTo(_stream, 10240); 69 //.net4.0如下寫法 70 _stream = GetMemoryStream(response.GetResponseStream()); 71 } 72 //獲取Byte 73 byte[] RawResponse = _stream.ToArray(); 74 _stream.Close(); 75 //是否返回Byte類型數據 76 if (objhttpitem.ResultType == ResultType.Byte) 77 result.ResultByte = RawResponse; 78 //從這裏開始咱們要無視編碼了 79 if (encoding == null) 80 { 81 Match meta = Regex.Match(Encoding.Default.GetString(RawResponse), "<meta([^<]*)charset=([^<]*)[\"']", RegexOptions.IgnoreCase); 82 string charter = (meta.Groups.Count > 2) ? meta.Groups[2].Value.ToLower() : string.Empty; 83 charter = charter.Replace("\"", "").Replace("'", "").Replace(";", "").Replace("iso-8859-1", "gbk"); 84 if (charter.Length > 2) 85 encoding = Encoding.GetEncoding(charter); 86 else 87 { 88 if (string.IsNullOrEmpty(response.CharacterSet)) 89 encoding = Encoding.UTF8; 90 else 91 encoding = Encoding.GetEncoding(response.CharacterSet); 92 } 93 } 94 //獲得返回的HTML 95 result.Html = encoding.GetString(RawResponse); 96 } 97 #endregion 98 } 99 catch (WebException ex) 100 { 101 //這裏是在發生異常時返回的錯誤信息 102 response = (HttpWebResponse)ex.Response; 103 result.Html = ex.Message; 104 result.StatusCode = response.StatusCode; 105 result.StatusDescription = response.StatusDescription; 106 } 107 catch (Exception ex) 108 { 109 result.Html = ex.Message; 110 } 111 if (objhttpitem.IsToLower) 112 result.Html = result.Html.ToLower(); 113 114 return result; 115 } 116 /// <summary> 117 /// 4.0如下.net版本取數據使用 118 /// </summary> 119 /// <param name="streamResponse">流</param> 120 private static MemoryStream GetMemoryStream(Stream streamResponse) 121 { 122 MemoryStream _stream = new MemoryStream(); 123 int Length = 256; 124 Byte[] buffer = new Byte[Length]; 125 int bytesRead = streamResponse.Read(buffer, 0, Length); 126 // write the required bytes 127 while (bytesRead > 0) 128 { 129 _stream.Write(buffer, 0, bytesRead); 130 bytesRead = streamResponse.Read(buffer, 0, Length); 131 } 132 return _stream; 133 } 134 /// <summary> 135 /// 爲請求準備參數 136 /// </summary> 137 ///<param name="objhttpItem">參數列表</param> 138 /// <param name="_Encoding">讀取數據時的編碼方式</param> 139 private void SetRequest(HttpItem objhttpItem) 140 { 141 // 驗證證書 142 SetCer(objhttpItem); 143 //設置Header參數 144 if (objhttpItem.Header != null && objhttpItem.Header.Count > 0) 145 { 146 foreach (string item in objhttpItem.Header.AllKeys) 147 { 148 request.Headers.Add(item, objhttpItem.Header[item]); 149 } 150 } 151 // 設置代理 152 SetProxy(objhttpItem); 153 //請求方式Get或者Post 154 request.Method = objhttpItem.Method; 155 request.Timeout = objhttpItem.Timeout; 156 request.ReadWriteTimeout = objhttpItem.ReadWriteTimeout; 157 //Accept 158 request.Accept = objhttpItem.Accept; 159 //ContentType返回類型 160 request.ContentType = objhttpItem.ContentType; 161 //UserAgent客戶端的訪問類型,包括瀏覽器版本和操做系統信息 162 request.UserAgent = objhttpItem.UserAgent; 163 // 編碼 164 encoding = objhttpItem.Encoding; 165 //設置Cookie 166 SetCookie(objhttpItem); 167 //來源地址 168 request.Referer = objhttpItem.Referer; 169 //是否執行跳轉功能 170 request.AllowAutoRedirect = objhttpItem.Allowautoredirect; 171 //設置Post數據 172 SetPostData(objhttpItem); 173 //設置最大鏈接 174 if (objhttpItem.Connectionlimit > 0) 175 request.ServicePoint.ConnectionLimit = objhttpItem.Connectionlimit; 176 } 177 /// <summary> 178 /// 設置證書 179 /// </summary> 180 /// <param name="objhttpItem"></param> 181 private void SetCer(HttpItem objhttpItem) 182 { 183 if (!string.IsNullOrEmpty(objhttpItem.CerPath)) 184 { 185 //這一句必定要寫在建立鏈接的前面。使用回調的方法進行證書驗證。 186 ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); 187 //初始化對像,並設置請求的URL地址 188 request = (HttpWebRequest)WebRequest.Create(objhttpItem.URL); 189 //將證書添加到請求裏 190 request.ClientCertificates.Add(new X509Certificate(objhttpItem.CerPath)); 191 } 192 else 193 //初始化對像,並設置請求的URL地址 194 request = (HttpWebRequest)WebRequest.Create(objhttpItem.URL); 195 } 196 /// <summary> 197 /// 設置Cookie 198 /// </summary> 199 /// <param name="objhttpItem">Http參數</param> 200 private void SetCookie(HttpItem objhttpItem) 201 { 202 if (!string.IsNullOrEmpty(objhttpItem.Cookie)) 203 //Cookie 204 request.Headers[HttpRequestHeader.Cookie] = objhttpItem.Cookie; 205 //設置Cookie 206 if (objhttpItem.CookieCollection != null) 207 { 208 request.CookieContainer = new CookieContainer(); 209 request.CookieContainer.Add(objhttpItem.CookieCollection); 210 } 211 } 212 /// <summary> 213 /// 設置Post數據 214 /// </summary> 215 /// <param name="objhttpItem">Http參數</param> 216 private void SetPostData(HttpItem objhttpItem) 217 { 218 //驗證在獲得結果時是否有傳入數據 219 if (request.Method.Trim().ToLower().Contains("post")) 220 { 221 byte[] buffer = null; 222 //寫入Byte類型 223 if (objhttpItem.PostDataType == PostDataType.Byte && objhttpItem.PostdataByte != null && objhttpItem.PostdataByte.Length > 0) 224 { 225 //驗證在獲得結果時是否有傳入數據 226 buffer = objhttpItem.PostdataByte; 227 }//寫入文件 228 else if (objhttpItem.PostDataType == PostDataType.FilePath && !string.IsNullOrEmpty(objhttpItem.Postdata)) 229 { 230 StreamReader r = new StreamReader(objhttpItem.Postdata, encoding); 231 buffer = Encoding.Default.GetBytes(r.ReadToEnd()); 232 r.Close(); 233 } //寫入字符串 234 else if (!string.IsNullOrEmpty(objhttpItem.Postdata)) 235 { 236 buffer = Encoding.Default.GetBytes(objhttpItem.Postdata); 237 } 238 if (buffer != null) 239 { 240 request.ContentLength = buffer.Length; 241 request.GetRequestStream().Write(buffer, 0, buffer.Length); 242 } 243 } 244 } 245 /// <summary> 246 /// 設置代理 247 /// </summary> 248 /// <param name="objhttpItem">參數對象</param> 249 private void SetProxy(HttpItem objhttpItem) 250 { 251 if (!string.IsNullOrEmpty(objhttpItem.ProxyIp)) 252 { 253 //設置代理服務器 254 WebProxy myProxy = new WebProxy(objhttpItem.ProxyIp, false); 255 //建議鏈接 256 myProxy.Credentials = new NetworkCredential(objhttpItem.ProxyUserName, objhttpItem.ProxyPwd); 257 //給當前請求對象 258 request.Proxy = myProxy; 259 //設置安全憑證 260 request.Credentials = CredentialCache.DefaultNetworkCredentials; 261 } 262 } 263 /// <summary> 264 /// 回調驗證證書問題 265 /// </summary> 266 /// <param name="sender">流對象</param> 267 /// <param name="certificate">證書</param> 268 /// <param name="chain">X509Chain</param> 269 /// <param name="errors">SslPolicyErrors</param> 270 /// <returns>bool</returns> 271 public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 272 { 273 // 老是接受 274 return true; 275 } 276 #endregion 277 #region 普通類型 278 ///<summary> 279 ///採用https協議訪問網絡,根據傳入的URl地址,獲得響應的數據字符串。 280 ///</summary> 281 ///<param name="objhttpItem">參數列表</param> 282 ///<returns>String類型的數據</returns> 283 public HttpResult GetHtml(HttpItem objhttpItem) 284 { 285 try 286 { 287 //準備參數 288 SetRequest(objhttpItem); 289 } 290 catch (Exception ex) 291 { 292 return new HttpResult() { Cookie = "", Header = null, Html = ex.Message, StatusDescription = "配置參考時報錯" }; 293 } 294 //調用專門讀取數據的類 295 return GetHttpRequestData(objhttpItem); 296 } 297 #endregion 298 } 299 /// <summary> 300 /// Http請求參考類 301 /// </summary> 302 public class HttpItem 303 { 304 string _URL = string.Empty; 305 /// <summary> 306 /// 請求URL必須填寫 307 /// </summary> 308 public string URL 309 { 310 get { return _URL; } 311 set { _URL = value; } 312 } 313 string _Method = "GET"; 314 /// <summary> 315 /// 請求方式默認爲GET方式,當爲POST方式時必須設置Postdata的值 316 /// </summary> 317 public string Method 318 { 319 get { return _Method; } 320 set { _Method = value; } 321 } 322 int _Timeout = 100000; 323 /// <summary> 324 /// 默認請求超時時間 325 /// </summary> 326 public int Timeout 327 { 328 get { return _Timeout; } 329 set { _Timeout = value; } 330 } 331 int _ReadWriteTimeout = 30000; 332 /// <summary> 333 /// 默認寫入Post數據超時間 334 /// </summary> 335 public int ReadWriteTimeout 336 { 337 get { return _ReadWriteTimeout; } 338 set { _ReadWriteTimeout = value; } 339 } 340 string _Accept = "text/html, application/xhtml+xml, */*"; 341 /// <summary> 342 /// 請求標頭值 默認爲text/html, application/xhtml+xml, */* 343 /// </summary> 344 public string Accept 345 { 346 get { return _Accept; } 347 set { _Accept = value; } 348 } 349 string _ContentType = "text/html"; 350 /// <summary> 351 /// 請求返回類型默認 text/html 352 /// </summary> 353 public string ContentType 354 { 355 get { return _ContentType; } 356 set { _ContentType = value; } 357 } 358 string _UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"; 359 /// <summary> 360 /// 客戶端訪問信息默認Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) 361 /// </summary> 362 public string UserAgent 363 { 364 get { return _UserAgent; } 365 set { _UserAgent = value; } 366 } 367 Encoding _Encoding = null; 368 /// <summary> 369 /// 返回數據編碼默認爲NUll,能夠自動識別,通常爲utf-8,gbk,gb2312 370 /// </summary> 371 public Encoding Encoding 372 { 373 get { return _Encoding; } 374 set { _Encoding = value; } 375 } 376 private PostDataType _PostDataType = PostDataType.String; 377 /// <summary> 378 /// Post的數據類型 379 /// </summary> 380 public PostDataType PostDataType 381 { 382 get { return _PostDataType; } 383 set { _PostDataType = value; } 384 } 385 string _Postdata = string.Empty; 386 /// <summary> 387 /// Post請求時要發送的字符串Post數據 388 /// </summary> 389 public string Postdata 390 { 391 get { return _Postdata; } 392 set { _Postdata = value; } 393 } 394 private byte[] _PostdataByte = null; 395 /// <summary> 396 /// Post請求時要發送的Byte類型的Post數據 397 /// </summary> 398 public byte[] PostdataByte 399 { 400 get { return _PostdataByte; } 401 set { _PostdataByte = value; } 402 } 403 CookieCollection cookiecollection = null; 404 /// <summary> 405 /// Cookie對象集合 406 /// </summary> 407 public CookieCollection CookieCollection 408 { 409 get { return cookiecollection; } 410 set { cookiecollection = value; } 411 } 412 string _Cookie = string.Empty; 413 /// <summary> 414 /// 請求時的Cookie 415 /// </summary> 416 public string Cookie 417 { 418 get { return _Cookie; } 419 set { _Cookie = value; } 420 } 421 string _Referer = string.Empty; 422 /// <summary> 423 /// 來源地址,上次訪問地址 424 /// </summary> 425 public string Referer 426 { 427 get { return _Referer; } 428 set { _Referer = value; } 429 } 430 string _CerPath = string.Empty; 431 /// <summary> 432 /// 證書絕對路徑 433 /// </summary> 434 public string CerPath 435 { 436 get { return _CerPath; } 437 set { _CerPath = value; } 438 } 439 private Boolean isToLower = false; 440 /// <summary> 441 /// 是否設置爲全文小寫,默認爲不轉化 442 /// </summary> 443 public Boolean IsToLower 444 { 445 get { return isToLower; } 446 set { isToLower = value; } 447 } 448 private Boolean allowautoredirect = false; 449 /// <summary> 450 /// 支持跳轉頁面,查詢結果將是跳轉後的頁面,默認是不跳轉 451 /// </summary> 452 public Boolean Allowautoredirect 453 { 454 get { return allowautoredirect; } 455 set { allowautoredirect = value; } 456 } 457 private int connectionlimit = 1024; 458 /// <summary> 459 /// 最大鏈接數 460 /// </summary> 461 public int Connectionlimit 462 { 463 get { return connectionlimit; } 464 set { connectionlimit = value; } 465 } 466 private string proxyusername = string.Empty; 467 /// <summary> 468 /// 代理Proxy 服務器用戶名 469 /// </summary> 470 public string ProxyUserName 471 { 472 get { return proxyusername; } 473 set { proxyusername = value; } 474 } 475 private string proxypwd = string.Empty; 476 /// <summary> 477 /// 代理 服務器密碼 478 /// </summary> 479 public string ProxyPwd 480 { 481 get { return proxypwd; } 482 set { proxypwd = value; } 483 } 484 private string proxyip = string.Empty; 485 /// <summary> 486 /// 代理 服務IP 487 /// </summary> 488 public string ProxyIp 489 { 490 get { return proxyip; } 491 set { proxyip = value; } 492 } 493 private ResultType resulttype = ResultType.String; 494 /// <summary> 495 /// 設置返回類型String和Byte 496 /// </summary> 497 public ResultType ResultType 498 { 499 get { return resulttype; } 500 set { resulttype = value; } 501 } 502 private WebHeaderCollection header = new WebHeaderCollection(); 503 //header對象 504 public WebHeaderCollection Header 505 { 506 get { return header; } 507 set { header = value; } 508 } 509 } 510 /// <summary> 511 /// Http返回參數類 512 /// </summary> 513 public class HttpResult 514 { 515 string _Cookie = string.Empty; 516 /// <summary> 517 /// Http請求返回的Cookie 518 /// </summary> 519 public string Cookie 520 { 521 get { return _Cookie; } 522 set { _Cookie = value; } 523 } 524 CookieCollection cookiecollection = new CookieCollection(); 525 /// <summary> 526 /// Cookie對象集合 527 /// </summary> 528 public CookieCollection CookieCollection 529 { 530 get { return cookiecollection; } 531 set { cookiecollection = value; } 532 } 533 private string html = string.Empty; 534 /// <summary> 535 /// 返回的String類型數據 只有ResultType.String時才返回數據,其它狀況爲空 536 /// </summary> 537 public string Html 538 { 539 get { return html; } 540 set { html = value; } 541 } 542 private byte[] resultbyte = null; 543 /// <summary> 544 /// 返回的Byte數組 只有ResultType.Byte時才返回數據,其它狀況爲空 545 /// </summary> 546 public byte[] ResultByte 547 { 548 get { return resultbyte; } 549 set { resultbyte = value; } 550 } 551 private WebHeaderCollection header = new WebHeaderCollection(); 552 //header對象 553 public WebHeaderCollection Header 554 { 555 get { return header; } 556 set { header = value; } 557 } 558 private string statusDescription = ""; 559 /// <summary> 560 /// 返回狀態說明 561 /// </summary> 562 public string StatusDescription 563 { 564 get { return statusDescription; } 565 set { statusDescription = value; } 566 } 567 private HttpStatusCode statusCode = HttpStatusCode.OK; 568 /// <summary> 569 /// 返回狀態碼,默認爲OK 570 /// </summary> 571 public HttpStatusCode StatusCode 572 { 573 get { return statusCode; } 574 set { statusCode = value; } 575 } 576 } 577 /// <summary> 578 /// 返回類型 579 /// </summary> 580 public enum ResultType 581 { 582 /// <summary> 583 /// 表示只返回字符串 只有Html有數據 584 /// </summary> 585 String, 586 /// <summary> 587 /// 表示返回字符串和字節流 ResultByte和Html都有數據返回 588 /// </summary> 589 Byte 590 } 591 /// <summary> 592 /// Post的數據格式默認爲string 593 /// </summary> 594 public enum PostDataType 595 { 596 /// <summary> 597 /// 字符串類型,這時編碼Encoding可不設置 598 /// </summary> 599 String, 600 /// <summary> 601 /// Byte類型,須要設置PostdataByte參數的值編碼Encoding可設置爲空 602 /// </summary> 603 Byte, 604 /// <summary> 605 /// 傳文件,Postdata必須設置爲文件的絕對路徑,必須設置Encoding的值 606 /// </summary> 607 FilePath 608 } 609 }