解析C#网络编程中的Http请求

解析C#网络编程中的Http请求

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

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

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

public class Req<T> { /// <summary> /// 传入数据 /// </summary> public T Input { get; set; } /// <summary> /// 请求地址 /// </summary> public string Url { get; set; } } public class Resp<T> { /// <summary> /// 错误消息 /// </summary> public string ErrorMsg { get; set; } /// <summary> /// 状态码 /// </summary> public int StatusCode { get; set; } /// <summary> /// 返回数据 /// </summary> public T RespData { get; set; } }

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

#region HttpClient版本 private static readonly string _baseAddress = ConfigurationManager.AppSettings["api-server"];//配置BaseUrl eg.http://localhost:1234 private static readonly HttpClient _httpClient; private static readonly HttpClient _fileClient; static ApiHelper() { #region 初始化和预热 httpClient _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri(_baseAddress); _httpClient.Timeout = TimeSpan.FromMilliseconds(2000); _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");//application/xml 想Accept的数据格式 _httpClient.SendAsync(new HttpRequestMessage { Method = new HttpMethod("HEAD"), RequestUri = new Uri(_baseAddress + "/api/test/HttpClientHot") }) .Result.EnsureSuccessStatusCode(); #endregion #region 初始化和预热 fileClient _fileClient = new HttpClient(); _fileClient.BaseAddress = new Uri(_baseAddress + "/api/test/HttpClientHot"); _fileClient.MaxResponseContentBufferSize = 256000; #endregion } /// <summary> /// http Get请求 /// </summary> /// <typeparam name="T">入参类型</typeparam> /// <typeparam name="TResult">出参类型</typeparam> /// <param name="req">入参对象</param> /// <returns></returns> public static async Task<Resp<TResult>> GetAsync<T, TResult>(Req<T> req) { try var result =await _httpClient.GetAsync(req.Url).Result.Content.ReadAsStringAsync(); return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) }; } catch(Exception ex) } return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>("") }; } /// <summary> /// http Post请求 /// </summary> /// <typeparam name="T">入参类型</typeparam> /// <typeparam name="TResult">出参类型</typeparam> /// <param name="req">入参对象</param> /// <returns></returns> public static async Task<Resp<TResult>> PostAsJsonAsync<T, TResult>(Req<T> req) var result = await _httpClient.PostAsJsonAsync(req.Url, req.Input).Result.Content.ReadAsStringAsync(); return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) }; } /// 上传文件 /// <typeparam name="T"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="req"></param> /// <param name="filePath"></param> public static async Task<Resp<TResult>> SendFile<T, TResult>(Req<T> req, string filePath)//D:\\white.webp //_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");//设置请求头 // 读文件流 FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); HttpContent fileContent = new StreamContent(fs);//为文件流提供的HTTP容器 fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");//设置媒体类型 MultipartFormDataContent mulContent = new MultipartFormDataContent("----");//创建用于可传递文件的容器 string fileName = filePath.Substring(filePath.LastIndexOf("/") + 1); mulContent.Add(fileContent, "form", fileName);//第二个参数是表单名,第三个是文件名。 HttpResponseMessage response = await _fileClient.PostAsync(req.Url, mulContent); response.EnsureSuccessStatusCode(); string result = await response.Content.ReadAsStringAsync(); return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) }; } /// 下载 /// <param name="url"></param> /// <returns></returns> public static async Task<Resp<byte[]>> HttpDownloadData<T>(Req<T> req) var byteres = await _fileClient.GetByteArrayAsync(req.Url); return new Resp<byte[]>() { Data = byteres }; #endregion }

另外分享下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(); }

到此这篇关于C#网络编程中的Http请求的文章就介绍到这了,更多相关C#网络编程Http请求内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    学习写字楼新选择6000元主流配置

    学习写字楼新选择6000元主流配置,,这种配置需要考虑双核心的办公和娱乐平台,充分考虑办公室的办公需求和娱乐需求,以约6000元的预算和cost-e

    Lucene学习之高亮显示

    Lucene学习之高亮显示,索引,字符,在搜索引擎中我们经常会看到这样的情景: 红色部分我们称之为高亮显示,lucene提供了HighLighter模块来实

    设计电脑系统封装|电脑系统封装教程

    设计电脑系统封装|电脑系统封装教程,,电脑系统封装教程不是的,只是虚拟机比较方便。物理机也可以的,只是要通过外界启动来ghost系统。 办法

    新手如何学习计算机知识(快速入门)

    新手如何学习计算机知识(快速入门),,作为一个初学者,因为我忙于工作和家庭的原因,我没有太多的时间去计算机培训班,但我想熟悉计算机操作和计算

    学习游戏两宜3000元菜鸟超频主机

    学习游戏两宜3000元菜鸟超频主机,,在英特尔中的主流新产品的推出,旧产品将面临洗牌。目前,奔腾双核E2180处理器的价格已经降至430元,而奔腾e2

    如何学习PP点(图2)

    如何学习PP点(图2),,再次输入密码,按GO你可以立即着陆(图1-5): 图1-5 着陆后,PP的主界面出现(图1-6): 图1-6 搜索 当成员进入PP时,点击主界面右上

    电脑维修学习网站|电脑维修自学网

    电脑维修学习网站|电脑维修自学网,,电脑维修自学网有的,建议多努力学习一些知识和本领,等出来可以自己租电脑维修,手机维修等工作,收入不错 电

    revit学习快捷键|Revit快捷键大全

    revit学习快捷键|Revit快捷键大全,,1. Revit快捷键大全Al 对齐Tr 修剪Rp 画参照线Hi 隔离原图Cv 复制Mm 镜像Hh 临时隐藏Vv 图形可见性设