• C#网络编程之Http请求


    C#网络编程之Http请求

    本片篇分享简单介绍C#中的Http请求,前几天帮朋友的项目封装ApiHelper,我粗糙的结果就如下,想想我真的是差的太远了。还有一位架构师也在封装这个Helper , 所以最后的结果当然是使用大牛的封装,这篇分享后,准备学习下他的封装,配置,错误处理机制等思想。不过这次也使我对C#网络编程了解的更多,算是一次学习经历吧。真心喜欢和老司机合作,下一阶段将会持续跟这位朋友学习项目底层的封装,和他谦虚的态度,有这样的机会也是幸运的。

    你可以将其封装成自己的HttpHelper,经朋友建议,统一Http请求的入参和出参。在HttpClient方面也参考了dudu的关于httpclient预热的文章。C#中HttpClient使用注意:预热与长连接。

    为了做到统一入参和出参,定义了Req<T>泛型类和Resp<T>泛型类。你可以根据自己的需要进行拓展。

    复制代码

     1   public class Req<T>
     2     {
     3         /// <summary>
     4         /// 传入数据
     5         /// </summary>
     6         public T Input { get; set; }
     7         /// <summary>
     8         /// 请求地址
     9         /// </summary>
    10         public string Url { get; set; }
    11     }

    复制代码

    复制代码

     1 public class Resp<T>
     2     {
     3         /// <summary>
     4         /// 错误消息
     5         /// </summary>
     6         public string ErrorMsg { get; set; }
     7         /// <summary>
     8         /// 状态码
     9         /// </summary>
    10         public int StatusCode { get; set; }
    11         /// <summary>
    12         /// 返回数据
    13         /// </summary>
    14         public T RespData { get; set; }
    15     }

    复制代码

    虽然保持了httpClient对象复用,但需要注意的是,在设置了httpClient,并且发生了一次请求之后,不能再对其属性进行重新设置。这也正是我又定义了一个fileClient的理由。

    复制代码

      1   #region HttpClient版本
      2         private static readonly string _baseAddress = ConfigurationManager.AppSettings["api-server"];//配置BaseUrl eg.http://localhost:1234
      3         private static readonly HttpClient _httpClient;
      4         private static readonly HttpClient _fileClient;
      5 
      6         static ApiHelper()
      7         {
      8             #region 初始化和预热 httpClient
      9             _httpClient = new HttpClient();
     10             _httpClient.BaseAddress = new Uri(_baseAddress);
     11             _httpClient.Timeout = TimeSpan.FromMilliseconds(2000);
     12             _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");//application/xml  想Accept的数据格式
     13 
     14             _httpClient.SendAsync(new HttpRequestMessage
     15             {
     16                 Method = new HttpMethod("HEAD"),
     17                 RequestUri = new Uri(_baseAddress + "/api/test/HttpClientHot")
     18             })
     19             .Result.EnsureSuccessStatusCode();
     20             #endregion
     21 
     22             #region 初始化和预热 fileClient
     23 
     24             _fileClient = new HttpClient();
     25             _fileClient.BaseAddress = new Uri(_baseAddress + "/api/test/HttpClientHot");
     26             _fileClient.MaxResponseContentBufferSize = 256000;
     27 
     28             #endregion
     29         }
     30 
     31         /// <summary>
     32         /// http Get请求
     33         /// </summary>
     34         /// <typeparam name="T">入参类型</typeparam>
     35         /// <typeparam name="TResult">出参类型</typeparam>
     36         /// <param name="req">入参对象</param>
     37         /// <returns></returns>
     38         public static async Task<Resp<TResult>> GetAsync<T, TResult>(Req<T> req)
     39         {
     40             try
     41             {
     42                 var result =await _httpClient.GetAsync(req.Url).Result.Content.ReadAsStringAsync();
     47                 return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
     48             }
     49             catch(Exception ex)
     50             {
     51 
     52             }
     53                 return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>("") };
     54             
     55         }
     56 
     57         /// <summary>
     58         ///  http Post请求
     59         /// </summary>
     60         /// <typeparam name="T">入参类型</typeparam>
     61         /// <typeparam name="TResult">出参类型</typeparam>
     62         /// <param name="req">入参对象</param>
     63         /// <returns></returns>
     64         public static async Task<Resp<TResult>> PostAsJsonAsync<T, TResult>(Req<T> req)
     65         {
     66             var result = await _httpClient.PostAsJsonAsync(req.Url, req.Input).Result.Content.ReadAsStringAsync();
     67             return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
     68         }
     69 
     70         /// <summary>
     71         /// 上传文件
     72         /// </summary>
     73         /// <typeparam name="T"></typeparam>
     74         /// <typeparam name="TResult"></typeparam>
     75         /// <param name="req"></param>
     76         /// <param name="filePath"></param>
     77         /// <returns></returns>
     78         public static async Task<Resp<TResult>> SendFile<T, TResult>(Req<T> req, string filePath)//D:\\white.jpg
     79         {
     80             //_fileClient.DefaultRequestHeaders.Add("user-agent", "User-Agent    Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; MALNJS; rv:11.0) like Gecko");//设置请求头
     81             // 读文件流
     82             FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
     83             HttpContent fileContent = new StreamContent(fs);//为文件流提供的HTTP容器
     84             fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");//设置媒体类型
     85             MultipartFormDataContent mulContent = new MultipartFormDataContent("----");//创建用于可传递文件的容器
     86             string fileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
     87             mulContent.Add(fileContent, "form", fileName);//第二个参数是表单名,第三个是文件名。
     88             HttpResponseMessage response = await _fileClient.PostAsync(req.Url, mulContent);
     89             response.EnsureSuccessStatusCode();
     90             string result = await response.Content.ReadAsStringAsync();
     91             return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
     92         }
     93 
     94         /// <summary>
     95         /// 下载
     96         /// </summary>
     97         /// <param name="url"></param>
     98         /// <returns></returns>
     99         public static async Task<Resp<byte[]>> HttpDownloadData<T>(Req<T> req)
    100         {
    101             var byteres = await _fileClient.GetByteArrayAsync(req.Url);
    102             return new Resp<byte[]>() { Data = byteres };
    103         }
    104 
    105         #endregion
    106 }

    复制代码

    另外分享下HttpWebRequest来实现的请求。HttpWebRequest需要你自行设置很多内容,当然这也证明其内容丰富。下面代码包含了post,get,以及上传。

    复制代码

            /// <summary>
            /// Post Http请求
            /// </summary>
            /// <param name="url">请求地址</param>
            /// <param name="postData">传输数据</param>
            /// <param name="timeout">超时时间</param>
            /// <param name="contentType">媒体格式</param>
            /// <param name="encode">编码</param>
            /// <returns>泛型集合</returns>
            public static List<T> PostAndRespList<T>(string url, string postData, int timeout = 5000, string contentType = "application/json;", string encode = "UTF-8")
            {
                if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
                {
                    // webRequest.Headers.Add("Authorization", "Bearer " + "SportApiAuthData");
                    HttpWebResponse webResponse = null;
                    Stream responseStream = null;
                    Stream requestStream = null;
                    StreamReader streamReader = null;
                    try
                    {
                        string respstr = GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
                        return JsonHelper.JsonDeserialize<List<T>>(respstr);
    
                    }
                    catch (Exception ex)
                    {
    
                    }
                    finally
                    {
                        if (responseStream != null) responseStream.Dispose();
                        if (webResponse != null) webResponse.Dispose();
                        if (requestStream != null) requestStream.Dispose();
                        if (streamReader != null) streamReader.Dispose();
                    }
                }
                return null;
            }
    
            /// <summary>
            /// Post Http请求
            /// </summary>
            /// <param name="url">请求地址</param>
            /// <param name="postData">传输数据</param>
            /// <param name="timeout">超时时间</param>
            /// <param name="contentType">媒体格式</param>
            /// <param name="encode">编码</param>
            /// <returns>泛型集合</returns>
            public static T PostAndRespSignle<T>(string url, int timeout = 5000, string postData = "", string contentType = "application/json;", string encode = "UTF-8")
            {
                if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
                {
                    // webRequest.Headers.Add("Authorization", "Bearer " + "SportApiAuthData");
                    HttpWebResponse webResponse = null;
                    Stream responseStream = null;
                    Stream requestStream = null;
                    StreamReader streamReader = null;
                    try
                    {
                        string respstr = GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
                        return JsonHelper.JsonDeserialize<T>(respstr);
                    }
                    catch (Exception ex)
                    {
    
                    }
                    finally
                    {
                        if (responseStream != null) responseStream.Dispose();
                        if (webResponse != null) webResponse.Dispose();
                        if (requestStream != null) requestStream.Dispose();
                        if (streamReader != null) streamReader.Dispose();
                    }
                }
                return default(T);
            }
    
            /// <summary>
            /// Post Http请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="postData"></param>
            /// <param name="timeout"></param>
            /// <param name="contentType"></param>
            /// <param name="encode"></param>
            /// <returns>响应流字符串</returns>
            public static string PostAndRespStr(string url, int timeout = 5000, string postData = "", string contentType = "application/json;", string encode = "UTF-8")
            {
                if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
                {
                    HttpWebResponse webResponse = null;
                    Stream responseStream = null;
                    Stream requestStream = null;
                    StreamReader streamReader = null;
                    try
                    {
    
                        return GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
                    }
                    catch (Exception ex)
                    {
    
                    }
                    finally
                    {
                        if (responseStream != null) responseStream.Dispose();
                        if (webResponse != null) webResponse.Dispose();
                        if (requestStream != null) requestStream.Dispose();
                        if (streamReader != null) streamReader.Dispose();
                    }
                }
                return null;
            }
    
            private static string GetStreamReader(string url, Stream responseStream, Stream requestStream, StreamReader streamReader, WebResponse webResponse, int timeout, string encode, string postData, string contentType)
            {
                byte[] data = Encoding.GetEncoding(encode).GetBytes(postData);
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
                SetAuth(webRequest);
                webRequest.Method = "POST";
                webRequest.ContentType = contentType + ";" + encode;
                webRequest.ContentLength = data.Length;
                webRequest.Timeout = timeout;
                requestStream = webRequest.GetRequestStream();
                requestStream.Write(data, 0, data.Length);
                webResponse = (HttpWebResponse)webRequest.GetResponse();
                responseStream = webResponse.GetResponseStream();
                if (responseStream == null) { return ""; }
                streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode));
                return streamReader.ReadToEnd();
            }
    
            /// <summary>
            /// Post文件流给指定Url
            /// </summary>
            /// <param name="url">url</param>
            /// <param name="filePath">文件路径</param>
            /// <returns>响应流字符串</returns>
            public static string PostFile(string url, string filePath, string contentType = "application/octet-stream", string encode = "UTF-8")
            {
                if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && !string.IsNullOrEmpty(filePath))
                {
    
                    Stream requestStream = null;
                    Stream responseStream = null;
                    StreamReader streamReader = null;
                    FileStream fileStream = null;
                    try
                    {
                        // 设置参数
                        HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
                        SetAuth(webRequest);
                        webRequest.AllowAutoRedirect = true;
                        webRequest.Method = "POST";
                        string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
                        webRequest.ContentType = "multipart/form-data;charset=" + encode + ";boundary=" + boundary;
                        byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");//消息开始
                        byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");//消息结尾
                        var fileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
                        //请求头部信息
                        string postHeader = string.Format("Content-Disposition:form-data;name=\"media\";filename=\"{0}\"\r\nContent-Type:{1}\r\n\r\n", fileName, contentType);
                        byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
                        fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                        byte[] fileByteArr = new byte[fileStream.Length];
                        fileStream.Read(fileByteArr, 0, fileByteArr.Length);
                        fileStream.Close();
                        requestStream = webRequest.GetRequestStream();
                        requestStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
                        requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
                        requestStream.Write(fileByteArr, 0, fileByteArr.Length);
                        requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                        requestStream.Close();
                        responseStream = webRequest.GetResponse().GetResponseStream();//发送请求,得到响应流
                        if (responseStream == null) return string.Empty;
                        streamReader = new StreamReader(responseStream, Encoding.UTF8);
                        return streamReader.ReadToEnd();
                    }
                    catch (Exception ex)
                    {
    
                    }
                    finally
                    {
    
                    }
                }
                return null;
    
            }
    
            /// <summary>
            /// Get http请求
            /// </summary>
            /// <param name="url">请求地址</param>
            /// <param name="timeout">超时时间</param>
            /// <param name="encode">编码</param>
            /// <returns>返回单个实体</returns>
            public static T GetSingle<T>(string url, int timeout = 5000, string encode = "UTF-8")
            {
                //HttpWebRequest对象
                //HttpClient->dudu 调用预热处理
                //Stream—>Model
    
                if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode))
                {
                    Stream responseStream = null;
                    StreamReader streamReader = null;
                    WebResponse webResponse = null;
                    try
                    {
                        string respStr = GetRespStr(url, responseStream, streamReader, webResponse, timeout, encode);
                        return JsonHelper.JsonDeserialize<T>(respStr);
                    }
                    catch (Exception ex)
                    {
    
                    }
                    finally
                    {
                        if (responseStream != null) responseStream.Dispose();
                        if (streamReader != null) streamReader.Dispose();
                        if (webResponse != null) webResponse.Dispose();
                    }
                }
                return default(T);
            }
    
            /// <summary>
            ///  Get http请求
            /// </summary>
            /// <param name="url"></param>
            /// <param name="timeout"></param>
            /// <param name="encode"></param>
            /// <returns>响应流字符串</returns>
            public static string GetResponseString(string url, int timeout = 5000, string encode = "UTF-8")
            {
                if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode))
                {
                    Stream responseStream = null;
                    StreamReader streamReader = null;
                    WebResponse webResponse = null;
                    try
                    {
                        return GetRespStr(url, responseStream, streamReader, webResponse, timeout, encode);
                    }
                    catch (Exception ex)
                    {
    
                    }
                    finally
                    {
                        if (responseStream != null) responseStream.Dispose();
                        if (streamReader != null) streamReader.Dispose();
                        if (webResponse != null) webResponse.Dispose();
                    }
                }
                return null;
            }
    
            private static string GetRespStr(string url, Stream responseStream, StreamReader streamReader, WebResponse webResponse, int timeout, string encode)
            {
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
                webRequest.Method = "GET";
                webRequest.Timeout = timeout;
                webResponse = webRequest.GetResponse();
                responseStream = webResponse.GetResponseStream();
                if (responseStream == null) { return ""; }
                streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode));
                return streamReader.ReadToEnd();
             }

    复制代码

    分类: .Net基础架构

  • 相关阅读:
    如何实现一个串行promise
    单机,分布式和集群的区别
    ERP & CRM
    CDN working principle diagram
    公众平台服务号、订阅号、企业号的相关说明
    DMZ的原理与应用
    ICP备案接入商
    DMZ主机
    浅析localstorage、sessionstorage
    Repeater+AspNetPager+Ajax留言板
  • 原文地址:https://www.cnblogs.com/grj001/p/12224962.html
Copyright © 2020-2023  润新知