使用流将Json转换为HttpContent

时间:2018-07-20 12:55:48

标签: c# serialization stream json.net httpclient

我有一个类MyData,该类可以通过使用Json.Net JsonSerializer.Serialize(TextWriter, object)进行Json序列化。我想通过HttpClient.PostAsync将此数据(作为json)发送到Web服务。

由于将json转换为字符串,然后以StringContent的形式发送,因此(可能)性能不佳,我想对流进行处理。

我找到了类StreamContent,该类在其构造函数中带有一个流。并且也可以将json序列化为流。所以我尝试了这个:

MyData data = ...; // already filled
string uri = ...;  // already filled
HttpClient client = new HttpClient();
JsonSerializer serializer = new JsonSerializer();
using (MemoryStream ms = new MemoryStream())
{
    using (StreamWriter sw = new StreamWriter(ms))
    using (JsonWriter jw = new JsonTextWriter(sw))
    {
        serializer.Serialize(sw, data);
        ms.Flush();
        ms.Position = 0;
    }
    HttpResponseMessage response = client.PostAsync(uri, new StreamContent(ms)).Result;
}

但是运行这段代码在HttpResponseMessage response = ...行中给了我两个例外:

  1. HttpRequestException:将内容复制到流中时出错。
  2. ObjectDisposedException:无法访问封闭的流。

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

如果将对象序列化为MemoryStream,则整个JSON数据将被写入缓冲区,因此与仅序列化为字符串并使用StringContent相比,没有明显的性能优势。

答案 1 :(得分:1)

您的StremWriter在发送请求之前会处理内存流,这就是为什么您会得到异常的原因。 您可以将using语句移动到与MemoryStream相同的作用域,也可以使用StreamWriter的构造函数,该构造函数接受布尔参数以在处理编写器之后使流保持打开状态。

StreamWriter constructor

  

除非将LeaveOpen参数设置为true,否则在调用StreamWriter.Dispose时,StreamWriter对象将在提供的Stream对象上调用Dispose()。