C#实现HTTP访问类HttpHelper的示例详解

在项目开发过程中,我们经常会访问第三方接口,如我们需要接入的第三方接口是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的示例详解的文章就介绍至此,更多相关C# HTTP访问类HttpHelper内容请搜索编程宝库以前的文章,希望以后支持编程宝库

 场景现在90%的管理系统都是在用上左右这种布局方式,真可谓是经典永流传。不过,由于现在基本都是Web做的后台管理系统,所以样式、效果等控制起来都比较方便。但是在WinForm上就很头疼 ...