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