很多时候在进行Http Get请求的时候,需要将对象序列化为请求字符串。为此写了一个工具类,通过反射,可以方便的把对象的属性转化为请求字符串。
/// <summary>
/// 对象编码为请求字符串
/// </summary>
/// <param name="obj">待编码对象</param>
/// <param name="url">请求URL</param>
/// <param name="isAddParaMark">是否添加?</param>
/// <param name="removeItems">要移除对象中的公共对象</param>
/// <returns></returns>
internal static string Encode(object obj, string url = "", bool isAddParaMark = false, params string[] removeItems)
{
if (!string.IsNullOrEmpty(url))
{
isAddParaMark = true;
}
List<PropertyInfo> propertis = obj.GetType().GetProperties().ToList();
if (removeItems.Length > 0)
{
List<PropertyInfo> removeList = new List<PropertyInfo>();
foreach (var item in removeItems)
{
foreach (var property in propertis)
{
if (property.Name == item)
{
removeList.Add(property);
}
}
}
if (removeList.Count > 0)
{
foreach (var item in removeList)
{
propertis.Remove(item);
}
}
}
propertis = propertis.OrderBy(p => p.Name).ToList(); //对参数进行升序排序
StringBuilder sb = new StringBuilder();
sb.Append(url);
if (isAddParaMark)
{
sb.Append("?");
}
foreach (var p in propertis)
{
var v = p.GetValue(obj, null);
if (v == null)
{
continue;
}
sb.Append(p.Name);
sb.Append("=");
sb.Append(WebUtility.UrlEncode(v.ToString()));
sb.Append("&");
}
sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
顺便记录一下使用的HTTP请求类,来源于Github。
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;
/*
* Created by SharpDevelop.
* Modified by Geeiot.
* User: RedXu
* Date: 2015-04-16
* Time: 13:58
*
*/
namespace AliyunDnsSDK.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)
{
throw new Exception("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)
{
throw new Exception("HttpGet Error: " + e.Message);
}
}
/// <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)
{
throw new Exception("HttpGetMine Error: " + e.Message);
}
}
/// <summary>
/// 发送POST请求
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <returns></returns>
public String HttpPost(String url, String data)
{
return HttpPost(url, data, url);
}
/// <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 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;
request.ContentType = _contenttype;
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)
{
throw new Exception("HttpPost Error: " + e.Message);
}
}
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()
{
Console.WriteLine("**********************BEGIN COOKIES*************************");
foreach (Cookie c in _cookiecollection)
{
throw new Exception(c.Name + "=" + c.Value);
throw new Exception("Path=" + c.Path);
throw new Exception("Domain=" + c.Domain);
}
Console.WriteLine("**********************END COOKIES*************************");
}
}
}
文章评论