From 0b60d25c8aa037caa85f73d1674c6966cbdd27ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Fri, 5 Jun 2020 08:57:34 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dform=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E8=BF=87=E9=95=BF=E7=BC=96=E7=A0=81=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DPathQuery=E7=9A=84uri=E7=BC=96=E7=A0=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B=20=E6=8F=90=E9=AB=98PathQuery=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E6=9B=BF=E6=8D=A2=E6=80=A7=E8=83=BD;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PathQueryAttributeTest.cs | 4 +- WebApiClient.Test/Internal/UriEditorTest.cs | 22 ++++---- .../ParameterAttributes/PathQueryAttribute.cs | 4 +- WebApiClient/HttpApiRequestMessage.cs | 47 +++++++++--------- .../HttpContents/UrlEncodedContent.cs | 6 +-- WebApiClient/Internal/UriEditor.cs | 38 ++++---------- WebApiClient/WebApiClient.csproj | Bin 11954 -> 11954 bytes 7 files changed, 52 insertions(+), 69 deletions(-) diff --git a/WebApiClient.Test/Attributes/ParameterAttributes/PathQueryAttributeTest.cs b/WebApiClient.Test/Attributes/ParameterAttributes/PathQueryAttributeTest.cs index 7f2d63ca..2c7a7e75 100644 --- a/WebApiClient.Test/Attributes/ParameterAttributes/PathQueryAttributeTest.cs +++ b/WebApiClient.Test/Attributes/ParameterAttributes/PathQueryAttributeTest.cs @@ -25,7 +25,7 @@ public async Task BeforeRequestAsyncTest() apiActionDescriptor: new ApiActionDescriptor(typeof(IMyApi).GetMethod("PostAsync"))); context.RequestMessage.RequestUri = new Uri("http://www.webapi.com/"); - context.RequestMessage.Method = HttpMethod.Post; + context.RequestMessage.Method = HttpMethod.Post; var parameter = context.ApiActionDescriptor.Parameters[0].Clone(new { @@ -37,7 +37,7 @@ public async Task BeforeRequestAsyncTest() await ((IApiParameterAttribute)attr).BeforeRequestAsync(context, parameter); var birthday = context.HttpApiConfig.FormatOptions.CloneChange(attr.DateTimeFormat).FormatDateTime(DateTime.Parse("2010-10-10")); - var target = new Uri("http://www.webapi.com?name=laojiu&birthDay=" + HttpUtility.UrlEncode(birthday, Encoding.GetEncoding(attr.Encoding))); + var target = new Uri("http://www.webapi.com?name=laojiu&birthDay=" + Uri.EscapeDataString(birthday)); Assert.True(context.RequestMessage.RequestUri == target); } } diff --git a/WebApiClient.Test/Internal/UriEditorTest.cs b/WebApiClient.Test/Internal/UriEditorTest.cs index 37210444..78bc9e94 100644 --- a/WebApiClient.Test/Internal/UriEditorTest.cs +++ b/WebApiClient.Test/Internal/UriEditorTest.cs @@ -12,63 +12,61 @@ public class UriEditorTest [Fact] public void BuildTest() { - var encoding = Encoding.UTF8; - var url = new Uri("http://www.webapiclient.com"); - var editor = new UriEditor(url, encoding); + var editor = new UriEditor(url); Assert.False(editor.Replace("a", "a")); editor.AddQuery("a", "a"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/?a=a"); url = new Uri("http://www.webapiclient.com/path"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "a"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path?a=a"); url = new Uri("http://www.webapiclient.com/path/"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "a"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path/?a=a"); url = new Uri("http://www.webapiclient.com/path/?"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "a"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path/?a=a"); url = new Uri("http://www.webapiclient.com/path?x=1"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "a"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path?x=1&a=a"); url = new Uri("http://www.webapiclient.com/path?x=1&"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "a"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path?x=1&a=a"); url = new Uri("http://www.webapiclient.com/path?x=1&"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "我"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path?x=1&a=我"); url = new Uri("http://www.webapiclient.com/path/?x=1&"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "我"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path/?x=1&a=我"); url = new Uri("http://www.webapiclient.com/path/?x={x}&"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "我"); editor.Replace("x", "你"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/path/?x=你&a=我"); url = new Uri("http://www.webapiclient.com"); - editor = new UriEditor(url, encoding); + editor = new UriEditor(url); editor.AddQuery("a", "我"); editor.AddQuery("b", "你"); Assert.True(editor.Uri.ToString() == "http://www.webapiclient.com/?a=我&b=你"); diff --git a/WebApiClient/Attributes/ParameterAttributes/PathQueryAttribute.cs b/WebApiClient/Attributes/ParameterAttributes/PathQueryAttribute.cs index 7eeac08b..cd2b0761 100644 --- a/WebApiClient/Attributes/ParameterAttributes/PathQueryAttribute.cs +++ b/WebApiClient/Attributes/ParameterAttributes/PathQueryAttribute.cs @@ -16,12 +16,14 @@ public class PathQueryAttribute : Attribute, IApiParameterAttribute, IIgnoreWhen /// <summary> /// 编码 /// </summary> + [Obsolete] private Encoding encoding = System.Text.Encoding.UTF8; /// <summary> /// 获取或设置参数的编码名称 /// </summary> /// <exception cref="ArgumentException"></exception> + [Obsolete("Encoding将不再生效")] public string Encoding { get => this.encoding.WebName; @@ -104,7 +106,7 @@ public async Task BeforeRequestAsync(ApiActionContext context, ApiParameterDescr /// <returns></returns> protected virtual Uri UsePathQuery(Uri uri, IEnumerable<KeyValuePair<string, string>> keyValues) { - var editor = new UriEditor(uri, this.encoding); + var editor = new UriEditor(uri); foreach (var keyValue in keyValues) { if (editor.Replace(keyValue.Key, keyValue.Value) == false) diff --git a/WebApiClient/HttpApiRequestMessage.cs b/WebApiClient/HttpApiRequestMessage.cs index 92245c6c..7726a84d 100644 --- a/WebApiClient/HttpApiRequestMessage.cs +++ b/WebApiClient/HttpApiRequestMessage.cs @@ -41,7 +41,10 @@ public HttpApiRequestMessage() /// <exception cref="ArgumentNullException"></exception> public void AddUrlQuery(IEnumerable<KeyValuePair<string, string>> keyValue) { - this.AddUrlQuery(keyValue, Encoding.UTF8); + foreach (var kv in keyValue) + { + this.AddUrlQuery(kv); + } } /// <summary> @@ -51,11 +54,12 @@ public void AddUrlQuery(IEnumerable<KeyValuePair<string, string>> keyValue) /// <param name="encoding">编码</param> /// <exception cref="HttpApiConfigException"></exception> /// <exception cref="ArgumentNullException"></exception> + [Obsolete("encoding参数不会再使用")] public void AddUrlQuery(IEnumerable<KeyValuePair<string, string>> keyValue, Encoding encoding) { foreach (var kv in keyValue) { - this.AddUrlQuery(kv, encoding); + this.AddUrlQuery(kv); } } @@ -67,7 +71,7 @@ public void AddUrlQuery(IEnumerable<KeyValuePair<string, string>> keyValue, Enco /// <exception cref="ArgumentNullException"></exception> public void AddUrlQuery(KeyValuePair<string, string> keyValue) { - this.AddUrlQuery(keyValue, Encoding.UTF8); + AddUrlQuery(keyValue.Key, keyValue.Value); } /// <summary> @@ -77,9 +81,10 @@ public void AddUrlQuery(KeyValuePair<string, string> keyValue) /// <param name="encoding">编码</param> /// <exception cref="HttpApiConfigException"></exception> /// <exception cref="ArgumentNullException"></exception> + [Obsolete("encoding参数不会再使用")] public void AddUrlQuery(KeyValuePair<string, string> keyValue, Encoding encoding) { - this.AddUrlQuery(keyValue.Key, keyValue.Value, encoding); + this.AddUrlQuery(keyValue.Key, keyValue.Value); } @@ -91,19 +96,6 @@ public void AddUrlQuery(KeyValuePair<string, string> keyValue, Encoding encoding /// <exception cref="HttpApiConfigException"></exception> /// <exception cref="ArgumentNullException"></exception> public void AddUrlQuery(string key, string value) - { - this.AddUrlQuery(key, value, Encoding.UTF8); - } - - /// <summary> - /// 追加Query参数到请求路径 - /// </summary> - /// <param name="key">参数名</param> - /// <param name="value">参数值</param> - /// <param name="encoding">编码</param> - /// <exception cref="HttpApiConfigException"></exception> - /// <exception cref="ArgumentNullException"></exception> - public void AddUrlQuery(string key, string value, Encoding encoding) { if (this.RequestUri == null) { @@ -115,16 +107,25 @@ public void AddUrlQuery(string key, string value, Encoding encoding) throw new ArgumentNullException(nameof(key)); } - if (encoding == null) - { - throw new ArgumentNullException(nameof(encoding)); - } - - var editor = new UriEditor(this.RequestUri, encoding); + var editor = new UriEditor(this.RequestUri); editor.AddQuery(key, value); this.RequestUri = editor.Uri; } + /// <summary> + /// 追加Query参数到请求路径 + /// </summary> + /// <param name="key">参数名</param> + /// <param name="value">参数值</param> + /// <param name="encoding">编码</param> + /// <exception cref="HttpApiConfigException"></exception> + /// <exception cref="ArgumentNullException"></exception> + [Obsolete("encoding参数不会再使用")] + public void AddUrlQuery(string key, string value, Encoding encoding) + { + AddUrlQuery(key, value); + } + /// <summary> /// 添加字段到已有的Content /// 要求content-type为application/x-www-form-urlencoded diff --git a/WebApiClient/Internal/HttpContents/UrlEncodedContent.cs b/WebApiClient/Internal/HttpContents/UrlEncodedContent.cs index e4b092fc..3ac7c683 100644 --- a/WebApiClient/Internal/HttpContents/UrlEncodedContent.cs +++ b/WebApiClient/Internal/HttpContents/UrlEncodedContent.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Http; @@ -143,7 +142,8 @@ private static string Encode(string value) { return string.Empty; } - return Uri.EscapeDataString(value).Replace("%20", "+"); + + return HttpUtility.UrlEncode(value, Encoding.UTF8); } /// <summary> diff --git a/WebApiClient/Internal/UriEditor.cs b/WebApiClient/Internal/UriEditor.cs index 1b0f2b29..f09a06d8 100644 --- a/WebApiClient/Internal/UriEditor.cs +++ b/WebApiClient/Internal/UriEditor.cs @@ -1,5 +1,4 @@ using System; -using System.Text; using System.Text.RegularExpressions; namespace WebApiClient @@ -51,34 +50,15 @@ private set this.uriCanReplace = value.OriginalString.IndexOf('{') > -1; } } - - /// <summary> - /// 获取Uri参数的编码 - /// </summary> - public Encoding Encoding { get; } - - /// <summary> - /// Uri编辑器 - /// </summary> - /// <param name="uri">绝对路径的uri</param> - /// <exception cref="ArgumentNullException"></exception> - /// <exception cref="UriFormatException"></exception> - public UriEditor(Uri uri) - : this(uri, Encoding.UTF8) - { - } - /// <summary> /// Url创建者 /// </summary> - /// <param name="uri">绝对路径的uri</param> - /// <param name="encoding">参数的编码</param> + /// <param name="uri">绝对路径的uri</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="UriFormatException"></exception> - public UriEditor(Uri uri, Encoding encoding) + public UriEditor(Uri uri) { this.Uri = uri ?? throw new ArgumentNullException(nameof(uri)); - this.Encoding = encoding ?? throw new ArgumentNullException(nameof(encoding)); if (uri.IsAbsoluteUri == false) { throw new UriFormatException($"{nameof(uri)}必须为绝对完整URI"); @@ -104,12 +84,11 @@ public bool Replace(string name, string value) } var replaced = false; - var regex = new Regex($"{{{name}}}", RegexOptions.IgnoreCase); - var url = regex.Replace(this.Uri.OriginalString, m => + var url = Regex.Replace(this.Uri.OriginalString, $"{{{name}}}", m => { replaced = true; - return HttpUtility.UrlEncode(value, this.Encoding); - }); + return value == null ? null : Uri.EscapeDataString(value); + }, RegexOptions.IgnoreCase); if (replaced == true) { @@ -131,8 +110,11 @@ public void AddQuery(string name, string value) throw new ArgumentNullException(nameof(name)); } - name = HttpUtility.UrlEncode(name, this.Encoding); - value = HttpUtility.UrlEncode(value, this.Encoding); + name = Uri.EscapeDataString(name); + if (value != null) + { + value = Uri.EscapeDataString(value); + } var pathQuery = this.GetPathAndQuery(); var concat = pathQuery.IndexOf('?') > -1 ? "&" : "?"; diff --git a/WebApiClient/WebApiClient.csproj b/WebApiClient/WebApiClient.csproj index e392c312bfdb600f946878d1131dc24108bb59d0..0c40667c515253f8740e4af54b889d8a225bb1c9 100644 GIT binary patch delta 14 VcmdlKyD4@<1Q(;p=18tc6#y(a1o;2} delta 14 VcmdlKyD4@<1Q(<6=18tc6#y(U1o!{| From 86bf22920a49eab9de3ae53af65a5766f1b6ef77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com> Date: Fri, 17 Jul 2020 20:57:28 +0800 Subject: [PATCH 2/2] Update README.md --- README.md | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index ac1a4508..c3668985 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,11 @@ -## WebApiClient -### 1 Nuget包 - -> WebApiClient.JIT - - PM> install-package WebApiClient.JIT -* 不适用于不支持JIT技术的平台(IOS、UWP); -* Http接口声明要求为public; - - -> WebApiClient.AOT - - PM> install-package WebApiClient.AOT -* 适用于不支持JIT技术的平台(IOS、UWP); -* Http接口声明不要求为public,可以嵌套在类里面; +## WebApiClient +一款声明式的http客户端库,只需要定义c#接口并修饰相关特性,即可异步调用远程http接口。 +### 1 Nuget包 +| 包名 | 描述 | Nuget | +---|---|--| +| WebApiClient.JIT | 适用于非AOT编译的所有平台,稳定性好 | [](https://www.nuget.org/packages/WebApiClient.JIT) | +| WebApiClient.AOT | 适用于所有平台,包括IOS和UWP,复杂依赖项目可能编译不通过 | [](https://www.nuget.org/packages/WebApiClient.AOT) | ### 2. Http请求 > 接口的声明 @@ -51,26 +43,15 @@ var api = HttpApi.Resolve<IUserApi>(); var user = new UserInfo { Account = "laojiu", Password = "123456" }; var user1 = await api.GetAsync("laojiu"); var state = await api.AddAsync(user); -``` - -#### 3. Api变化 -> 相对于[v0.3.6](https://github.com/dotnetcore/WebApiClient/tree/v0.3.6)或以前版本,Api有如下变化 - -* ~~HttpApiClient.Create()~~ -> HttpApi.Create() -* ~~HttpApiFactory.Add()~~ -> HttpApi.Register() -* ~~HttpApiFactory.Create()~~ -> HttpApi.Resolve() -* ~~Timeout~~ -* ~~UrlAttribute~~ -* ~~DebugAttribute~~ +``` -#### 4. Wiki文档 +#### 3. Wiki文档 1. [WebApiClient基础](https://github.com/dotnetcore/WebApiClient/wiki/WebApiClient%E5%9F%BA%E7%A1%80) 2. [WebApiClient进阶](https://github.com/dotnetcore/WebApiClient/wiki/WebApiClient%E8%BF%9B%E9%98%B6) 3. [WebApiClient高级](https://github.com/dotnetcore/WebApiClient/wiki/WebApiClient%E9%AB%98%E7%BA%A7) 4. [WebApiClient.Extensions](https://github.com/xljiulang/WebApiClient.Extensions) 5. [WebApiClient.Tools.Swagger](https://github.com/xljiulang/WebApiClient.Tools) -#### 5. 联系方式 -1. 加Q群825135345 注明WeApiClient -2. 邮箱366193849@qq.com,不重要的尽量不要发 +### 4 QQ群 +> 加Q群[825135345](https://shang.qq.com/wpa/qunwpa?idkey=c6df21787c9a774ca7504a954402c9f62b6595d1e63120eabebd6b2b93007410),注明WeApiClient