項目開發過程中,我們經常會訪問第三方接口,如我們需要接入的第三方接口是Web API,這時候我們就需要使用HttpHelper調用遠程接口了。示例中的HttpHelper類使用Log4Net記錄了每次調用的請求內容和響應內容的日志,并且每條日志都帶上了鏈路ID和標識,這樣方便我們在排查問題時能快速的找到當時的請求和響應內容,進而定位分析問題。大家在使用的時候如不需要記錄日志,刪除掉即可。
HttpHelper類代碼如下:
public class HttpHelper : IDisposable
{
private bool _disposable=false;
/// <summary>
/// 請求編碼格式默認utf-8;
/// </summary>
public Encoding HtmlEncoding=Encoding.UTF8;
/// <summary>
/// 請求時間
/// </summary>
public int Timeout=5000;
public CookieContainer Cookies=null;
/// <summary>
/// 是否記錄Cookies
/// </summary>
public bool IsRecordCookie=false;
public string ContentType="application/x-www-form-urlencoded";
public string AcceptLanguage="en-US, en; q=0.8, zh-Hans-CN; q=0.5, zh-Hans; q=0.3";
public string KeepAlive="Keep-Alive";
public string Accept="*/*";
private const string UserAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240";
private static ILogger Logger=Log4NetLoggerFactory.Instance.Create("remote.info");
public HttpHelper()
{
//允許最大連接數,突破Http協議的并發連接數限制
ServicePointManager.DefaultConnectionLimit=512;
}
/// <summary>
/// 上傳圖片
/// </summary>
/// <param name="url"></param>
/// <param name="bArr"></param>
/// <param name="fileName"></param>
/// <returns></returns>
public HttpRequestEntity RequestFile(string url, byte[] bArr, string fileName="")
{
var result=new HttpRequestEntity { IsSuccess=0 };
//后續需要再放開,啟用時需增加日志收集
//if (string.IsNullOrEmpty(url))
// throw new ArgumentNullException("請求Url不能為空值");
//if (bArr==null || bArr.Length <=0)
// throw new AccessViolationException("缺少輸入數據");
//Stream requestStream=null;
//StreamReader streamReader=null;
//HttpWebResponse response=null;
//HttpWebRequest request=null;
//try
//{
// request=WebRequest.Create(url) as HttpWebRequest;
// request.AllowAutoRedirect=true;
// request.Method="POST";
// string boundary=DateTime.Now.Ticks.ToString("X"); // 隨機分隔線
// request.ContentType="multipart/form-data;charset=utf-8;boundary=" + boundary;
// byte[] itemBoundaryBytes=Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
// byte[] endBoundaryBytes=Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
// if (string.IsNullOrEmpty(fileName))
// fileName=DateTime.Now.ToString("yyyyMMddHHmmss");
// //請求頭部信息
// StringBuilder sbHeader=new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
// byte[] postHeaderBytes=Encoding.UTF8.GetBytes(sbHeader.ToString());
// request.Headers.Add("auth", fileName);
// Stream postStream=request.GetRequestStream();
// postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
// postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
// postStream.Write(bArr, 0, bArr.Length);
// postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
// postStream.Close();
// response=request.GetResponse() as HttpWebResponse;
// requestStream=response.GetResponseStream();
// if (response.StatusCode==HttpStatusCode.OK)
// {
// result.IsSuccess=0;
// if (requestStream !=null)
// {
// streamReader=new StreamReader(requestStream, HtmlEncoding);
// result.ResponseContent=streamReader.ReadToEnd();
// }
// }
//}
//catch (Exception ex)
//{
// result.IsSuccess=1;
// result.ResponseContent=ex.Message;
//}
//finally
//{
// if (requestStream !=null)
// {
// requestStream.Close();
// requestStream.Dispose();
// }
// if (streamReader !=null)
// {
// streamReader.Close();
// streamReader.Dispose();
// }
// request.Abort();
// if (response !=null)
// response.Close();
//}
return result;
}
/// <summary>
/// 基本請求方法
/// </summary>
/// <param name="requestType">HTTP請求類型</param>
/// <param name="url">請求的URL</param>
/// <param name="requestData">請求參數</param>
/// <param name="traceID">鏈路ID,方便查詢日志</param>
/// <param name="markType">請求標識,方便查詢日志</param>
/// <returns></returns>
private HttpRequestEntity BaseRequest(RequestType requestType, string url, string requestData, string traceID,string markType)
{
var result=new HttpRequestEntity { IsSuccess=0 };
if (string.IsNullOrEmpty(url))
throw new ArgumentNullException("請求Url不能為空值");
Stopwatch stopwatch=new Stopwatch();
stopwatch.Start();
Dictionary<string, object> resultLog=new Dictionary<string, object>();//log對象
resultLog.Add("logType", "remote");
resultLog.Add("traceID", traceID);
resultLog.Add("localIp", IpHelper.LocalIp);
resultLog.Add("markType", markType);
resultLog.Add("url", url);
resultLog.Add("requestContent", HttpUtility.UrlDecode(requestData, Encoding.UTF8));
resultLog.Add("createTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
StackTrace ss=new StackTrace(true);
System.Reflection.MethodBase mb=ss.GetFrame(2).GetMethod();//0表示當前棧空間,1表示上一級的??臻g,依次類推
resultLog.Add("className", mb.DeclaringType.FullName);
resultLog.Add("methodName", mb.Name);
HttpStatusCode statusCode=HttpStatusCode.OK;
if (IsRecordCookie)
Cookies=new CookieContainer();
Stream requestStream=null;
StreamReader streamReader=null;
HttpWebRequest webRe=null;
HttpWebResponse webPos=null;
try
{
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback=new RemoteCertificateValidationCallback(CheckValidationResult);
webRe=WebRequest.Create(url) as HttpWebRequest;
webRe.ProtocolVersion=HttpVersion.Version10;
}
else
{
webRe=(HttpWebRequest)WebRequest.Create(url);
}
webRe.Headers.Add("Accept-Language", AcceptLanguage);
webRe.Headers.Add("Keep-Alive", KeepAlive);
webRe.UserAgent=UserAgent;
webRe.Accept=Accept;
webRe.Timeout=Timeout;
webRe.ReadWriteTimeout=Timeout;
webRe.CookieContainer=Cookies;
if (requestType==RequestType.Post)
{
webRe.ContentType=string.Format("{0}; {1}", ContentType, HtmlEncoding.BodyName);
byte[] datas=HtmlEncoding.GetBytes(requestData);
webRe.Method="POST";
webRe.ContentLength=datas.Length;
webRe.MaximumResponseHeadersLength=-1;
requestStream=webRe.GetRequestStream();
requestStream.Write(datas, 0, datas.Length);
requestStream.Flush();
requestStream.Close();
}
else
webRe.Method="GET";
webPos=(HttpWebResponse)webRe.GetResponse();
resultLog.Add("requestType", webRe.Method);
statusCode=webPos.StatusCode;
result.ResponseLength=webPos.ContentLength;
result.ResponseEncodingName=webPos.ContentEncoding;
requestStream=webPos.GetResponseStream();
if (webPos.StatusCode==HttpStatusCode.OK)
{
result.IsSuccess=0;
if (requestStream !=null)
{
streamReader=new StreamReader(requestStream, HtmlEncoding);
result.ResponseContent=streamReader.ReadToEnd();
}
}
}
catch (Exception ex)
{
result.IsSuccess=1;
result.ResponseContent=ex.Message;
}
finally
{
if (requestStream !=null)
{
requestStream.Close();
requestStream.Dispose();
}
if (streamReader !=null)
{
streamReader.Close();
streamReader.Dispose();
}
webRe.Abort();
if (webPos !=null)
webPos.Close();
}
if (result.IsSuccess==1)
{
resultLog.Add("status", HttpStatusCode.InternalServerError);
resultLog.Add("success", false);
resultLog.Add("responseContent", result.ResponseContent);
stopwatch.Stop();
resultLog.Add("elapseTime", stopwatch.Elapsed.TotalMilliseconds);
string log=JsonConvert.SerializeObject(resultLog);
Logger.Info(log);
Logger.Error(log);
}
else
{
resultLog.Add("status", statusCode);
resultLog.Add("success", true);
resultLog.Add("responseContent", result.ResponseContent);
stopwatch.Stop();
resultLog.Add("elapseTime", stopwatch.Elapsed.TotalMilliseconds);
string log=JsonConvert.SerializeObject(resultLog);
Logger.Info(log);
}
return result;
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; //總是接受
}
/// <summary>
/// Get請求
/// </summary>
/// <param name="url">請求地址</param>
/// <param name="traceID">鏈路ID,方便查詢日志</param>
/// <param name="markType">請求標識,方便查詢日志</param>
/// <returns></returns>
public HttpRequestEntity Request(string url, string traceID, string markType)
{
return BaseRequest(RequestType.Get, url, string.Empty, traceID, markType);
}
/// <summary>
/// Post請求
/// </summary>
/// <param name="url">請求地址Url</param>
/// <param name="requestData">請求內容參數</param>
/// <param name="traceID">鏈路ID,方便查詢日志</param>
/// <param name="markType">請求標識,方便查詢日志</param>
/// <returns></returns>
public HttpRequestEntity Request(string url, string requestData, string traceID, string markType)
{
return BaseRequest(RequestType.Post, url, requestData, traceID, markType);
}
~HttpHelper()
{
Dispose(false);
}
#region IDisposable 成員
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this._disposable)
return;
if (disposing)
{
}
_disposable=true;
}
#endregion
}
/// <summary>
/// HttpHelper請求方式
/// </summary>
public enum RequestType
{
/// <summary>
/// Get請求
/// </summary>
Get,
/// <summary>
/// Post請求
/// </summary>
Post
}
/// <summary>
/// HttpHelper請求時返回實體
/// </summary>
public class HttpRequestEntity
{
/// <summary>
/// 請求是否成功 0-成功(返回Http狀態碼200) 1-失敗(出現異常)
/// </summary>
public int IsSuccess { get; set; }
/// <summary>
/// 請求返回內容
/// </summary>
public string ResponseContent { get; set; }
/// <summary>
/// 請求返回內容長度
/// </summary>
public long ResponseLength { get; set; }
/// <summary>
/// 請求返回編碼類型
/// </summary>
public string ResponseEncodingName { get; set; }
}
調用示例如下:
HttpHelper helper=new HttpHelper();
HttpRequestEntity response=helper.Request("需要訪問的URL", "請求需要的參數", "訪問鏈路ID", "訪問標識");
if (response.IsSuccess !=0)
{
//程序處理異常,請重試!
}
else
{
//請求響應成功
}
如對您有幫助勞煩幫忙點個贊,收藏關注一下,相互學習,共同進步。
在項目開發過程中,我們經常會訪問第三方接口,如我們需要接入的第三方接口是Web API,這時候我們就需要使用HttpHelper調用遠程接口了。示例中的HttpHelper類使用Log4Net記錄了每次調用的請求內容和響應內容的日志,并且每條日志都帶上了鏈路ID和標識,這樣方便我們在排查問題時能快速的找到當時的請求和響應內容,進而定位分析問題。大家在使用的時候如不需要記錄日志,刪除掉即可。
HttpHelper類代碼如下:
public class HttpHelper : IDisposable
{
private bool _disposable=false;
/// <summary>
/// 請求編碼格式默認utf-8;
/// </summary>
public Encoding HtmlEncoding=Encoding.UTF8;
/// <summary>
/// 請求時間
/// </summary>
public int Timeout=5000;
public CookieContainer Cookies=null;
/// <summary>
/// 是否記錄Cookies
/// </summary>
public bool IsRecordCookie=false;
public string ContentType="application/x-www-form-urlencoded";
public string AcceptLanguage="en-US, en; q=0.8, zh-Hans-CN; q=0.5, zh-Hans; q=0.3";
public string KeepAlive="Keep-Alive";
public string Accept="*/*";
private const string UserAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240";
private static ILogger Logger=Log4NetLoggerFactory.Instance.Create("remote.info");
public HttpHelper()
{
//允許最大連接數,突破Http協議的并發連接數限制
ServicePointManager.DefaultConnectionLimit=512;
}
/// <summary>
/// 上傳圖片
/// </summary>
/// <param name="url"></param>
/// <param name="bArr"></param>
/// <param name="fileName"></param>
/// <returns></returns>
public HttpRequestEntity RequestFile(string url, byte[] bArr, string fileName="")
{
var result=new HttpRequestEntity { IsSuccess=0 };
//后續需要再放開,啟用時需增加日志收集
//if (string.IsNullOrEmpty(url))
// throw new ArgumentNullException("請求Url不能為空值");
//if (bArr==null || bArr.Length <=0)
// throw new AccessViolationException("缺少輸入數據");
//Stream requestStream=null;
//StreamReader streamReader=null;
//HttpWebResponse response=null;
//HttpWebRequest request=null;
//try
//{
// request=WebRequest.Create(url) as HttpWebRequest;
// request.AllowAutoRedirect=true;
// request.Method="POST";
// string boundary=DateTime.Now.Ticks.ToString("X"); // 隨機分隔線
// request.ContentType="multipart/form-data;charset=utf-8;boundary=" + boundary;
// byte[] itemBoundaryBytes=Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
// byte[] endBoundaryBytes=Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
// if (string.IsNullOrEmpty(fileName))
// fileName=DateTime.Now.ToString("yyyyMMddHHmmss");
// //請求頭部信息
// StringBuilder sbHeader=new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
// byte[] postHeaderBytes=Encoding.UTF8.GetBytes(sbHeader.ToString());
// request.Headers.Add("auth", fileName);
// Stream postStream=request.GetRequestStream();
// postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
// postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
// postStream.Write(bArr, 0, bArr.Length);
// postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
// postStream.Close();
// response=request.GetResponse() as HttpWebResponse;
// requestStream=response.GetResponseStream();
// if (response.StatusCode==HttpStatusCode.OK)
// {
// result.IsSuccess=0;
// if (requestStream !=null)
// {
// streamReader=new StreamReader(requestStream, HtmlEncoding);
// result.ResponseContent=streamReader.ReadToEnd();
// }
// }
//}
//catch (Exception ex)
//{
// result.IsSuccess=1;
// result.ResponseContent=ex.Message;
//}
//finally
//{
// if (requestStream !=null)
// {
// requestStream.Close();
// requestStream.Dispose();
// }
// if (streamReader !=null)
// {
// streamReader.Close();
// streamReader.Dispose();
// }
// request.Abort();
// if (response !=null)
// response.Close();
//}
return result;
}
/// <summary>
/// 基本請求方法
/// </summary>
/// <param name="requestType">HTTP請求類型</param>
/// <param name="url">請求的URL</param>
/// <param name="requestData">請求參數</param>
/// <param name="traceID">鏈路ID,方便查詢日志</param>
/// <param name="markType">請求標識,方便查詢日志</param>
/// <returns></returns>
private HttpRequestEntity BaseRequest(RequestType requestType, string url, string requestData, string traceID,string markType)
{
var result=new HttpRequestEntity { IsSuccess=0 };
if (string.IsNullOrEmpty(url))
throw new ArgumentNullException("請求Url不能為空值");
Stopwatch stopwatch=new Stopwatch();
stopwatch.Start();
Dictionary<string, object> resultLog=new Dictionary<string, object>();//log對象
resultLog.Add("logType", "remote");
resultLog.Add("traceID", traceID);
resultLog.Add("localIp", IpHelper.LocalIp);
resultLog.Add("markType", markType);
resultLog.Add("url", url);
resultLog.Add("requestContent", HttpUtility.UrlDecode(requestData, Encoding.UTF8));
resultLog.Add("createTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
StackTrace ss=new StackTrace(true);
System.Reflection.MethodBase mb=ss.GetFrame(2).GetMethod();//0表示當前??臻g,1表示上一級的??臻g,依次類推
resultLog.Add("className", mb.DeclaringType.FullName);
resultLog.Add("methodName", mb.Name);
HttpStatusCode statusCode=HttpStatusCode.OK;
if (IsRecordCookie)
Cookies=new CookieContainer();
Stream requestStream=null;
StreamReader streamReader=null;
HttpWebRequest webRe=null;
HttpWebResponse webPos=null;
try
{
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback=new RemoteCertificateValidationCallback(CheckValidationResult);
webRe=WebRequest.Create(url) as HttpWebRequest;
webRe.ProtocolVersion=HttpVersion.Version10;
}
else
{
webRe=(HttpWebRequest)WebRequest.Create(url);
}
webRe.Headers.Add("Accept-Language", AcceptLanguage);
webRe.Headers.Add("Keep-Alive", KeepAlive);
webRe.UserAgent=UserAgent;
webRe.Accept=Accept;
webRe.Timeout=Timeout;
webRe.ReadWriteTimeout=Timeout;
webRe.CookieContainer=Cookies;
if (requestType==RequestType.Post)
{
webRe.ContentType=string.Format("{0}; {1}", ContentType, HtmlEncoding.BodyName);
byte[] datas=HtmlEncoding.GetBytes(requestData);
webRe.Method="POST";
webRe.ContentLength=datas.Length;
webRe.MaximumResponseHeadersLength=-1;
requestStream=webRe.GetRequestStream();
requestStream.Write(datas, 0, datas.Length);
requestStream.Flush();
requestStream.Close();
}
else
webRe.Method="GET";
webPos=(HttpWebResponse)webRe.GetResponse();
resultLog.Add("requestType", webRe.Method);
statusCode=webPos.StatusCode;
result.ResponseLength=webPos.ContentLength;
result.ResponseEncodingName=webPos.ContentEncoding;
requestStream=webPos.GetResponseStream();
if (webPos.StatusCode==HttpStatusCode.OK)
{
result.IsSuccess=0;
if (requestStream !=null)
{
streamReader=new StreamReader(requestStream, HtmlEncoding);
result.ResponseContent=streamReader.ReadToEnd();
}
}
}
catch (Exception ex)
{
result.IsSuccess=1;
result.ResponseContent=ex.Message;
}
finally
{
if (requestStream !=null)
{
requestStream.Close();
requestStream.Dispose();
}
if (streamReader !=null)
{
streamReader.Close();
streamReader.Dispose();
}
webRe.Abort();
if (webPos !=null)
webPos.Close();
}
if (result.IsSuccess==1)
{
resultLog.Add("status", HttpStatusCode.InternalServerError);
resultLog.Add("success", false);
resultLog.Add("responseContent", result.ResponseContent);
stopwatch.Stop();
resultLog.Add("elapseTime", stopwatch.Elapsed.TotalMilliseconds);
string log=JsonConvert.SerializeObject(resultLog);
Logger.Info(log);
Logger.Error(log);
}
else
{
resultLog.Add("status", statusCode);
resultLog.Add("success", true);
resultLog.Add("responseContent", result.ResponseContent);
stopwatch.Stop();
resultLog.Add("elapseTime", stopwatch.Elapsed.TotalMilliseconds);
string log=JsonConvert.SerializeObject(resultLog);
Logger.Info(log);
}
return result;
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; //總是接受
}
/// <summary>
/// Get請求
/// </summary>
/// <param name="url">請求地址</param>
/// <param name="traceID">鏈路ID,方便查詢日志</param>
/// <param name="markType">請求標識,方便查詢日志</param>
/// <returns></returns>
public HttpRequestEntity Request(string url, string traceID, string markType)
{
return BaseRequest(RequestType.Get, url, string.Empty, traceID, markType);
}
/// <summary>
/// Post請求
/// </summary>
/// <param name="url">請求地址Url</param>
/// <param name="requestData">請求內容參數</param>
/// <param name="traceID">鏈路ID,方便查詢日志</param>
/// <param name="markType">請求標識,方便查詢日志</param>
/// <returns></returns>
public HttpRequestEntity Request(string url, string requestData, string traceID, string markType)
{
return BaseRequest(RequestType.Post, url, requestData, traceID, markType);
}
~HttpHelper()
{
Dispose(false);
}
#region IDisposable 成員
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (this._disposable)
return;
if (disposing)
{
}
_disposable=true;
}
#endregion
}
/// <summary>
/// HttpHelper請求方式
/// </summary>
public enum RequestType
{
/// <summary>
/// Get請求
/// </summary>
Get,
/// <summary>
/// Post請求
/// </summary>
Post
}
/// <summary>
/// HttpHelper請求時返回實體
/// </summary>
public class HttpRequestEntity
{
/// <summary>
/// 請求是否成功 0-成功(返回Http狀態碼200) 1-失敗(出現異常)
/// </summary>
public int IsSuccess { get; set; }
/// <summary>
/// 請求返回內容
/// </summary>
public string ResponseContent { get; set; }
/// <summary>
/// 請求返回內容長度
/// </summary>
public long ResponseLength { get; set; }
/// <summary>
/// 請求返回編碼類型
/// </summary>
public string ResponseEncodingName { get; set; }
}
調用示例如下:
HttpHelper helper=new HttpHelper();
HttpRequestEntity response=helper.Request("需要訪問的URL", "請求需要的參數", "訪問鏈路ID", "訪問標識");
if (response.IsSuccess !=0)
{
//程序處理異常,請重試!
}
else
{
//請求響應成功
}
如對您有幫助勞煩幫忙點個贊,收藏關注一下,相互學習,共同進步。