本片篇分享简单介绍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();
_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 = ; #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) };
} /// <summary>
/// 上传文件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="req"></param>
/// <param name="filePath"></param>
/// <returns></returns>
public static async Task<Resp<TResult>> SendFile<T, TResult>(Req<T> req, string filePath)//D:\\white.jpg
{
//_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("/") + );
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) };
} /// <summary>
/// 下载
/// </summary>
/// <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 = , 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 = , 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 = , 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, , 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("/") + );
//请求头部信息
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, , fileByteArr.Length);
fileStream.Close();
requestStream = webRequest.GetRequestStream();
requestStream.Write(itemBoundaryBytes, , itemBoundaryBytes.Length);
requestStream.Write(postHeaderBytes, , postHeaderBytes.Length);
requestStream.Write(fileByteArr, , fileByteArr.Length);
requestStream.Write(endBoundaryBytes, , 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 = , 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 = , 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. [深入浅出WP8.1(Runtime)]网络编程之HttpClient类

    12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类 ...

  2. python3网络编程之socketserver

    本节主要是讲解python3网络编程之socketserver,在上一节中我们讲到了socket.由于socket无法支持多用户和多并发,于是就有了socket server. socket serv ...

  3. 网络编程之UDP编程

    网络编程之UDP编程 UDP协议是一种不可靠的网络协议,它在通信的2端各建立一个Socket,但是这个Socket之间并没有虚拟链路,这2个Socket只是发送和接受数据的对象,Java提供了Data ...

  4. 网络编程之TCP编程

    网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...

  5. 网络编程之socketserver

    网络编程之socketserver """ socketserver.py 中的5个基础类 +------------+ | BaseServer | +-------- ...

  6. 网络编程之Socket & ServerSocket

    网络编程之Socket & ServerSocket Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP ...

  7. GO语言的进阶之路-网络编程之socket

    GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...

  8. 网络编程之HttpClient类(转)

    12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类 ...

  9. [深入浅出Cocoa]iOS网络编程之Socket

    http://blog.csdn.net/kesalin/article/details/8798039 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   [深入浅出Co ...

随机推荐

  1. Python(二)之对象类型

    本篇记录Python对象类型 开始仍然是先掌握几个查看对象有用的函数,id,type,print 查看对象身份.类型.值:记住以下两个命令id,type 两个对象的比较 以上三个分别是 身份比较.对象 ...

  2. 详解利用Dockerfile构建mysql镜像并实现数据的初始化及权限设置

    本文提要 本文目的不仅仅是创建一个MySQL的镜像,而是在其基础上再实现启动过程中自动导入数据及数据库用户的权限设置,并且在新创建出来的容器里自动启动MySQL服务接受外部连接,主要是通过Docker ...

  3. 可嵌入图片视频jQuery全屏滑块

    分享一款可嵌入图片视频jQuery全屏滑块.这是一款可定制的滑块幻灯片代码,支持键盘箭头切换.效果图如下: 在线预览   源码下载 实现的代码. html代码:     <script type ...

  4. Oracle查看数据库表的创建时间

    select OBJECT_NAME, CREATED from DBA_OBJECTS obj, USER_TABLES tab where obj.OBJECT_NAME = tab.TABLE_ ...

  5. HashTable浅析

    本文转载自: http://rock3.info/blog/2013/12/05/hashtable%E6%B5%85%E6%9E%90/ 一.Hash特点 Hash,就是杂凑算法,Hash(str1 ...

  6. C#中的volatile关键字

    volatile 关键字指示一个字段可以由多个同时执行的线程修改. 声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制. 这样可以确保该字段在任何时间呈现的都是最新的值. vo ...

  7. C# switch-case中的或(or)操作

    今天需要在switch中添加一个条件,类似if中的 " || “操作 switch(var) { : : ... break; : : ... break; ... } 这样条件2 5会执行 ...

  8. 批量修改mysql数据库引擎

    数据库表中部分是MyISAM引擎,部分是InnoDB.由于MyISAM不支持事务,所以需要全部修改为InnoDB引擎. (下面例子SQL语句中 ecsoft 为数据库名) 通过以下查询可以看到数据库中 ...

  9. Android文档 - 账户管理器概述

    账户管理器概述 这个类提供了访问到 用户在线账户的集中式注册中心 的能力.用户为每账户输入一次 认证信息(credentials,包含用户名和密码),过过 点击一次(one-click)完成认证的方式 ...

  10. 微信公众平台开发 - 动手篇。使用weinxinFundation开始一个微信公众平台的开发

    本文主要讲解如何使用 weinxinFundation 进行二次开发. 步骤如下: 1.创建新的web项目. 在eclipse里新建一个dynamicly web project,比如本文叫weixi ...