简体   繁体   English

JsonHttpContent 与 ASP.NET 核心 3.1

[英]JsonHttpContent with ASP.NET Core 3.1

I created a custom HttpContent to efficiently send objects using System.Text.Json with HttpClient.我创建了一个自定义 HttpContent 以使用带有 HttpClient 的 System.Text.Json 有效地发送对象。 Sadly there's very little documentation around how to correctly do this.遗憾的是,关于如何正确执行此操作的文档很少。 The following class results in an error about malformed JSON data at my test endpoint.以下 class 在我的测试端点导致错误的 JSON 数据错误。 Looking at the packets in wireshark shows that only an empty json object ( {} ) is transmitted.查看 wireshark 中的数据包显示,只传输了一个空的 json object ( {} )。 I also tried to flush the stream (same result) or dispose it after writing to it (this results in an error about tring to access a disposed object).我还尝试刷新 stream (结果相同)或在写入后将其处置(这会导致有关访问已处置对象的错误)。

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;
        }
    }
}

The whole thing is used like this:整个东西是这样使用的:

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);
}

What am I missing here?我在这里想念什么?

Seemingly, you have missed the type of _content .看起来,您错过了_content的类型。 Try this:尝试这个:

protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
    return JsonSerializer.SerializeAsync(stream, _content, _content.GetType(), _options);
}

The method you called was actually SerializeAsync<TValue>(...) , which uses typeof(TValue) as the type to serialize.您调用的方法实际上是SerializeAsync<TValue>(...) ,它使用typeof(TValue)作为序列化的类型。 Because your _content is an instance of object , so TValue in this case is object , thus _content was serialized as object .因为您的_contentobject的实例,所以这种情况下的TValueobject ,因此_content被序列化为object That is why you see only {} .这就是您只看到{}的原因。

The fix calls another overload SerializeAsync(...) which allows you to specify the correct type to serialize.该修复程序调用另一个重载SerializeAsync(...) ,它允许您指定要序列化的正确类型。

Does your object contain fields or properties.. System.Text.Json will not serialize fields..您的 object 是否包含字段或属性.. System.Text.Json 不会序列化字段..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM