本片篇分享简单介绍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—>Modelif (!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();}

C#网络编程之Http请求相关推荐

  1. Android网络编程之Http请求服务器数据(POST方式)

    Android中的网络请求主要有GET和POST方式.POST方式比GET方式更为安全,因为需要发送的消息不是嵌入在url中的,同时能比GET发送更多的数据. 本文讨论使用POST方式向聚合数据API ...

  2. Android网络编程之Http请求服务器数据(GET方式)

    进行Android应用开发,其中不得不使用到网络编程,最基本的就是向服务器发送Http请求,并接收从服务器返回的数据,该类数据一般为JSON或XML格式. 向服务器进行请求数据一般有GET.POST两 ...

  3. IOS网络编程之http请求响应篇

    从IOS角度看http url是服务器上资源的一个位置,作为这个规则一个单独的资源可能和很多url有关系,但是一个url不能关联很多资源.但是也有例外的情况,例如当hostname关联一个不稳定的ho ...

  4. Java网络编程之TCP、UDP

    Java网络编程之TCP.UDP 2014-11-25 15:23 513人阅读 评论(0) 收藏 举报 分类: java基础及多线程(28) 版权声明:本文为博主原创文章,未经博主允许不得转载. J ...

  5. iOS网络编程之Socket

    [深入浅出Cocoa]iOS网络编程之Socket 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 更多 Cocoa 开发文章,敬请访问<深入浅 ...

  6. Python中的网络编程之TCP

    Python中的网络编程之TCP 文章目录 Python中的网络编程之TCP 1.TCP介绍 2.TCP特点 3.TCP与UDP的不同点 4.tcp通信模型 5.tcp客户端 6.tcp服务器 7.T ...

  7. Python中的网络编程之UDP

    Python中的网络编程之UDP 文章目录 Python中的网络编程之UDP 一.Socket编程 `1.什么是客户端/服务器架构`? **`2.套接字:通信端点`** 3.套接字地址:主机-端口对 ...

  8. 浅谈Java网络编程之Socket (1)

    和大家一起分享的是Java网络编程之Socket.在Java中Socket可以理解为客户端或者服务器端的一个特殊的对象,这个对象有两个关键的方法,一个是getInputStream方法,另一个是get ...

  9. Python之路 - 网络编程之Socket

    Python之路 - 网络编程之Socket C/S架构 ? Socket ? 基于TCP ? 基于UDP ? Socket对象方法 ? C/S架构 ? 在网络通信中 , 一般是一方求一方应 , 求的 ...

最新文章

  1. 16S+功能预测发Sciences:尸体降解过程中的微生物组
  2. struts2之ModelDriven的使用
  3. spring_Spring Boot登录选项快速指南
  4. python sort 部分元素_Python 简单排序算法-选择、冒泡、插入排序实现
  5. 可持久化3--可持久化01Trie
  6. 找通项公式在线计算机,在线硬盘分区计算器工具
  7. 【实时+排重】摆脱渠道统计刷量作弊行为
  8. JQuery datepicker
  9. H.266/VVC代码学习38:VTM6.0帧间merge预测(xCheckRDCostMerge2Nx2N)
  10. EXCEL 中数据分析常用统计方法介绍(二)
  11. 港股通Level2介绍
  12. python处理淘宝助理csv_淘宝助理上传CSV文件
  13. 一招解决Maven项目中resource目录下的application.yml不能被识别(即没有小叶子)
  14. lwIP配置宏整理(部分)
  15. kryo com.esotericsoftware.kryo.KryoException: Buffer underflow.
  16. easyui分页查询为什么会有下拉框_Easyui 添加分页组件_EasyUI 教程
  17. 去除水印PNAS-latex
  18. fedora安装fcitx
  19. LoadRunner之并发用户数与迭代关系---并发数与迭代的区别
  20. 华为鸿蒙系统开发语言,华为鸿蒙系统采用什么语言进行开发的

热门文章

  1. final 和static的关系
  2. CentOS 6.4 yum安装LAMP环境
  3. codeforecs Gym 100286B Blind Walk
  4. C++ 连接数据库的入口和获取列数、数据
  5. jquery 请求jsp传递json数据的方法
  6. 有关DataVisualization类组件的研究——Silverlight学习笔记[43]
  7. Java实现单例的5种方式
  8. 详细描述一下 Elasticsearch 更新和删除文档的过程。
  9. RabbitMQ (一) MQ介绍以Linux下RabbitMq环境安装
  10. 首次使用mysql_mysql-8.0.20-winx64_初次使用过程(Win7x64)