在项目开发过程中,我们经常会访问第三方接口,如我们需要接入的第三方接口是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表示上一级的栈空间,依次类推
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
{
//请求响应成功
}

如对您有帮助劳烦帮忙点个赞,收藏关注一下,相互学习,共同进步。

C#实现HTTP访问类HttpHelper的更多相关文章

  1. DataAccess通用数据库访问类,简单易用,功能强悍

    以下是我编写的DataAccess通用数据库访问类,简单易用,支持:内联式创建多个参数.支持多事务提交.支持参数复用.支持更换数据库类型,希望能帮到大家,若需支持查出来后转换成实体,可以自行扩展dat ...

  2. 我也来写:数据库访问类DBHelper

    一.前言 相信许多人都百度过:“.net 数据库访问类”.然后就出来一大堆SqlHelper.我也用过这些SqlHelper,也自己写过,一堆静态方法,开始使用起来感觉很不错,它们也确实在很多时候可以 ...

  3. 类A have-a 类B,类B访问类A public 成员

    需求是类A中包含类B,而类B又需要访问类A的public属性的成员. 首先类B中要访问类A的属性,那么对于类B而言,我们必须要知道有类A这个类,所以在类B的具体实现之前我们需要前向声明类A. 对于类A ...

  4. C#-ade.net-实体类、数据访问类

    实体类.数据访问类 是由封装演变而来,使对数据的访问更便捷,使用时只需要调用即可,无需再次编写代码 实体类是按照数据库表的结构封装起来的一个类 首先,新建文件夹 App_Code ,用于存放数据库类等 ...

  5. 我也来写:数据库访问类DBHelper(转)

    一.前言 相信许多人都百度过:“.net 数据库访问类”.然后就出来一大堆SqlHelper.我也用过这些SqlHelper,也自己写过,一堆静态方法,开始使用起来感觉很不错,它们也确实在很多时候可以 ...

  6. ado.net 实体类_数据访问类

    实体类: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...

  7. 9_13学习完整修改和查询&&实体类,数据访问类

    完整修改和查询:中间变量运用. 1.先查 2.执行操作 ---------------------------------------------------- namespace ADO.NET_小 ...

  8. ADO.net 实体类 、数据访问类

    程序分三层:界面层.业务逻辑层.数据访问层 比较规范的写程序方法,要把业务逻辑层和数据访问层分开,此时需要创建实体类和数据访问类 实体类: 例 using System; using System.C ...

  9. ADO,NET 实体类 和 数据访问类

    啥也不说,看代码. --SQl中 --建立ren的数据库,插入一条信息 create database ren go use ren go create table xinxi ( code ) pr ...

随机推荐

  1. 3D还原货拉拉女孩身亡真相,这一环值得反思!

    货拉拉女孩跳车身亡的消息,让人惋惜又震惊.司机多次偏离原始路线,女孩最终选择跳车,结果不幸身亡. 货拉拉女孩跳车真相被3D还原 有人质疑平台监管不力,造成如此惨剧,有人吐槽企业压榨员工,司机绕路是不得 ...

  2. 搭建SVN服务器-腾讯云

    检查服务器SVN服务器 svn --version 出现版本号说明已安装 安装SVN yum install subversion 创建版本库 svnadmin create /opt/svn/rep ...

  3. WPF开发随笔收录-唯一标识符GUID

    一.前言 该系列博客用于记录本人在WPF开发过程中遇到的各种知识点 二.正文 1.在工作的项目中,软件需要用到在线升级功能,由于第一次弄,在下载服务端的文件到本地时,文件的名称我选择直接生成为固定的格 ...

  4. XXXX系统测试计划

    XXXX系统测试计划 目录 XXXX系统测试计划 目标 概述 项目背景 适用范围 组织形式 组织架构图 角色及职责 测试工作分工 团队协作 测试对象 应测试特性 不被测试特性 测试任务安排 系统测试任 ...

  5. 攻防世界MISC—进阶区1-10

    1.something_in_image zip中的文件用010 Editor打开后直接搜索flag,即可找到flag 2.wireshark-1 zip内是pcap文件,打开后根据题目知道要寻找登录 ...

  6. [ZJCTF 2019]NiZhuanSiWei 1

    考察知识点:反序列化.php伪协议 1.打开之后获得源码信息,如下: <?php $text = $_GET["text"]; $file = $_GET["fil ...

  7. 驳"一切不谈考核的管理都是扯淡"

    一.引子 以我个人的从业经验认为,研发人员的量化考核,始终是一个世界难题.正巧不久前在园子里看到了"一切不谈考核的管理都是扯淡!"一文(下面简称为"扯淡"),该 ...

  8. SpringBoot中Tomcat和SpringMVC整合源码分析

    概述 ​ SpringBoot中集成官方的第三方组件是通过在POM文件中添加组件的starter的Maven依赖来完成的.添加相关的Maven依赖之后,会引入具体的jar包,在SpringBoot启动 ...

  9. Mysql 数据恢复流程 基于binlog redolog undolog

    注:文中有个易混淆的地方 sql事务,即每次数据库操作生成的事务,这个事务trx_id只在undolog里存储,同时undolog维护了此事务是否完成的状态. 日志持久化事务,为了保证redolog和 ...

  10. @DS("slave") 多数据源兼容事务问题解决方案

    SpringBoot项目中用到多数据源,在方法上又必须加事务处理,此时可以对使用了@DS的方法或类添加@Transactional并添加事务隔离级别 举例: 1.这是一个方法,方法内需要实现多数据源查 ...