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 }