ASP.NET 核心 3.1 的 JsonHttpContent
JsonHttpContent with ASP.NET Core 3.1
我创建了一个自定义 HttpContent 以使用 System.Text.Json 和 HttpClient 有效地发送对象。遗憾的是,关于如何正确执行此操作的文档很少。以下 class 导致在我的测试端点出现格式错误的 JSON 数据错误。查看 wireshark 中的数据包显示仅传输了一个空的 json 对象 ({}
)。我还尝试刷新流(相同的结果)或在写入流后将其处置(这导致有关 tring 访问已处置对象的错误)。
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Common
{
public sealed class JsonContent : HttpContent
{
private readonly object _content;
private readonly JsonSerializerOptions _options;
public JsonContent(object content, JsonSerializerOptions options)
{
_content = content;
_options = options;
Headers.ContentType = new MediaTypeHeaderValue("application/json")
{
CharSet = Encoding.UTF8.WebName
};
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return JsonSerializer.SerializeAsync(stream, _content, _options);
}
protected override bool TryComputeLength(out long length)
{
length = 0;
return false;
}
}
}
整个东西是这样使用的:
public static async Task<HttpResponseMessage> PostAsJsonAsync<T>(this HttpClient client, string url, T content,
CancellationToken ct = default) where T : class
{
return await client.PostAsync(url, new JsonContent(content, Json.DefaultSerializerOptions), ct);
}
我在这里错过了什么?
你的对象是否包含字段或属性..System.Text.Json不会序列化字段..
看来,你错过了_content
的类型。试试这个:
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return JsonSerializer.SerializeAsync(stream, _content, _content.GetType(), _options);
}
你调用的方法实际上是SerializeAsync<TValue>(...)
,它使用typeof(TValue)
作为序列化的类型。因为你的 _content
是 object
的实例,所以 TValue
在这种情况下是 object
,因此 _content
被序列化为 object
。这就是为什么你只看到 {}
.
此修复调用了另一个重载 SerializeAsync(...)
,它允许您指定要序列化的正确类型。
我创建了一个自定义 HttpContent 以使用 System.Text.Json 和 HttpClient 有效地发送对象。遗憾的是,关于如何正确执行此操作的文档很少。以下 class 导致在我的测试端点出现格式错误的 JSON 数据错误。查看 wireshark 中的数据包显示仅传输了一个空的 json 对象 ({}
)。我还尝试刷新流(相同的结果)或在写入流后将其处置(这导致有关 tring 访问已处置对象的错误)。
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Common
{
public sealed class JsonContent : HttpContent
{
private readonly object _content;
private readonly JsonSerializerOptions _options;
public JsonContent(object content, JsonSerializerOptions options)
{
_content = content;
_options = options;
Headers.ContentType = new MediaTypeHeaderValue("application/json")
{
CharSet = Encoding.UTF8.WebName
};
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return JsonSerializer.SerializeAsync(stream, _content, _options);
}
protected override bool TryComputeLength(out long length)
{
length = 0;
return false;
}
}
}
整个东西是这样使用的:
public static async Task<HttpResponseMessage> PostAsJsonAsync<T>(this HttpClient client, string url, T content,
CancellationToken ct = default) where T : class
{
return await client.PostAsync(url, new JsonContent(content, Json.DefaultSerializerOptions), ct);
}
我在这里错过了什么?
你的对象是否包含字段或属性..System.Text.Json不会序列化字段..
看来,你错过了_content
的类型。试试这个:
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return JsonSerializer.SerializeAsync(stream, _content, _content.GetType(), _options);
}
你调用的方法实际上是SerializeAsync<TValue>(...)
,它使用typeof(TValue)
作为序列化的类型。因为你的 _content
是 object
的实例,所以 TValue
在这种情况下是 object
,因此 _content
被序列化为 object
。这就是为什么你只看到 {}
.
此修复调用了另一个重载 SerializeAsync(...)
,它允许您指定要序列化的正确类型。