zoukankan      html  css  js  c++  java
  • 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基础架构

  • 相关阅读:
    Balanced Binary Tree
    Swap Nodes in Pairs
    Reverse Nodes in k-Group
    Reverse Linked List II
    Remove Nth Node From End of List
    Remove Duplicates from Sorted List II
    Remove Duplicates from Sorted List
    Partition List
    Merge Two Sorted Lists
    【Yii2.0】1.2 Apache检查配置文件语法
  • 原文地址:https://www.cnblogs.com/grj001/p/12224963.html
Copyright © 2011-2022 走看看