Using JSON.NET to serialize object into HttpClient's response stream

前端 未结 2 685
温柔的废话
温柔的废话 2020-12-20 00:48

Abstract

Hi, I\'m working on a project where it is needed to send potentially huge json of some object via HttpClient, a 10-20 mb of JSON is a typical size. In orde

相关标签:
2条回答
  • 2020-12-20 01:07

    Use PushStreamContent. Rather than have Web API "pull" from a stream, it lets you more intuitively "push" into one.

    object value = ...;
    
    PushStreamContent content = new PushStreamContent((stream, httpContent, transportContext) =>
    {
        using (var tw = new StreamWriter(stream))
        {
            JsonSerializer ser = new JsonSerializer();
            ser.Serialize(tw, value);
        }
    });
    

    Note that JSON.NET doesn't support async during serialization so while this may be more memory efficient, it won't be very scalable.

    I'd recommend trying to avoid such large JSON objects, though. Try to chunk it up, for instance, if you're sending over a large collection. Many clients/servers will flat out reject something so big without special handling.

    0 讨论(0)
  • 2020-12-20 01:24

    If you define a subclass of HttpContent :

    public class JsonContent:HttpContent
    {
        public object SerializationTarget{get;private set;}
        public JsonContent(object serializationTarget)
        {
            SerializationTarget=serializationTarget;
            this.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
        protected override async Task SerializeToStreamAsync(Stream stream, 
                                                    TransportContext context)
        {
            using(StreamWriter writer = new StreamWriter(stream))
            using(JsonTextWriter jsonWriter = new JsonTextWriter(writer))
            {
                JsonSerializer ser = new JsonSerializer();
                ser.Serialize(jsonWriter, SerializationTarget );
            }
    
        }   
    
        protected override bool TryComputeLength(out long length)
        {
            //we don't know. can't be computed up-front
            length = -1;
            return false;
        }
    }
    

    then you can:

    var someObj = new {a = 1, b = 2};
    var client = new HttpClient();
    var content = new JsonContent(someObj);
    var responseMsg = await client.PostAsync("http://someurl",content);
    

    and the serializer will write directly to the request stream.

    0 讨论(0)
提交回复
热议问题