• C#实现HTTP访问类HttpHelper


    在项目开发过程中,我们经常会访问第三方接口,如我们需要接入的第三方接口是Web API,这时候我们就需要使用HttpHelper调用远程接口了。示例中的HttpHelper类使用Log4Net记录了每次调用的请求内容和响应内容的日志,并且每条日志都带上了链路ID和标识,这样方便我们在排查问题时能快速的找到当时的请求和响应内容,进而定位分析问题。大家在使用的时候如不需要记录日志,删除掉即可。

    HttpHelper类代码如下:

    public class HttpHelper : IDisposable
    {
    private bool _disposable = false;
    ///
    /// 请求编码格式默认utf-8;
    ///
    public Encoding HtmlEncoding = Encoding.UTF8;
    ///
    /// 请求时间
    ///
    public int Timeout = 5000;
    public CookieContainer Cookies = null;
    ///
    /// 是否记录Cookies
    ///
    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;
    }
    ///
    /// 上传图片
    ///
    ///
    ///
    ///
    ///
    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;
    }
    ///
    /// 基本请求方法
    ///
    /// HTTP请求类型
    /// 请求的URL
    /// 请求参数
    /// 链路ID,方便查询日志
    /// 请求标识,方便查询日志
    ///
    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; //总是接受
    }
    ///
    /// Get请求
    ///
    /// 请求地址
    /// 链路ID,方便查询日志
    /// 请求标识,方便查询日志
    ///
    public HttpRequestEntity Request(string url, string traceID, string markType)
    {
    return BaseRequest(RequestType.Get, url, string.Empty, traceID, markType);
    }
    ///
    /// Post请求
    ///
    /// 请求地址Url
    /// 请求内容参数
    /// 链路ID,方便查询日志
    /// 请求标识,方便查询日志
    ///
    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
    }
    ///
    /// HttpHelper请求方式
    ///
    public enum RequestType
    {
    ///
    /// Get请求
    ///
    Get,
    ///
    /// Post请求
    ///
    Post
    }
    ///
    /// HttpHelper请求时返回实体
    ///
    public class HttpRequestEntity
    {
    ///
    /// 请求是否成功 0-成功(返回Http状态码200) 1-失败(出现异常)
    ///
    public int IsSuccess { get; set; }
    ///
    /// 请求返回内容
    ///
    public string ResponseContent { get; set; }
    ///
    /// 请求返回内容长度
    ///
    public long ResponseLength { get; set; }
    ///
    /// 请求返回编码类型
    ///
    public string ResponseEncodingName { get; set; }
    }

    调用示例如下:

    HttpHelper helper = new HttpHelper();
    HttpRequestEntity response = helper.Request("需要访问的URL", "请求需要的参数", "访问链路ID", "访问标识");
    if (response.IsSuccess != 0)
    {
    //程序处理异常,请重试!
    }
    else
    {
    //请求响应成功
    }

     


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

  • 相关阅读:
    第六章 数字化工作方法与应用
    《YOLO医学影像检测》专栏介绍 & CSDN独家改进实战
    Springboot启动流程核心知识点(一):Spring自动装配原理
    RabbitMQ(四)【Docker安装&AMQP协议】
    Sql优化(详解一条龙服务)
    CPU+GPU掌舵AI大算力时代,中国企业能否从巨头碗中分一杯羹?
    报错解决: 未能解析此远程名称: ‘raw.githubusercontent.com‘
    深度学习课后week3 编程( 带有一个隐藏层的平面数据分类)
    【GoWeb框架初探————XORM篇】
    logback异步日志打印阻塞工作线程
  • 原文地址:https://www.cnblogs.com/huaxiaorui/p/16658624.html