Write to HttpClient Request Stream with JSON.net

Viewed 1390

I have some rather big json's to send with a post request to an Api.

Using C# (Xamarin) I'd like to write this Json straight into the request stream.

I've tried implementing a custom HttpContent, but I either get a 'cannot read from a closed stream' exception (when i use dispose) or an empty body.

Please do not suggest using PushStreamContent, I do not have access to it in Xamarin, also I wish to understand this.

e.g.:

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



    // Should I dispose here or not ? When I do, the stream is 'closed'

    // When I do not dispose, the body seems to be empty

    // Should I Wrap this in a await Task.Run(() => {});
    // To make it 'async'






    }

    protected override bool TryComputeLength(out long length)
    {
        //we don't know. can't be computed up-front
        length = -1;
        return false;
    }
}

EDIT

After fiddling around I got it to work with the following:

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)
    {
        JsonSerializer ser = new JsonSerializer();

        StreamWriter writer = new StreamWriter(stream);
        JsonTextWriter jsonWriter = new JsonTextWriter(writer);
        ser.Serialize(jsonWriter, SerializationTarget);
        await jsonWriter.FlushAsync();
    }

    protected override bool TryComputeLength(out long length)
    {
        //we don't know. can't be computed up-front
        length = -1;
        return false;
    }
}

Although I do not get yet why I need to Flush and cannot dispose of the writers.

Looking at the documentation :

 Product product = new Product();
 product.ExpiryDate = new DateTime(2008, 12, 28);

 JsonSerializer serializer = new JsonSerializer();
 serializer.Converters.Add(new JavaScriptDateTimeConverter());
 serializer.NullValueHandling = NullValueHandling.Ignore;

 using (StreamWriter sw = new StreamWriter(@"c:\json.txt"))
 using (JsonWriter writer = new JsonTextWriter(sw))
 {
     serializer.Serialize(writer, product);
     // {"ExpiryDate":new Date(1230375600000),"Price":0}
 }
0 Answers
Related