usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Net;usingSystem.IO;usingSystem.Text.RegularExpressions;usingSystem.IO.Compression;usingSystem.Security.Cryptography.X509Certificates;usingSystem.Net.Security;usingSystem.Linq;usingSystem.Net.Cache;usingSystem.Security.Authentication;namespaceHh.Mes.Common.Http{///<summary>///Http连接操作帮助类推荐使用来源苏飞///教程:http://www.sufeinet.com/forum.php?mod=forumdisplay&fid=135&filter=typeid&typeid=239///</summary>publicclassHttpHelper{#region预定义方变量//默认的编码privateEncodingencoding=Encoding.Default;//Post数据编码privateEncodingpostencoding=Encoding.Default;//HttpWebRequest对象用来发起请求privateHttpWebRequestrequest=null;//获取影响流的数据对象privateHttpWebResponseresponse=null;//设置本地的出口ip和端口privateIPEndPoint_IPEndPoint=null;#endregion#regionPublic///<summary>///根据相传入的数据,得到相应页面数据///</summary>///<paramname="item">参数类对象</param>///<returns>返回HttpResult类型</returns>publicHttpResultGetHtml(HttpItemitem){//返回参数HttpResultresult=newHttpResult();try{//准备参数SetRequest(item);}catch(Exceptionex){//配置参数时出错returnnewHttpResult(){Cookie=string.Empty,Header=null,Html=ex.Message,StatusDescription="配置参数时出错:"+ex.Message};}try{//请求数据using(response=(HttpWebResponse)request.GetResponse()){GetData(item,result);}}catch(WebExceptionex){if(ex.Response!=null){using(response=(HttpWebResponse)ex.Response){GetData(item,result);}}else{result.Html=ex.Message+$"【url:{item.URL},method:{item.Method}】";}}catch(Exceptionex){result.Html=ex.Message;}if(item.IsToLower)result.Html=result.Html.ToLower();//重置request,response为空if(item.IsReset){request=null;response=null;}returnresult;}#endregion#regionGetData///<summary>///获取数据的并解析的方法///</summary>///<paramname="item"></param>///<paramname="result"></param>privatevoidGetData(HttpItemitem,HttpResultresult){if(response==null){return;}#regionbase//获取StatusCoderesult.StatusCode=response.StatusCode;//获取StatusDescriptionresult.StatusDescription=response.StatusDescription;//获取Headersresult.Header=response.Headers;//获取最后访问的URlresult.ResponseUri=response.ResponseUri.ToString();//获取CookieCollectionif(response.Cookies!=null)result.CookieCollection=response.Cookies;//获取set-cookieif(response.Headers["set-cookie"]!=null)result.Cookie=response.Headers["set-cookie"];#endregion#regionbyte//处理网页Bytebyte[]ResponseByte=GetByte();#endregion#regionHtmlif(ResponseByte!=null&&ResponseByte.Length>0){//设置编码SetEncoding(item,result,ResponseByte);//得到返回的HTMLresult.Html=encoding.GetString(ResponseByte);}else{//没有返回任何Html代码result.Html=string.Empty;}#endregion}///<summary>///设置编码///</summary>///<paramname="item">HttpItem</param>///<paramname="result">HttpResult</param>///<paramname="ResponseByte">byte[]</param>privatevoidSetEncoding(HttpItemitem,HttpResultresult,byte[]ResponseByte){//是否返回Byte类型数据if(item.ResultType==ResultType.Byte)result.ResultByte=ResponseByte;//从这里开始我们要无视编码了if(encoding==null){Matchmeta=Regex.Match(Encoding.Default.GetString(ResponseByte),"<meta[^<]*charset=([^<]*)[\"']",RegexOptions.IgnoreCase);stringc=string.Empty;if(meta!=null&&meta.Groups.Count>0){c=meta.Groups[1].Value.ToLower().Trim();}if(c.Length>2){try{encoding=Encoding.GetEncoding(c.Replace("\"",string.Empty).Replace("'","").Replace(";","").Replace("iso-8859-1","gbk").Trim());}catch{if(string.IsNullOrEmpty(response.CharacterSet)){encoding=Encoding.UTF8;}else{encoding=Encoding.GetEncoding(response.CharacterSet);}}}else{if(string.IsNullOrEmpty(response.CharacterSet)){encoding=Encoding.UTF8;}else{encoding=Encoding.GetEncoding(response.CharacterSet);}}}}///<summary>///提取网页Byte///</summary>///<returns></returns>privatebyte[]GetByte(){byte[]ResponseByte=null;using(MemoryStream_stream=newMemoryStream()){//GZIIP处理if(response.ContentEncoding!=null&&response.ContentEncoding.Equals("gzip",StringComparison.InvariantCultureIgnoreCase)){//开始读取流并设置编码方式newGZipStream(response.GetResponseStream(),CompressionMode.Decompress).CopyTo(_stream,1024);}else{//开始读取流并设置编码方式response.GetResponseStream().CopyTo(_stream,1024);}//获取ByteResponseByte=_stream.ToArray();}returnResponseByte;}#endregion#regionSetRequest///<summary>///为请求准备参数///</summary>///<paramname="item">参数列表</param>privatevoidSetRequest(HttpItemitem){//验证证书SetCer(item);if(item.IPEndPoint!=null){_IPEndPoint=item.IPEndPoint;//设置本地的出口ip和端口request.ServicePoint.BindIPEndPointDelegate=newBindIPEndPoint(BindIPEndPointCallback);}//设置Header参数if(item.Header!=null&&item.Header.Count>0)foreach(stringkeyinitem.Header.AllKeys){request.Headers.Add(key,item.Header[key]);}//设置代理SetProxy(item);if(item.ProtocolVersion!=null)request.ProtocolVersion=item.ProtocolVersion;request.ServicePoint.Expect100Continue=item.Expect100Continue;//请求方式Get或者Postrequest.Method=item.Method;request.Timeout=item.Timeout;request.KeepAlive=item.KeepAlive;request.ReadWriteTimeout=item.ReadWriteTimeout;if(!string.IsNullOrWhiteSpace(item.Host)){request.Host=item.Host;}if(item.IfModifiedSince!=null)request.IfModifiedSince=Convert.ToDateTime(item.IfModifiedSince);if(item.Date!=null){request.Date=Convert.ToDateTime(item.Date);}//Acceptrequest.Accept=item.Accept;//ContentType返回类型request.ContentType=item.ContentType;//UserAgent客户端的访问类型,包括浏览器版本和操作系统信息request.UserAgent=item.UserAgent;//编码encoding=item.Encoding;//设置安全凭证request.Credentials=item.ICredentials;//设置CookieSetCookie(item);//来源地址request.Referer=item.Referer;//是否执行跳转功能request.AllowAutoRedirect=item.Allowautoredirect;if(item.MaximumAutomaticRedirections>0){request.MaximumAutomaticRedirections=item.MaximumAutomaticRedirections;}//设置Post数据SetPostData(item);//设置最大连接if(item.Connectionlimit>0)request.ServicePoint.ConnectionLimit=item.Connectionlimit;}///<summary>///设置证书///</summary>///<paramname="item"></param>privatevoidSetCer(HttpItemitem){//这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。//ServicePointManager.ServerCertificateValidationCallback=newSystem.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);ServicePointManager.ServerCertificateValidationCallback=newSystem.Net.Security.RemoteCertificateValidationCallback(delegate(objectsender,System.Security.Cryptography.X509Certificates.X509Certificatecertificate,System.Security.Cryptography.X509Certificates.X509Chainchain,System.Net.Security.SslPolicyErrorserrors){returntrue;});if(!string.IsNullOrWhiteSpace(item.CerPath)){//初始化对像,并设置请求的URL地址request=(HttpWebRequest)WebRequest.Create(item.URL);SetCerList(item);//将证书添加到请求里request.ClientCertificates.Add(newX509Certificate(item.CerPath));}else{//初始化对像,并设置请求的URL地址request=(HttpWebRequest)WebRequest.Create(item.URL);SetCerList(item);}}///<summary>///设置多个证书///</summary>///<paramname="item"></param>privatevoidSetCerList(HttpItemitem){if(item.ClentCertificates!=null&&item.ClentCertificates.Count>0){//这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。ServicePointManager.ServerCertificateValidationCallback=newSystem.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);foreach(X509Certificatecinitem.ClentCertificates){request.ClientCertificates.Add(c);}}}///<summary>///设置Cookie///</summary>///<paramname="item">Http参数</param>privatevoidSetCookie(HttpItemitem){if(!string.IsNullOrEmpty(item.Cookie))request.Headers[HttpRequestHeader.Cookie]=item.Cookie;//设置CookieCollectionif(item.ResultCookieType==ResultCookieType.CookieCollection){request.CookieContainer=newCookieContainer();if(item.CookieCollection!=null&&item.CookieCollection.Count>0){//默认为20个,如果超出需要增加长度if(item.CookieCollection.Count>20){request.CookieContainer.PerDomainCapacity=item.CookieCollection.Count;}request.CookieContainer.Add(item.CookieCollection);}}}///<summary>///设置Post数据///</summary>///<paramname="item">Http参数</param>privatevoidSetPostData(HttpItemitem){//验证在得到结果时是否有传入数据if(!request.Method.Trim().ToLower().Contains("get")){if(item.PostEncoding!=null){postencoding=item.PostEncoding;}byte[]buffer=null;//写入Byte类型if(item.PostDataType==PostDataType.Byte&&item.PostdataByte!=null&&item.PostdataByte.Length>0){//验证在得到结果时是否有传入数据buffer=item.PostdataByte;}//写入文件elseif(item.PostDataType==PostDataType.FilePath&&!string.IsNullOrWhiteSpace(item.Postdata)){StreamReaderr=newStreamReader(item.Postdata,postencoding);buffer=postencoding.GetBytes(r.ReadToEnd());r.Close();}//写入字符串elseif(!string.IsNullOrWhiteSpace(item.Postdata)){buffer=postencoding.GetBytes(item.Postdata);}if(buffer!=null){request.ContentLength=buffer.Length;request.GetRequestStream().Write(buffer,0,buffer.Length);}else{request.ContentLength=0;}}}///<summary>///设置代理///</summary>///<paramname="item">参数对象</param>privatevoidSetProxy(HttpItemitem){boolisIeProxy=false;if(!string.IsNullOrWhiteSpace(item.ProxyIp)){isIeProxy=item.ProxyIp.ToLower().Contains("ieproxy");}if(!string.IsNullOrWhiteSpace(item.ProxyIp)&&!isIeProxy){//设置代理服务器if(item.ProxyIp.Contains(":")){string[]plist=item.ProxyIp.Split(':');WebProxymyProxy=newWebProxy(plist[0].Trim(),Convert.ToInt32(plist[1].Trim()));//建议连接myProxy.Credentials=newNetworkCredential(item.ProxyUserName,item.ProxyPwd);//给当前请求对象request.Proxy=myProxy;}else{WebProxymyProxy=newWebProxy(item.ProxyIp,false);//建议连接myProxy.Credentials=newNetworkCredential(item.ProxyUserName,item.ProxyPwd);//给当前请求对象request.Proxy=myProxy;}}elseif(isIeProxy){//设置为IE代理}else{request.Proxy=item.WebProxy;}}#endregion#regionprivatemain///<summary>///回调验证证书问题///</summary>///<paramname="sender">流对象</param>///<paramname="certificate">证书</param>///<paramname="chain">X509Chain</param>///<paramname="errors">SslPolicyErrors</param>///<returns>bool</returns>privateboolCheckValidationResult(objectsender,X509Certificatecertificate,X509Chainchain,SslPolicyErrorserrors){returntrue;}///<summary>///通过设置这个属性,可以在发出连接的时候绑定客户端发出连接所使用的IP地址。///</summary>///<paramname="servicePoint"></param>///<paramname="remoteEndPoint"></param>///<paramname="retryCount"></param>///<returns></returns>privateIPEndPointBindIPEndPointCallback(ServicePointservicePoint,IPEndPointremoteEndPoint,intretryCount){return_IPEndPoint;//端口号}#endregion#region扩展postData方法https://blog.csdn.net/qq807081817/article/details/38053011///<summary>///post参数拼接///</summary>publicstringCreatePostData(Dictionary<string,string>PostParameters){stringpostdata=string.Empty;foreach(variteminPostParameters){if(postdata!=string.Empty)postdata+="&";postdata+=item.Key+"="+item.Value;}returnpostdata;}///<summary>///post参数拼接linq///</summary>///<paramname="PostParameters">Dictionary</param>///<paramname="IsEncode">敏感字符UrlEncode</param>///<returns></returns>publicstringCreatePostData(Dictionary<string,string>PostParameters,boolIsEncode=false){varquery=fromsinPostParametersselects.Key+"="+(IsEncode?System.Web.HttpUtility.UrlEncode(s.Value):s.Value);string[]parameters=query.ToArray<string>();returnstring.Join("&",parameters);}#endregion}#regionpubliccalss///<summary>///Http请求参考类///</summary>publicclassHttpItem{///<summary>///请求URL必须填写///</summary>publicstringURL{get;set;}string_Method="GET";///<summary>///请求方式默认为GET方式,当为POST方式时必须设置Postdata的值///</summary>publicstringMethod{get{return_Method;}set{_Method=value;}}int_Timeout=100000;///<summary>///默认请求超时时间///</summary>publicintTimeout{get{return_Timeout;}set{_Timeout=value;}}int_ReadWriteTimeout=30000;///<summary>///默认写入Post数据超时间///</summary>publicintReadWriteTimeout{get{return_ReadWriteTimeout;}set{_ReadWriteTimeout=value;}}///<summary>///设置Host的标头信息///</summary>publicstringHost{get;set;}Boolean_KeepAlive=true;///<summary>///获取或设置一个值,该值指示是否与Internet资源建立持久性连接默认为true。///</summary>publicBooleanKeepAlive{get{return_KeepAlive;}set{_KeepAlive=value;}}string_Accept="text/html, application/xhtml+xml, */*";///<summary>///请求标头值默认为text/html,application/xhtml+xml,*/*///</summary>publicstringAccept{get{return_Accept;}set{_Accept=value;}}string_ContentType="text/html";///<summary>///请求返回类型默认text/html///</summary>publicstringContentType{get{return_ContentType;}set{_ContentType=value;}}string_UserAgent="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";///<summary>///客户端访问信息默认Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0)///</summary>publicstringUserAgent{get{return_UserAgent;}set{_UserAgent=value;}}///<summary>///返回数据编码默认为NUll,可以自动识别,一般为utf-8,gbk,gb2312///</summary>publicEncodingEncoding{get;set;}privatePostDataType_PostDataType=PostDataType.String;///<summary>///Post的数据类型///</summary>publicPostDataTypePostDataType{get{return_PostDataType;}set{_PostDataType=value;}}///<summary>///Post请求时要发送的字符串Post数据///</summary>publicstringPostdata{get;set;}///<summary>///Post请求时要发送的Byte类型的Post数据///</summary>publicbyte[]PostdataByte{get;set;}///<summary>///Cookie对象集合///</summary>publicCookieCollectionCookieCollection{get;set;}///<summary>///请求时的Cookie///</summary>publicstringCookie{get;set;}///<summary>///来源地址,上次访问地址///</summary>publicstringReferer{get;set;}///<summary>///证书绝对路径///</summary>publicstringCerPath{get;set;}///<summary>///设置代理对象,不想使用IE默认配置就设置为Null,而且不要设置ProxyIp///</summary>publicWebProxyWebProxy{get;set;}privateBooleanisToLower=false;///<summary>///是否设置为全文小写,默认为不转化///</summary>publicBooleanIsToLower{get{returnisToLower;}set{isToLower=value;}}privateDateTime?_Date=null;///<summary>///获取或设置要在HTTP请求中使用的DateHTTP标头值。默认不填写///</summary>publicDateTime?Date{get{return_Date;}set{_Date=value;}}privateBooleanallowautoredirect=false;///<summary>///支持跳转页面,查询结果将是跳转后的页面,默认是不跳转///</summary>publicBooleanAllowautoredirect{get{returnallowautoredirect;}set{allowautoredirect=value;}}privateintconnectionlimit=1024;///<summary>///最大连接数///</summary>publicintConnectionlimit{get{returnconnectionlimit;}set{connectionlimit=value;}}///<summary>///代理Proxy服务器用户名///</summary>publicstringProxyUserName{get;set;}///<summary>///代理服务器密码///</summary>publicstringProxyPwd{get;set;}///<summary>///代理服务IP,如果要使用IE代理就设置为ieproxy///</summary>publicstringProxyIp{get;set;}privateResultTyperesulttype=ResultType.String;///<summary>///设置返回类型String和Byte///</summary>publicResultTypeResultType{get{returnresulttype;}set{resulttype=value;}}privateWebHeaderCollectionheader=newWebHeaderCollection();///<summary>///header对象///</summary>publicWebHeaderCollectionHeader{get{returnheader;}set{header=value;}}///<summary>//获取或设置用于请求的HTTP版本。返回结果:用于请求的HTTP版本。默认为System.Net.HttpVersion.Version11。///</summary>publicVersionProtocolVersion{get;set;}privateBoolean_expect100continue=false;///<summary>///获取或设置一个System.Boolean值,该值确定是否使用100-Continue行为。如果POST请求需要100-Continue响应,则为true;否则为false。默认值为true。///</summary>publicBooleanExpect100Continue{get{return_expect100continue;}set{_expect100continue=value;}}///<summary>///设置509证书集合///</summary>publicX509CertificateCollectionClentCertificates{get;set;}///<summary>///设置或获取Post参数编码,默认的为Default编码///</summary>publicEncodingPostEncoding{get;set;}privateResultCookieType_ResultCookieType=ResultCookieType.String;///<summary>///Cookie返回类型,默认的是只返回字符串类型///</summary>publicResultCookieTypeResultCookieType{get{return_ResultCookieType;}set{_ResultCookieType=value;}}privateICredentials_ICredentials=CredentialCache.DefaultCredentials;///<summary>///获取或设置请求的身份验证信息。///</summary>publicICredentialsICredentials{get{return_ICredentials;}set{_ICredentials=value;}}///<summary>///设置请求将跟随的重定向的最大数目///</summary>publicintMaximumAutomaticRedirections{get;set;}privateDateTime?_IfModifiedSince=null;///<summary>///获取和设置IfModifiedSince,默认为当前日期和时间///</summary>publicDateTime?IfModifiedSince{get{return_IfModifiedSince;}set{_IfModifiedSince=value;}}#regionip-portprivateIPEndPoint_IPEndPoint=null;///<summary>///设置本地的出口ip和端口///</summary>]///<example>///item.IPEndPoint=newIPEndPoint(IPAddress.Parse("192.168.1.1"),80);///</example>publicIPEndPointIPEndPoint{get{return_IPEndPoint;}set{_IPEndPoint=value;}}#endregionprivatebool_isReset=false;///<summary>///是否重置request,response的值,默认不重置,当设置为True时request,response将被设置为Null///</summary>publicboolIsReset{get{return_isReset;}set{_isReset=value;}}///<summary>///忽略证书扩展字段///</summary>publicboolIsCer{get;set;}///<summary>///扩展字段///</summary>publicstringHeaderStr{get;set;}}///<summary>///Http返回参数类///</summary>publicclassHttpResult{///<summary>///Http请求返回的Cookie///</summary>publicstringCookie{get;set;}///<summary>///Cookie对象集合///</summary>publicCookieCollectionCookieCollection{get;set;}privatestring_html=string.Empty;///<summary>///返回的String类型数据只有ResultType.String时才返回数据,其它情况为空///</summary>publicstringHtml{get{return_html;}set{_html=value;}}///<summary>///返回的Byte数组只有ResultType.Byte时才返回数据,其它情况为空///</summary>publicbyte[]ResultByte{get;set;}///<summary>///header对象///</summary>publicWebHeaderCollectionHeader{get;set;}///<summary>///返回状态说明///</summary>publicstringStatusDescription{get;set;}///<summary>///返回状态码,默认为OK///</summary>publicHttpStatusCodeStatusCode{get;set;}///<summary>///最后访问的URl///</summary>publicstringResponseUri{get;set;}///<summary>///获取重定向的URl///</summary>publicstringRedirectUrl{get{try{if(Header!=null&&Header.Count>0){if(Header.AllKeys.Any(k=>k.ToLower().Contains("base_location"))){stringbaseurl=Header["base_location"].ToString().Trim();stringlocationurl=baseurl.ToLower();if(!string.IsNullOrWhiteSpace(locationurl)){boolb=locationurl.StartsWith("http://")||locationurl.StartsWith("https://");if(!b){baseurl=newUri(newUri(ResponseUri),baseurl).AbsoluteUri;}}returnbaseurl;}}}catch{}returnstring.Empty;}}}///<summary>///返回类型///</summary>publicenumResultType{///<summary>///表示只返回字符串只有Html有数据///</summary>String,///<summary>///表示返回字符串和字节流ResultByte和Html都有数据返回///</summary>Byte}///<summary>///Post的数据格式默认为string///</summary>publicenumPostDataType{///<summary>///字符串类型,这时编码Encoding可不设置///</summary>String,///<summary>///Byte类型,需要设置PostdataByte参数的值编码Encoding可设置为空///</summary>Byte,///<summary>///传文件,Postdata必须设置为文件的绝对路径,必须设置Encoding的值///</summary>FilePath}///<summary>///Cookie返回类型///</summary>publicenumResultCookieType{///<summary>///只返回字符串类型的Cookie///</summary>String,///<summary>///CookieCollection格式的Cookie集合同时也返回String类型的cookie///</summary>CookieCollection}#endregion}