概述
2.0版本之所以放弃了1.x版本的序列,是因为变更比较大,存在不少破坏性变更。
详细变更列表
警告:列表中为红色的变更记录为破坏性变更,您可能需要调整现有的代码以匹配当前的库。
HttpClient
增加新的Clear()
函数,用于重置状态。此操作会清空所有Cookies以及上下文跟踪- 请求流封装逻辑细节调整,对极个别情况下出现的流异常增加捕捉
- 请求数据封装类逻辑修正,现在支持直接将
HttpPostFile
类型作为表单数据上传 HttpContext
请求发送流程微调,异步模式下所有代码都以异步模式启动- 增加对图片的上传支持(默认保存为JPG)
- 增加UrlTokenIdentitier功能(默认启用),允许将请求数据标记在URL中
- 提交数据在
GET
模式下序列化到 URL 中的模式默认行为变更,默认会对字符串进行转义 - 支持设置客户端的证书
- 增加新的
IContentPayloadBuilder
接口(原BuilderUtility
中的静态方法并改进了签名设计),并提供默认实例(HttpContext
的设置中可以修改) IRequestContentBuilder
/IResponseContentBuilder
接口签名变更- 增加数据包装接口
IRequestContentBuilder`1
,并更改为泛型类设计,允许使用标签进行标记 IFormData
接口的BindData
函数签名变更,增加深度以及前缀标记- 增加新的
IFormDataKeyGenerator
接口,用于生成表单数据中每个项的键名;提供默认的实例(DefaultFormDataKeyGenerator
) - 移除
HttpSetting
以及HttpRequestMessage
的ContentType
属性(此处设置无意义) RequestPayloadType
重命名为ContentType
,所有的payloadType
参数名均改名为contentType
,RequestPayloadTypeAttribute
类型改名为ContentTypeAttribute
- 增加新的
ExtraRequestInfo
类型,用于添加并设置请求中的额外数据 HttpClient
增加大量的便捷函数并移除过期的或不适合使用的便捷函数IHttpHandler
接口签名修改,表示 HTTP 谓词的method
参数类型修改为string
HttpContext
添加SetRequestContentType()
函数,可以在发送前修改发送数据的ContentType
- 修正当下载文件时,如果读取出现超时或其它异常时,已打开文件句柄可能没有被正确关闭的BUG
- 对UTF-8编码的识别改善,兼容个别错误的编码结果
HttpPerformance
增加PerformanceUpdated
属性,每次性能数据更新的时候将会引发事件通知HttpClient
增加SendContextWithRetry
、SendContextWithRetryAsync
便捷函数,用于在请求失败时自动重试请求- 直接发送字符串为表单数据时,使用请求的编码而非ASCII发送字符串
- 发送数据增加对
IDictionary<string, object>
的支持
新增的功能
新增了UrlTokenIdentitier 功能,此选项默认打开。其基本的意思是,对于提交的数据,可以在URL地址中以占位符的形式提交。
此选项默认开启,参考如下代码。
var client = new HttpClient(); var data = new Dictionary<string, object>() { ["name"] = "哈哈", ["id"] = "测试" }; //此功能默认打开,并不需要下面这么设置 //如果您希望关闭此功能,可以将下面这行的true改为false client.Setting.EnableUrlTokenIdentitier = true; var ctx = client.Create<string>(HttpMethod.Post, "http://www.fishlee.net/?search={name}", data: data, contentType: ContentType.FormUrlEncoded ); ctx.Send();
最后发送的结果如下。
从图中可见,虽然data
是一个字典并且我们直接放在 Post 数据中,但是其中的name
因为在URL中有占位符,所以被序列化到了URL中,而除name
以外的数据,则继续在 Post 正文中被发送。
占位符的格式为 {变量名}
。
设置请求的ContentType
在之前的版本中,由于BUG的存在,您无法将请求的数据(如Post的正文)设置为application/x-www-form-urlencoded或application/multi-formdata以外的内容。这个错误在本版本中被修正并得到了增强。
现在,您有两种方式设置发送的ContentType。
方式一:创建的时候指定
参考如下代码。
var client = new HttpClient(); var data = new Dictionary<string, object>() { ["name"] = "哈哈", ["id"] = "测试" }; var ctx = client.Create<string>(HttpMethod.Post, "http://www.fishlee.net/?search={name}", data: data, extra: new ExtraRequestInfo() { ContentType = "text/plain" }); ctx.Send();
此代码运行结果如下。
方式二:创建后指定
参见如下代码。
var client = new HttpClient(); var data = new Dictionary<string, object>() { ["name"] = "哈哈", ["id"] = "测试" }; var ctx = client.Create<string>(HttpMethod.Post, "http://www.fishlee.net/?search={name}", data: data ); ctx.SetRequestContentType("text/plain"); ctx.Send();
此代码运行结果与楼上结果相同。
禁止302跳转
在一些情况下,301/302跳转往往意味着错误(比如未登录等)。
在这些情况下,HttpContext可能会依然返回正确的状态,但结果并非如您所愿。因此,新增了属性来禁止这些情况。
参考如下代码。
var client = new HttpClient(); var ctx = client.Create<string>(HttpMethod.Get, "http://t.cn/RUbKZCU", extra: new ExtraRequestInfo() { Disable302Redirection = true } ); ctx.Send(); Console.WriteLine(ctx.ExceptionStatus.ToString()); Console.WriteLine(ctx.IsValid().ToString()); Console.WriteLine(ctx.Exception?.Message);
如果此请求返回了301或302代码,则将会引发错误,而不会返回正常。上述代码的结果如下。
自动重试
在一些情况下,我们可能需要在请求发生错误的时候自动重试。从2.0版本开始,库引入了自动重试支持。
自动重试需要的参数包含一个工厂函数(通过它每次都创建一个用于发送请求的HttpContext
)、设置(检测是否正确的函数、重试次数、休息时间、重试提示)等。
工作流程为:工厂函数新建HttpContext -> 通知重试 -> 发送请求 -> 判断是否正确,如果失败则重试整个流程,否则返回当前的HttpContext。
如果重试全部失败,则返回最后的服务器响应。
参考如下的代码。
var client = new HttpClient(); var ctx = client.SendContextWithRetry( () => //工厂函数,每次重试返回一个需要的HttpContext。每次重试的时候使用的都不是同一个HttpContext client.Create<string>(HttpMethod.Get, "http://t.cn/RUbKZCU", extra: new ExtraRequestInfo() { Disable302Redirection = true } ), null, //判定是否正确的处理函数,用于检测响应是否正常。为null使用默认的检测,默认检测依据为 IsValid() 返回 true (i, ctx1) => { //通知重试次数 Console.WriteLine("第 " + i + " 次请求..."); }, null, //为null使用全局的重试次数设置,默认为5 null //为null使用全局的重试休息时间,默认为100 ); Console.WriteLine(ctx.ExceptionStatus.ToString()); Console.WriteLine(ctx.IsValid().ToString()); Console.WriteLine(ctx.Exception?.Message);
上述代码的运行结果如下。
安装和其它信息
请在NUGET项目主页安装: https://www.nuget.org/packages/network.fishlee.net/
如果您访问NUGET过慢,也许您会想要试试 提供针对Nuget包管理器的缓存加速服务。
鱼哥 好不好写个Demo啊 新手不会用
不错。。能提供例子吗,和应用场景
天啦噜,更新咯更新咯!!
以前的BUG可以修复了。
–愤怒的TryCatch
有木例子,,这样可以更好的学习一下。
后续将会提供文档,还请留意。。。
支持一下,Dict参数提交,很好用撒~