Skip to content

Commit 748628b

Browse files
committed
提高JsonContentAttribute的性能
1 parent 655d4f9 commit 748628b

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

WebApiClientCore/Attributes/ParameterAttributes/JsonContentAttribute.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Diagnostics.CodeAnalysis;
3+
using System.Net.Http.Headers;
34
using System.Text;
45
using System.Threading.Tasks;
56
using WebApiClientCore.HttpContents;
@@ -36,9 +37,29 @@ public string CharSet
3637
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
3738
protected override Task SetHttpContentAsync(ApiParameterContext context)
3839
{
39-
var options = context.HttpContext.HttpApiOptions.JsonSerializeOptions;
40-
context.HttpContext.RequestMessage.Content = new JsonContent(context.ParameterValue, options, this.encoding);
40+
context.HttpContext.RequestMessage.Content = this.CreateContent(context);
4141
return Task.CompletedTask;
4242
}
43+
44+
[RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
45+
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
46+
#if NET5_0_OR_GREATER
47+
private System.Net.Http.Json.JsonContent CreateContent(ApiParameterContext context)
48+
{
49+
var value = context.ParameterValue;
50+
var options = context.HttpContext.HttpApiOptions.JsonSerializeOptions;
51+
var valueType = value == null ? context.Parameter.ParameterType : value.GetType();
52+
var mediaType = Encoding.UTF8.Equals(this.encoding) ? defaultMediaType : new MediaTypeHeaderValue(JsonContent.MediaType) { CharSet = this.CharSet };
53+
return System.Net.Http.Json.JsonContent.Create(value, valueType, mediaType, options);
54+
}
55+
private static readonly MediaTypeHeaderValue defaultMediaType = new(JsonContent.MediaType);
56+
#else
57+
private JsonContent CreateContent(ApiParameterContext context)
58+
{
59+
var value = context.ParameterValue;
60+
var options = context.HttpContext.HttpApiOptions.JsonSerializeOptions;
61+
return new JsonContent(value, options, this.encoding);
62+
}
63+
#endif
4364
}
4465
}

WebApiClientCore/HttpContents/BufferContent.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace WebApiClientCore.HttpContents
1111
{
1212
/// <summary>
13-
/// 表示 utf8 的BufferContent
13+
/// 表示缓冲的 Http 内容
1414
/// </summary>
1515
public class BufferContent : HttpContent, IBufferWriter<byte>
1616
{
@@ -20,21 +20,28 @@ public class BufferContent : HttpContent, IBufferWriter<byte>
2020
private readonly RecyclableBufferWriter<byte> bufferWriter = new();
2121

2222
/// <summary>
23-
/// utf8的BufferContent
23+
/// 缓冲的 Http 内容
2424
/// </summary>
2525
public BufferContent(string mediaType)
2626
: this(new MediaTypeHeaderValue(mediaType))
2727
{
2828
}
2929

3030
/// <summary>
31-
/// utf8的BufferContent
31+
/// 缓冲的 Http 内容
3232
/// </summary>
3333
public BufferContent(MediaTypeHeaderValue mediaType)
3434
{
3535
this.Headers.ContentType = mediaType;
3636
}
3737

38+
/// <summary>
39+
/// 缓冲的 Http 内容
40+
/// </summary>
41+
protected BufferContent()
42+
{
43+
}
44+
3845
/// <summary>
3946
/// 设置向前推进实际写入的数据长度
4047
/// </summary>

WebApiClientCore/HttpContents/JsonContent.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace WebApiClientCore.HttpContents
1313
public class JsonContent : BufferContent
1414
{
1515
private const string mediaType = "application/json";
16-
private static readonly MediaTypeHeaderValue mediaTypeHeaderValue = new(mediaType);
16+
private static readonly MediaTypeHeaderValue defaultMediaType = new(mediaType);
1717

1818
/// <summary>
1919
/// 获取对应的ContentType
@@ -24,7 +24,7 @@ public class JsonContent : BufferContent
2424
/// uft8 的 json 内容
2525
/// </summary>
2626
public JsonContent()
27-
: base(mediaTypeHeaderValue)
27+
: base(defaultMediaType)
2828
{
2929
}
3030

@@ -49,19 +49,18 @@ public JsonContent(object? value, JsonSerializerOptions? jsonSerializerOptions)
4949
[RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
5050
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
5151
public JsonContent(object? value, JsonSerializerOptions? jsonSerializerOptions, Encoding? encoding)
52-
: base(mediaTypeHeaderValue)
5352
{
5453
if (encoding == null || Encoding.UTF8.Equals(encoding))
5554
{
55+
this.Headers.ContentType = defaultMediaType;
5656
JsonBufferSerializer.Serialize(this, value, jsonSerializerOptions);
5757
}
5858
else
5959
{
60+
this.Headers.ContentType = new MediaTypeHeaderValue(mediaType) { CharSet = encoding.WebName };
6061
using var utf8Writer = new RecyclableBufferWriter<byte>();
6162
JsonBufferSerializer.Serialize(utf8Writer, value, jsonSerializerOptions);
62-
6363
Encoding.UTF8.Convert(encoding, utf8Writer.WrittenSpan, this);
64-
this.Headers.ContentType = new MediaTypeHeaderValue(mediaType) { CharSet = encoding.WebName };
6564
}
6665
}
6766
}

0 commit comments

Comments
 (0)