C# HTTP请求

一个http请求的工具类。这个就不必多说了,但是这里为了可以应对较多场景,加入了一个传入参数的类型,用来支持各种的数据,这里再提一下StringText这个枚举类型,访问.net core webapi的接口时,假如定义接收参数为[FromBody]String,那边必须再加引号转一下,否则获取不到,在Swagger上也一样,但是用Jquery的话,直接json.stringify()转一下是没问题的(我感觉这里是个深坑,当然你要用其他方式接收的话可以避免这个问题);同时返回结果有string和byte[]两种类型的数据。用来直接取结果集或者做文件的下载。.

实现功能:

  • C#模拟HTTP请求,获取返回的数据

开发环境:

  • 开发工具:Visual Studio 2019
  • .NET版本:.NET Core 3.1

实现代码:

public class HttpUtil {
        public static HttpResult HttpRequest(HttpItem httpItem) {
            HttpResult result = new HttpResult();
            try {
                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(httpItem.Url);
                httpWebRequest.Method = httpItem.Method.ToString();
                httpWebRequest.ContentType = httpItem.ContentType;
                httpWebRequest.Headers = httpItem.Header;
                httpWebRequest.Timeout = httpItem.TimeOut;
                if(httpItem.Method == RequestMethod.POST && (httpItem.RequestValue != null)) {
                    using(Stream requestStream = httpWebRequest.GetRequestStream()) {
                        requestStream.Write(httpItem.RequestValue, 0, httpItem.RequestValue.Length);
                        httpWebRequest.ContentLength = httpItem.RequestValue.Length;
                    }
                }

                HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                using(Stream responseStream = httpWebResponse.GetResponseStream()) {
                    MemoryStream memoryStream = new MemoryStream();
                    responseStream.CopyTo(memoryStream);

                    result.HttpByteData = memoryStream.ToArray();
                    memoryStream.Seek(0, SeekOrigin.Begin);

                    result.HttpStringData = (httpWebResponse.ContentEncoding != null && httpWebResponse.ContentEncoding.Equals("gzip", StringComparison.InvariantCultureIgnoreCase)) ? memoryStream.ReadGzipText(httpItem.Encoding) : memoryStream.ReadText(httpItem.Encoding);

                }
                return result;
            }
            catch(Exception ex) {
                result.Status = false;
                result.Msg = ex.Message;
                return result;
            }
        }

    }

    public class HttpItem {

        /// <summary>
        /// Url地址
        /// </summary>
        private string url;
        public string Url
        {
            get
            {
                if(!url.ToLower().StartsWith("http")) {
                    url = "http://" + url;
                }
                return url;
            }
            set { url = value; }
        }

        /// <summary>
        /// Method
        /// </summary>
        public RequestMethod Method { get; set; } = RequestMethod.POST;

        /// <summary>
        /// 超时时间
        /// </summary>
        public int TimeOut { get; set; } = 1000 * 60;

        /// <summary>
        /// 接收的ContentType
        /// </summary>
        public string ContentType { get; set; } = "application/json";

        /// <summary>
        /// 发送的ContentType
        /// </summary>
        public string HeaderContentType { get; set; } = "application/json";

        /// <summary>
        /// 
        /// </summary>
        public string UserAgent { get; set; }

        /// <summary>
        /// 编码
        /// </summary>
        public Encoding Encoding { get; set; } = Encoding.UTF8;

        /// <summary>
        /// 发送的数据类型
        /// </summary>
        public RequesDataType RequestDataType { get; set; } = RequesDataType.Text;

        /// <summary>
        /// 发送的数据
        /// </summary>
        public object RequestData { get; set; }

        /// <summary>
        /// 根据数据类型转换数据
        /// </summary>
        public byte[] RequestValue
        {
            get
            {
                byte[] bytes = null;
                if(RequestData != null) {
                    switch(RequestDataType) {
                        case RequesDataType.Text:
                        bytes = Encoding.GetBytes(RequestData.ToString());
                        break;
                        case RequesDataType.StringText:
                        bytes = Encoding.GetBytes($"\"{RequestData}\"");
                        break;
                        case RequesDataType.Byte:
                        bytes = RequestData as byte[];
                        break;
                    }
                }
                return bytes;
            }
        }

        private WebHeaderCollection _header;
        /// <summary>
        /// 设置Header
        /// </summary>
        public WebHeaderCollection Header
        {
            get
            {
                if(_header == null) {
                    _header = new WebHeaderCollection();
                }
                _header.Add(HttpResponseHeader.ContentType, HeaderContentType);
                return _header;
            }
            set { _header = value; }
        }

        public HttpItem(string url, RequesDataType requestDataType = RequesDataType.Text, object requestData = null) {
            Url = url;
            RequestDataType = requestDataType;
            RequestData = requestData;
        }
    }

    public class HttpResult {
        public bool Status { get; set; } = true;
        public string Msg { get; set; } = "Success";
        public string HttpStringData { get; set; }
        public byte[] HttpByteData { get; set; }
    }

    public enum RequestMethod {
        GET, POST
    }

    public enum RequesDataType {
        Text,

        // 如果WebApi设置接收类型为[FromBody]String,需将数据先转义为String
        // 如:SendData:"data", 转义:"\"data\""
        StringText,

        Byte
    }
/// <summary>
/// Stream扩展类
/// </summary>
public static class StreamEx {
  
  /// <summary>
  /// 流转字符串
  /// </summary>
  /// <param name="stream"></param>
  /// <param name="encoding"></param>
  /// <returns></returns>
  public static string ReadText(this Stream stream, Encoding encoding) {
    string text = string.Empty;
    using(StreamReader streamReader = new StreamReader(stream, encoding)) {
      text = streamReader.ReadToEnd();
    }
    return text;
  }
  
  /// <summary>
  /// 流转Gzip压缩字符串
  /// </summary>
  /// <param name="stream"></param>
  /// <param name="encoding"></param>
  /// <returns></returns>
  public static string ReadGzipText(this Stream stream, Encoding encoding) {
    string text = string.Empty;
    using(GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress)) {
      using(StreamReader reader = new StreamReader(gZipStream, encoding)) {
        text = reader.ReadToEnd();
      }
    }
    return text;
  }
    }
public Form1() {
            InitializeComponent();
            Init();
        }

        DataTable dt_head = new DataTable();
        void Init() {
            cb_requetType.SelectedIndex = 0;
            dt_head.Columns.Add("key");
            dt_head.Columns.Add("value");

            grid_headers.DataSource = dt_head;
        }

        private void btn_send_Click(object sender, EventArgs e) {

            WebHeaderCollection headrs = new WebHeaderCollection();
            foreach(DataRow row in dt_head.Rows) {
                headrs.Add(row[0].ToString(), row[1].ToString());
            }

            HttpItem httpItem = new HttpItem(text_url.Text, requestData: text_params.Text) {
                Header = headrs,
                Method = cb_requetType.Text == "Get" ? RequestMethod.GET : RequestMethod.POST
            };
            HttpResult httpResult = HttpUtil.HttpRequest(httpItem);
            if(httpResult.Status) {
                text_response.Text = httpResult.HttpStringData;
            }
            else {
                text_response.Text = "error:" + httpResult.Msg;
            }
        }

实现效果:

C# HTTP请求