HTTP 请求
前言
HTTP 请求的过程这里不再赘述,有兴趣的小伙伴可以自己搜索。
请求方式有Get和Post方式,Get即请求指定的页面信息,Post是向指定资源提交数据进行处理请求。
我们使用中会用到同步请求和异步请求,以下分别介绍。
1、同步请求
经常使用的一种http请求,请求后会直接得到结果,使用简单。但是请求连接无法访问的时候会卡死整个线进,体验很差。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
/// Http 同步请求
public class HttpSynRequest
{
/// <summary>
/// 获取URL数据
/// </summary>
public string Content { get; private set; }
/// <summary>
/// 请求错误
/// </summary>
public string ErrorMsg { get; private set; }
/// <summary>
/// url 请求地址
/// </summary>
private string urlRequest;
/// <summary>
/// 重试次数
/// </summary>
private int tryTimesLimit;
/// <summary>
/// http请求方法 get post
/// </summary>
private string methodRequest;
/// <summary>
/// http请求参数
/// </summary>
private string dataRequest;
/// <summary>
/// HttpWebRequest
/// </summary>
private HttpWebRequest webRequest;
/// <summary>
/// HttpWebRequest
/// </summary>
private HttpWebResponse webResponse;
/// <summary>
/// 构造函数
/// </summary>
public HttpSynRequest(string url, string method, string param = "", int times = 0)
{
urlRequest = url;
methodRequest = method;
tryTimesLimit = times;
dataRequest = param;
}
/// <summary>
/// 开始请求
/// </summary>
public void Start()
{
if (string.IsNullOrEmpty(urlRequest))
{
ErrorMsg = "url is empty";
return;
}
HttpMethodRequest();
}
/// <summary>
/// http 请求方式
/// </summary>
private void HttpMethodRequest()
{
if (methodRequest.CompareTo("Post") == 0)
HttpRequestPost();
else
HttpRequestGet();
}
/// <summary>
/// 创建WebRequest
/// </summary>
public HttpWebRequest CreateRequest(string url)
{
//https,并且设置了SSL,我们在访问程序时可能远程证书无效
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version11;
return request;
}
else
{
return (HttpWebRequest)HttpWebRequest.Create(url);
}
}
/// <summary>
/// 创建WebRequest
/// </summary>
private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
/// <summary>
/// 通过远程证书验证,总是返回true
/// </summary>
private void HttpRequestGet()
{
try
{
string url = urlRequest;
if (!string.IsNullOrEmpty(dataRequest))
url = string.Format("{0}?p={1}", urlRequest, dataRequest);
webRequest = CreateRequest(url);
webResponse = (HttpWebResponse)webRequest.GetResponse();
using (var s = webResponse.GetResponseStream())
{
StreamReader sr = new StreamReader(s);
Content = sr.ReadToEnd();
sr.Close();
s.Close();
}
ErrorMsg = string.Empty;
}
catch (System.Exception ex)
{
ErrorMsg = ex.Message;
}
finally
{
Abort();
}
TrtRequestAgain();
}
/// <summary>
/// http post 请求
/// </summary>
private void HttpRequestPost()
{
string md5 = GetMd5(dataRequest);
dataRequest += "&sign=" + md5;
try
{
HttpWebRequest request = CreateRequest(urlRequest);
request = WebRequest.Create(urlRequest) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] data = Encoding.UTF8.GetBytes(dataRequest);
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
webResponse = request.GetResponse() as HttpWebResponse;
using (var s = webResponse.GetResponseStream())
{
StreamReader sr = new StreamReader(s);
Content = sr.ReadToEnd();
sr.Close();
s.Close();
}
ErrorMsg = string.Empty;
}
catch (System.Exception ex)
{
ErrorMsg = ex.Message;
}
finally
{
Abort();
}
TrtRequestAgain();
}
/// <summary>
/// 终止
/// </summary>
private void Abort()
{
if (webResponse != null)
{
webResponse.Close();
webResponse = null;
}
if (webRequest != null)
{
webRequest.Abort();
webRequest = null;
}
}
/// <summary>
/// http请求如果失败,再次尝试
/// </summary>
private void TrtRequestAgain()
{
if (string.IsNullOrEmpty(ErrorMsg))
{
return;
}
if (tryTimesLimit > 0)
{
tryTimesLimit--;
HttpMethodRequest();
}
}
/// <summary>
/// 获得MD5
/// </summary>
private string GetMd5(string input)
{
MD5 md5Hash = MD5.Create();
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
}
调用示例
HttpSynRequest request = new HttpSynRequest("https://www.baidu.com/", "Get");//Get方式
request.Start();
string err = request.ErrorMsg;
string content = request.Content;
2、异步请求
异步请求会单独开一个线程进行http请求,不会影响主线程运行,但是不能实时拿到结果,需要监听请求的完成。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
/// Http 异步请求
public class HttpAsynRequest
{
/// <summary>
/// 是否完成
/// </summary>
public bool IsDone { get; private set; }
/// <summary>
/// 获取URL数据
/// </summary>
public string Content { get; private set; }
/// <summary>
/// 请求错误
/// </summary>
public string ErrorMsg { get; private set; }
/// <summary>
/// url 请求地址
/// </summary>
private string urlRequest;
/// <summary>
/// 重试次数
/// </summary>
private int tryTimesLimit;
/// <summary>
/// http请求方法 get post
/// </summary>
private string methodRequest;
/// <summary>
/// http请求参数
/// </summary>
private string dataRequest;
/// <summary>
/// HttpWebRequest
/// </summary>
private HttpWebRequest webRequest;
/// <summary>
/// HttpWebRequest
/// </summary>
private HttpWebResponse webResponse;
/// <summary>
/// 异步获取
/// </summary>
private Thread thread_;
/// <summary>
/// 构造函数
/// </summary>
public HttpAsynRequest(string url, string method, string param = "", int times = 0)
{
IsDone = false;
urlRequest = url;
methodRequest = method;
tryTimesLimit = times;
dataRequest = param;
}
/// <summary>
/// 开始校验
/// </summary>
public void Start()
{
if (string.IsNullOrEmpty(urlRequest))
{
ErrorMsg = "url is empty";
return;
}
thread_ = new Thread(new ThreadStart(HttpMethodRequest));
thread_.Start();
}
/// <summary>
/// http 请求方式
/// </summary>
private void HttpMethodRequest()
{
if (methodRequest.CompareTo("Post") == 0)
HttpRequestPost();
else
HttpRequestGet();
}
/// <summary>
/// 创建WebRequest
/// </summary>
public HttpWebRequest CreateRequest(string url)
{
//https,并且设置了SSL,我们在访问程序时可能远程证书无效
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version11;
return request;
}
else
{
return (HttpWebRequest)HttpWebRequest.Create(url);
}
}
/// <summary>
/// 创建WebRequest
/// </summary>
private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
/// <summary>
/// http get 请求
/// </summary>
private void HttpRequestGet()
{
try
{
string url = urlRequest;
if (!string.IsNullOrEmpty(dataRequest))
url = string.Format("{0}?p={1}", urlRequest, dataRequest);
webRequest = CreateRequest(url);
webResponse = (HttpWebResponse)webRequest.GetResponse();
using (var s = webResponse.GetResponseStream())
{
StreamReader sr = new StreamReader(s);
Content = sr.ReadToEnd();
sr.Close();
s.Close();
}
ErrorMsg = string.Empty;
}
catch (System.Exception ex)
{
ErrorMsg = ex.Message;
}
finally
{
Abort();
}
TrtRequestAgain();
}
/// <summary>
/// http post 请求
/// </summary>
private void HttpRequestPost()
{
string md5 = GetMd5(dataRequest);
dataRequest += "&sign=" + md5;
try
{
HttpWebRequest request = CreateRequest(urlRequest);
request = WebRequest.Create(urlRequest) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] data = Encoding.UTF8.GetBytes(dataRequest);
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
webResponse = request.GetResponse() as HttpWebResponse;
using (var s = webResponse.GetResponseStream())
{
StreamReader sr = new StreamReader(s);
Content = sr.ReadToEnd();
sr.Close();
s.Close();
}
ErrorMsg = string.Empty;
}
catch (System.Exception ex)
{
ErrorMsg = ex.Message;
}
finally
{
Abort();
}
TrtRequestAgain();
}
/// <summary>
/// 终止
/// </summary>
public void Abort()
{
if (webResponse != null)
{
webResponse.Close();
webResponse = null;
}
if (webRequest != null)
{
webRequest.Abort();
webRequest = null;
}
}
/// <summary>
/// http请求如果失败,再次尝试
/// </summary>
private void TrtRequestAgain()
{
if (string.IsNullOrEmpty(ErrorMsg))
{
IsDone = true;
return;
}
if (tryTimesLimit > 0)
{
tryTimesLimit--;
HttpMethodRequest();
}
else
IsDone = true;
}
/// <summary>
/// 获得MD5
/// </summary>
private string GetMd5(string input)
{
MD5 md5Hash = MD5.Create();
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
}
获得请求结果常用的两种方式:
- 在请求类中创建一个协成检测IsDone是否完成,完成后获得结果
- HttpAsynRequest类中添加回调函数,完成回调。注意调用回调函数时,最好在主线程,否者有些操作不能放在回调里。