Skip to content

Commit 4db2d76

Browse files
committed
原始类型返回声明,accpet头设置为默认为空;
完善MediaType的匹配计算; 默认的accpet的q值设置为0.001的最小值;
1 parent 36b388e commit 4db2d76

File tree

9 files changed

+129
-18
lines changed

9 files changed

+129
-18
lines changed

App/App.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<TargetFramework>net5.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>

App/Clients/IUserApi.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ namespace App.Clients
1515
[LoggingFilter]
1616
[OAuthToken]
1717
[HttpHost("http://localhost:6000/")]
18-
[JsonNetReturn]
1918
public interface IUserApi : IHttpApi
2019
{
2120
[HttpGet("api/users/{account}")]
@@ -31,7 +30,7 @@ public interface IUserApi : IHttpApi
3130

3231

3332
[HttpGet("api/users/{account}")]
34-
[XmlReturn]
33+
[XmlReturn]
3534
ITask<string> GetExpectXmlAsync([Required] string account, CancellationToken token = default);
3635

3736

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Xunit;
2+
3+
namespace WebApiClientCore.Test.ResponseCaches
4+
{
5+
public class MediaTypeTest
6+
{
7+
[Fact]
8+
public void IsMatchTest()
9+
{
10+
Assert.True(MediaType.IsMatch("a/a", "a/a"));
11+
Assert.True(MediaType.IsMatch("a/a", "a/a"));
12+
Assert.True(MediaType.IsMatch("a/a", "A/a"));
13+
Assert.True(MediaType.IsMatch("a/a", "A/A"));
14+
15+
Assert.True(MediaType.IsMatch("a/*", "A/A"));
16+
Assert.True(MediaType.IsMatch("*/*", "A/A"));
17+
18+
Assert.False(MediaType.IsMatch("a/b", "a/a"));
19+
Assert.False(MediaType.IsMatch("a/B", "A/a"));
20+
Assert.False(MediaType.IsMatch("a/b", "A/A"));
21+
22+
Assert.False(MediaType.IsMatch("a/*", "b/A"));
23+
Assert.False(MediaType.IsMatch("a/*", null));
24+
Assert.False(MediaType.IsMatch("a/*", ""));
25+
Assert.False(MediaType.IsMatch("a", "a/a"));
26+
}
27+
28+
}
29+
}

WebApiClientCore/ApiReturnDescriptor.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,13 @@ public ApiReturnDescriptor(MethodInfo method, Type interfaceType)
7979
/// <returns></returns>
8080
private static IEnumerable<IApiReturnAttribute> GetDefaultAttributes(ApiDataTypeDescriptor dataType)
8181
{
82-
const double acceptQuality = 0.01d;
82+
const double acceptQuality = 0.001;
8383
if (dataType.IsRawType == true)
8484
{
8585
yield return new RawReturnAttribute(acceptQuality);
86-
yield return new JsonReturnAttribute(acceptQuality);
87-
yield return new XmlReturnAttribute(acceptQuality);
8886
}
8987
else
90-
{
88+
{
9189
yield return new JsonReturnAttribute(acceptQuality);
9290
yield return new XmlReturnAttribute(acceptQuality);
9391
yield return new NoneReturnAttribute(acceptQuality);

WebApiClientCore/Attributes/ReturnAttributes/ApiReturnAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public async Task OnResponseAsync(ApiResponseContext context)
105105
/// <returns></returns>
106106
protected virtual bool IsMatchAcceptContentType(MediaTypeHeaderValue? responseContentType)
107107
{
108-
return string.Equals(this.AcceptContentType.MediaType, responseContentType?.MediaType, StringComparison.OrdinalIgnoreCase);
108+
return MediaType.IsMatch(this.AcceptContentType.MediaType, responseContentType?.MediaType);
109109
}
110110

111111
/// <summary>

WebApiClientCore/Attributes/ReturnAttributes/JsonReturnAttribute.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Net.Http.Headers;
1+
using System.Net.Http.Headers;
32
using System.Threading.Tasks;
43
using WebApiClientCore.HttpContents;
54

@@ -13,7 +12,7 @@ public class JsonReturnAttribute : ApiReturnAttribute
1312
/// <summary>
1413
/// text/json
1514
/// </summary>
16-
private static readonly string textJson ="text/json";
15+
private static readonly string textJson = "text/json";
1716

1817
/// <summary>
1918
/// json内容的结果特性
@@ -40,8 +39,7 @@ public JsonReturnAttribute(double acceptQuality)
4039
/// <returns></returns>
4140
protected override bool IsMatchAcceptContentType(MediaTypeHeaderValue? responseContentType)
4241
{
43-
return base.IsMatchAcceptContentType(responseContentType) ||
44-
string.Equals(textJson, responseContentType?.MediaType, StringComparison.OrdinalIgnoreCase);
42+
return base.IsMatchAcceptContentType(responseContentType) || MediaType.IsMatch(textJson, responseContentType?.MediaType);
4543
}
4644

4745
/// <summary>

WebApiClientCore/Attributes/ReturnAttributes/XmlReturnAttribute.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Net.Http.Headers;
1+
using System.Net.Http.Headers;
32
using System.Threading.Tasks;
43
using WebApiClientCore.HttpContents;
54

@@ -40,8 +39,7 @@ public XmlReturnAttribute(double acceptQuality)
4039
/// <returns></returns>
4140
protected override bool IsMatchAcceptContentType(MediaTypeHeaderValue? responseContentType)
4241
{
43-
return base.IsMatchAcceptContentType(responseContentType) ||
44-
string.Equals(textXml, responseContentType?.MediaType, StringComparison.OrdinalIgnoreCase);
42+
return base.IsMatchAcceptContentType(responseContentType) || MediaType.IsMatch(textXml, responseContentType?.MediaType);
4543
}
4644

4745
/// <summary>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
3+
namespace WebApiClientCore
4+
{
5+
/// <summary>
6+
/// 提供媒体类型比较
7+
/// </summary>
8+
static class MediaType
9+
{
10+
/// <summary>
11+
/// 是否与目标匹配
12+
/// </summary>
13+
/// <param name="source"></param>
14+
/// <param name="target"></param>
15+
/// <returns></returns>
16+
public static bool IsMatch(string? source, string? target)
17+
{
18+
return IsMatch(source.AsSpan(), target.AsSpan());
19+
}
20+
21+
/// <summary>
22+
/// 是否与目标匹配
23+
/// </summary>
24+
/// <param name="source"></param>
25+
/// <param name="target"></param>
26+
/// <returns></returns>
27+
private static bool IsMatch(ReadOnlySpan<char> source, ReadOnlySpan<char> target)
28+
{
29+
var index = source.IndexOf('/');
30+
var sourceMain = index >= 0 ? source.Slice(0, index) : source;
31+
var sourceSub = index >= 0 ? source.Slice(index + 1) : ReadOnlySpan<char>.Empty;
32+
33+
index = target.IndexOf('/');
34+
var targetMain = index >= 0 ? target.Slice(0, index) : target;
35+
var targetSub = index >= 0 ? target.Slice(index + 1) : ReadOnlySpan<char>.Empty;
36+
37+
return MediaTypeMatch(sourceMain, targetMain) && MediaTypeMatch(sourceSub, targetSub);
38+
}
39+
40+
41+
/// <summary>
42+
/// MediaType是否匹配
43+
/// </summary>
44+
/// <param name="source"></param>
45+
/// <param name="target"></param>
46+
/// <returns></returns>
47+
private static bool MediaTypeMatch(ReadOnlySpan<char> source, ReadOnlySpan<char> target)
48+
{
49+
if (source.Length == 1 && source[0] == '*')
50+
{
51+
return true;
52+
}
53+
54+
if (target.Length == 1 && target[0] == '*')
55+
{
56+
return true;
57+
}
58+
59+
if (source.Length != target.Length)
60+
{
61+
return false;
62+
}
63+
64+
for (var i = 0; i < source.Length; i++)
65+
{
66+
var s = source[i];
67+
var t = target[i];
68+
if (char.IsUpper(s))
69+
{
70+
s = char.ToLowerInvariant(s);
71+
}
72+
if (char.IsUpper(t))
73+
{
74+
t = char.ToLowerInvariant(t);
75+
}
76+
77+
if (s.Equals(t) == false)
78+
{
79+
return false;
80+
}
81+
}
82+
return true;
83+
}
84+
}
85+
}

WebApiClientCore/BuildinUtils/MultiplableComparer.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ sealed class MultiplableComparer<TAttributeMultiplable> : IEqualityComparer<TAtt
2121
public bool Equals(TAttributeMultiplable x, TAttributeMultiplable y)
2222
{
2323
// 如果其中一个不允许重复,返回true将y过滤
24-
return x.AllowMultiple == false || y.AllowMultiple == false;
24+
if (x.GetType() == y.GetType())
25+
{
26+
return x.AllowMultiple == false || y.AllowMultiple == false;
27+
}
28+
return false;
2529
}
2630

2731
/// <summary>

0 commit comments

Comments
 (0)