You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

878 lines
30 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Web;
using Newtonsoft.Json;
using System.Xml.Serialization;
namespace POSV.Helper
{
/// <summary>
/// Http操作类.
/// </summary>
public class HttpHelper
{
private const int ConnectionLimit = 100;
//编码
private Encoding _encoding = Encoding.UTF8;
//浏览器类型
private string[] _useragents = new string[]{
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)",
"Mozilla/5.0 (Windows NT 6.1; rv:36.0) Gecko/20100101 Firefox/36.0",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20130401 Firefox/31.0"
};
private String _useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36";
//接受类型
private String _accept = "text/html, application/xhtml+xml, application/xml, */*";
//超时时间
private int _timeout = 30 * 1000;
//类型
private string _contenttype = "application/x-www-form-urlencoded";
//cookies
private String _cookies = "";
//cookies
private CookieCollection _cookiecollection;
//custom heads
private Dictionary<string , string> _headers = new Dictionary<string , string>();
public HttpHelper()
{
_headers.Clear();
//随机一个useragent
_useragent = _useragents[new Random().Next(0 , _useragents.Length)];
//解决性能问题?
ServicePointManager.DefaultConnectionLimit = ConnectionLimit;
}
public void InitCookie()
{
_cookies = "";
_cookiecollection = null;
_headers.Clear();
}
/// <summary>
/// 设置当前编码
/// </summary>
/// <param name="en"></param>
public void SetEncoding(Encoding en)
{
_encoding = en;
}
/// <summary>
/// 设置UserAgent
/// </summary>
/// <param name="ua"></param>
public void SetUserAgent(String ua)
{
_useragent = ua;
}
public void RandUserAgent()
{
_useragent = _useragents[new Random().Next(0 , _useragents.Length)];
}
public void SetCookiesString(string c)
{
_cookies = c;
}
/// <summary>
/// 设置超时时间
/// </summary>
/// <param name="sec"></param>
public void SetTimeOut(int msec)
{
_timeout = msec;
}
public void SetContentType(String type)
{
_contenttype = type;
}
public void SetAccept(String accept)
{
_accept = accept;
}
/// <summary>
/// 添加自定义头
/// </summary>
/// <param name="key"></param>
/// <param name="ctx"></param>
public void AddHeader(String key , String ctx)
{
//_headers.Add(key,ctx);
_headers[key] = ctx;
}
/// <summary>
/// 清空自定义头
/// </summary>
public void ClearHeader()
{
_headers.Clear();
}
/// <summary>
/// 获取HTTP返回的内容
/// </summary>
/// <param name="response"></param>
/// <returns></returns>
private String GetStringFromResponse(HttpWebResponse response)
{
String html = "";
try
{
Stream stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream , _encoding);
html = sr.ReadToEnd();
sr.Close();
stream.Close();
}
catch (Exception e)
{
Trace.WriteLine("GetStringFromResponse Error: " + e.Message);
}
return html;
}
/// <summary>
/// 检测证书
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="errors"></param>
/// <returns></returns>
private bool CheckCertificate(object sender , X509Certificate certificate , X509Chain chain , SslPolicyErrors errors)
{
return true;
}
/// <summary>
/// 发送GET请求
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public String HttpGet(String url)
{
return HttpGet(url , url);
}
/// <summary>
/// 发送GET请求
/// </summary>
/// <param name="url"></param>
/// <param name="refer"></param>
/// <returns></returns>
public String HttpGet(String url , String refer)
{
String html;
try
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.UserAgent = _useragent;
request.Timeout = _timeout;
request.ContentType = _contenttype;
request.Accept = _accept;
request.Method = "GET";
request.Referer = refer;
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.UnsafeAuthenticatedConnectionSharing = true;
request.CookieContainer = new CookieContainer();
//据说能提高性能
request.Proxy = null;
if (_cookiecollection != null)
{
foreach (Cookie c in _cookiecollection)
{
c.Domain = request.Host;
}
request.CookieContainer.Add(_cookiecollection);
}
foreach (KeyValuePair<String , String> hd in _headers)
{
request.Headers[hd.Key] = hd.Value;
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
html = GetStringFromResponse(response);
if (request.CookieContainer != null)
{
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
}
if (response.Cookies != null)
{
_cookiecollection = response.Cookies;
}
if (response.Headers["Set-Cookie"] != null)
{
string tmpcookie = response.Headers["Set-Cookie"];
_cookiecollection.Add(ConvertCookieString(tmpcookie));
}
response.Close();
return html;
}
catch (Exception e)
{
Trace.WriteLine("HttpGet Error: " + e.Message);
return String.Empty;
}
}
/// <summary>
/// 获取MINE文件
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public Byte[] HttpGetMine(String url)
{
Byte[] mine = null;
try
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.UserAgent = _useragent;
request.Timeout = _timeout;
request.ContentType = _contenttype;
request.Accept = _accept;
request.Method = "GET";
request.Referer = url;
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.UnsafeAuthenticatedConnectionSharing = true;
request.CookieContainer = new CookieContainer();
//据说能提高性能
request.Proxy = null;
if (_cookiecollection != null)
{
foreach (Cookie c in _cookiecollection)
c.Domain = request.Host;
request.CookieContainer.Add(_cookiecollection);
}
foreach (KeyValuePair<String , String> hd in _headers)
{
request.Headers[hd.Key] = hd.Value;
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
MemoryStream ms = new MemoryStream();
byte[] b = new byte[1024];
while (true)
{
int s = stream.Read(b , 0 , b.Length);
ms.Write(b , 0 , s);
if (s == 0 || s < b.Length)
{
break;
}
}
mine = ms.ToArray();
ms.Close();
if (request.CookieContainer != null)
{
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
}
if (response.Cookies != null)
{
_cookiecollection = response.Cookies;
}
if (response.Headers["Set-Cookie"] != null)
{
_cookies = response.Headers["Set-Cookie"];
}
stream.Close();
stream.Dispose();
response.Close();
return mine;
}
catch (Exception e)
{
Trace.WriteLine("HttpGetMine Error: " + e.Message);
return null;
}
}
/// <summary>
/// 发送POST请求
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <returns></returns>
public String HttpPost(String url , String data , String cntentType = "")
{
return HttpPost(url , data , url, cntentType);
}
/// <summary>
/// 发送POST请求
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="refer"></param>
/// <returns></returns>
public String HttpPost(String url , String data , String refer,String cntentType = "")
{
String html;
try
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.UserAgent = _useragent;
request.Timeout = _timeout;
request.Referer = refer;
if (string.IsNullOrEmpty(_contenttype))
{
request.ContentType = _contenttype;
}
else
{
request.ContentType = cntentType;
}
request.Accept = _accept;
request.Method = "POST";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.CookieContainer = new CookieContainer();
//据说能提高性能
request.Proxy = null;
if (_cookiecollection != null)
{
foreach (Cookie c in _cookiecollection)
{
c.Domain = request.Host;
if (c.Domain.IndexOf(':') > 0)
c.Domain = c.Domain.Remove(c.Domain.IndexOf(':'));
}
request.CookieContainer.Add(_cookiecollection);
}
foreach (KeyValuePair<String , String> hd in _headers)
{
request.Headers[hd.Key] = hd.Value;
}
byte[] buffer = _encoding.GetBytes(data.Trim());
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer , 0 , buffer.Length);
request.GetRequestStream().Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
html = GetStringFromResponse(response);
if (request.CookieContainer != null)
{
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
}
if (response.Cookies != null)
{
_cookiecollection = response.Cookies;
}
if (response.Headers["Set-Cookie"] != null)
{
string tmpcookie = response.Headers["Set-Cookie"];
_cookiecollection.Add(ConvertCookieString(tmpcookie));
}
response.Close();
return html;
}
catch (Exception e)
{
Trace.WriteLine("HttpPost Error: " + e.Message);
return String.Empty;
}
}
public string UrlEncode(string str)
{
StringBuilder sb = new StringBuilder();
byte[] byStr = _encoding.GetBytes(str);
for (int i = 0; i < byStr.Length; i++)
{
sb.Append(@"%" + Convert.ToString(byStr[i] , 16));
}
return (sb.ToString());
}
/// <summary>
/// 转换cookie字符串到CookieCollection
/// </summary>
/// <param name="ck"></param>
/// <returns></returns>
private CookieCollection ConvertCookieString(string ck)
{
CookieCollection cc = new CookieCollection();
string[] cookiesarray = ck.Split(";".ToCharArray() , StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < cookiesarray.Length; i++)
{
string[] cookiesarray_2 = cookiesarray[i].Split(",".ToCharArray() , StringSplitOptions.RemoveEmptyEntries);
for (int j = 0; j < cookiesarray_2.Length; j++)
{
string[] cookiesarray_3 = cookiesarray_2[j].Trim().Split("=".ToCharArray());
if (cookiesarray_3.Length == 2)
{
string cname = cookiesarray_3[0].Trim();
string cvalue = cookiesarray_3[1].Trim();
if (cname.ToLower() != "domain" && cname.ToLower() != "path" && cname.ToLower() != "expires")
{
Cookie c = new Cookie(cname , cvalue);
cc.Add(c);
}
}
}
}
return cc;
}
public void DebugCookies()
{
Trace.WriteLine("**********************BEGIN COOKIES*************************");
foreach (Cookie c in _cookiecollection)
{
Trace.WriteLine(c.Name + "=" + c.Value);
Trace.WriteLine("Path=" + c.Path);
Trace.WriteLine("Domain=" + c.Domain);
}
Trace.WriteLine("**********************END COOKIES*************************");
}
#region http请求新方法
public static T PostJson<T>(string url, Dictionary<string, string> parameters, Encoding dataEncoding = null) where T : class, new()
{
try
{
var _data = Post(url, parameters, dataEncoding);
return JsonConvert.DeserializeObject<T>(_data);
}
catch (Exception ex)
{
return null;
}
}
public static T GetJson<T>(string url, Dictionary<string, string> parameters, Encoding dataEncoding = null) where T : class, new()
{
try
{
var _data = Get(url, parameters, dataEncoding);
return JsonConvert.DeserializeObject<T>(_data);
}
catch (Exception ex)
{
return null;
}
}
public static T PostXml<T>(string url, Dictionary<string, string> parameters, Encoding dataEncoding = null) where T : class, new()
{
try
{
var _data = Post(url, parameters, dataEncoding);
return DESerializer<T>(_data);
}
catch (Exception ex)
{
return null;
}
}
public static T GetXml<T>(string url, Dictionary<string, string> parameters, Encoding dataEncoding = null) where T : class, new()
{
try
{
var _data = Get(url, parameters, dataEncoding);
return DESerializer<T>(_data);
}
catch (Exception ex)
{
return null;
}
}
public static string Post(string url, Dictionary<string, string> parameters, Encoding dataEncoding = null)
{
Dictionary<string, string> headers = new Dictionary<string, string>();
if (dataEncoding == null)
{
dataEncoding = Encoding.UTF8;
}
using (var _data = HttpRequest("POST", url, null, parameters, dataEncoding, null))
{
using (var _readerGET = new System.IO.StreamReader(_data.GetResponseStream(), dataEncoding))
{
var respHTML = _readerGET.ReadToEnd();
return (respHTML);
};
};
}
public static string Post(string url, string parameters, Encoding dataEncoding = null)
{
Dictionary<string, string> headers = new Dictionary<string, string>();
if (dataEncoding == null)
{
dataEncoding = Encoding.UTF8;
}
HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
webrequest.Method = "post";
webrequest.Timeout = 20000;
byte[] postdatabyte = Encoding.UTF8.GetBytes(parameters);
webrequest.ContentLength = postdatabyte.Length;
Stream stream;
stream = webrequest.GetRequestStream();
stream.Write(postdatabyte, 0, postdatabyte.Length);
stream.Close();
using (var httpWebResponse = webrequest.GetResponse())
using (StreamReader responseStream = new StreamReader(httpWebResponse.GetResponseStream()))
{
String ret = responseStream.ReadToEnd();
return ret;
}
}
public static string Get(string url, Dictionary<string, string> parameters, Encoding dataEncoding = null)
{
Dictionary<string, string> headers = new Dictionary<string, string>();
if (dataEncoding == null)
{
dataEncoding = Encoding.UTF8;
}
using (var _data = HttpRequest("GET", url, null, parameters, dataEncoding, null))
{
using (var _readerGET = new System.IO.StreamReader(_data.GetResponseStream(), dataEncoding))
{
var respHTML = _readerGET.ReadToEnd();
return (respHTML);
};
};
}
#region 内部方法
/// <summary>
/// http/https请求响应
/// </summary>
/// <param name="getOrPost"></param>
/// <param name="url">地址要带上http或https</param>
/// <param name="headers">请求头</param>
/// <param name="parameters">提交数据</param>
/// <param name="dataEncoding">编码类型 utf-8</param>
/// <param name="contentType">application/x-www-form-urlencoded</param>
/// <returns></returns>
private static HttpWebResponse HttpRequest(string getOrPost, string url, Dictionary<string, string> headers, Dictionary<string, string> parameters, Encoding dataEncoding, string contentType)
{
try
{
var request = CreateRequest(getOrPost, url, headers, parameters, dataEncoding, contentType);
//如果需要POST数据
if (getOrPost == "POST" && !(parameters == null || parameters.Count == 0))
{
var data = FormatPostParameters(parameters, dataEncoding, contentType);
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
stream.Close();
}
}
WebResponse Res = null;
try
{
Res = request.GetResponse();
}
catch (WebException ex)
{
Res = (HttpWebResponse)ex.Response;
}
catch (Exception e)
{
throw e;
}
if (null == Res)
{
return request.GetResponse() as HttpWebResponse;
}
return (HttpWebResponse)Res;
}
catch(WebException ex)
{
throw ex;
}
}
/// <summary>
/// 创建HTTP请求对象
/// </summary>
/// <param name="getOrPost"></param>
/// <param name="url"></param>
/// <param name="headers"></param>
/// <param name="parameters"></param>
/// <param name="paraEncoding"></param>
/// <param name="contentType"></param>
/// <returns></returns>
private static HttpWebRequest CreateRequest(string getOrPost, string url, Dictionary<string, string> headers, Dictionary<string, string> parameters, Encoding paraEncoding, string contentType)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (parameters != null && parameters.Count > 0 && paraEncoding == null)
{
throw new ArgumentNullException("requestEncoding");
}
HttpWebRequest request = null;
//判断是否是https
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(CheckValidationResult);
request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version10;
}
else
{
request = WebRequest.Create(url) as HttpWebRequest;
}
if (getOrPost == "GET")
{
request.Method = "GET";
if (parameters != null && parameters.Count > 0)
{
url = FormatGetParametersToUrl(url, parameters, paraEncoding);
request = WebRequest.Create(url) as HttpWebRequest;
}
}
else
{
request.Method = "POST";
}
if (contentType == null)
{
}
else
{
request.ContentType = contentType;
}
//POST的数据大于1024字节的时候如果不设置会分两步
request.ServicePoint.Expect100Continue = false;
request.ServicePoint.ConnectionLimit = int.MaxValue;
if (headers != null)
{
FormatRequestHeaders(headers, request);
}
return request;
}
/// <summary>
/// 格式化请求头信息
/// </summary>
/// <param name="headers"></param>
/// <param name="request"></param>
private static void FormatRequestHeaders(Dictionary<string, string> headers, HttpWebRequest request)
{
foreach (var hd in headers)
{
//因为HttpWebRequest中很多标准标头都被封装成只能通过属性设置添加的话会抛出异常
switch (hd.Key.ToLower())
{
case "connection":
request.KeepAlive = false;
break;
case "content-type":
request.ContentType = hd.Value;
break;
case "transfer-enconding":
request.TransferEncoding = hd.Value;
break;
default:
request.Headers.Add(hd.Key, hd.Value);
break;
}
}
}
/// <summary>
/// 格式化Get请求参数
/// </summary>
/// <param name="url">URL</param>
/// <param name="parameters">参数</param>
/// <param name="paraEncoding">编码格式</param>
/// <returns></returns>
private static string FormatGetParametersToUrl(string url, Dictionary<string, string> parameters, Encoding paraEncoding)
{
if (url.IndexOf("?") < 0)
url += "?";
int i = 0;
string sendContext = "";
foreach (var parameter in parameters)
{
if (i > 0)
{
sendContext += "&";
}
sendContext += HttpUtility.UrlEncode(parameter.Key, paraEncoding)
+ "=" + HttpUtility.UrlEncode(parameter.Value, paraEncoding);
++i;
}
url += sendContext;
return url;
}
/// <summary>
/// 格式化Post请求参数
/// </summary>
/// <param name="parameters">编码格式</param>
/// <param name="dataEncoding">编码格式</param>
/// <param name="contentType">类型</param>
/// <returns></returns>
private static byte[] FormatPostParameters(Dictionary<string, string> parameters, Encoding dataEncoding, string contentType)
{
string sendContext = "";
int i = 0;
if (!string.IsNullOrEmpty(contentType) && contentType.ToLower().Trim() == "application/json")
{
sendContext = "{";
}
foreach (var para in parameters)
{
if (!string.IsNullOrEmpty(contentType) && contentType.ToLower().Trim() == "application/json")
{
if (i > 0)
{
if (para.Value.StartsWith("{"))
{
sendContext += string.Format(@",""{0}"":{1}", para.Key, para.Value);
}
else
{
sendContext += string.Format(@",""{0}"":""{1}""", para.Key, para.Value);
}
}
else
{
if (para.Value.StartsWith("{"))
{
sendContext += string.Format(@"""{0}"":{1}", para.Key, para.Value);
}
else
{
sendContext += string.Format(@"""{0}"":""{1}""", para.Key, para.Value);
}
}
}
else
{
if (i > 0)
{
sendContext += string.Format("&{0}={1}", para.Key, HttpUtility.UrlEncode(para.Value, dataEncoding));
}
else
{
sendContext = string.Format("{0}={1}", para.Key, HttpUtility.UrlEncode(para.Value, dataEncoding));
}
}
i++;
}
if (!string.IsNullOrEmpty(contentType) && contentType.ToLower().Trim() == "application/json")
{
sendContext += "}";
}
byte[] data = dataEncoding.GetBytes(sendContext);
return data;
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; //总是接受
}
/// <summary>
/// 反序列化
/// </summary>
private static T DESerializer<T>(string strXML) where T : class
{
try
{
using (StringReader sr = new StringReader(strXML))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return serializer.Deserialize(sr) as T;
}
}
catch (Exception ex)
{
return null;
}
}
#endregion
#endregion
}
}