我需要流式传输大型对象。我无法弄清楚如何以块的形式发送它。但是,发布的代码有效, stream.Flush()只会被调用一次。所以,基本上我是在缓冲对象 - 不好。如何多次调用 stream.Flush()?如果我有一个集合,我可以循环/刷新。那么如何用大型物体做到这一点?
服务器代码:
public async Task<HttpResponseMessage> ConvertToTiffAsync([FromBody] DocumentDto dto)
{
// THIS IS LARGE
var document = await _service.ConvertToTiffAsync(dto);
var response = Request.CreateResponse();
response.Content = new PushStreamContent((stream, content, context) =>
{
var serializer = new JsonSerializer();
using (var writer = new StreamWriter(stream))
{
using (var jsonTextWriter = new JsonTextWriter(writer))
{
serializer.Serialize(jsonTextWriter, document);
stream.Flush(); // ONLY CALLED ONCE - NEED MANY CALLS
}
}
});
return response;
}
客户端代码(流媒体不在这里,但需要):
using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.Timeout = new TimeSpan(0, 5, 0);
var stringContent = new StringContent(JsonConvert.SerializeObject(dto), Encoding.UTF8, "application/json");
using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, endpoint))
{
httpRequest.Content = stringContent;
using (HttpResponseMessage response = await client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
using (var streamReader = new StreamReader(await response.Content.ReadAsStreamAsync()))
using (var jsonReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
return await Task.Run(() => serializer.Deserialize<ConvertDocumentDto>(jsonReader)).ConfigureAwait(false);
}
}
}
}
答案 0 :(得分:0)
您的服务器代码似乎没问题。但是,您的客户端代码似乎无法与服务器正确交互。
如果要设置DocumentDto输入,则需要将JSON写入请求,而不是响应。如果要在内存中没有完整的JSON的情况下使用服务器操作,则需要一个JsonTextReader。所以一般在客户端应该是:
var client = new HttpClient();
var dtoContent = new PushStreamContent((stream, content, context) => {
var serializer = new JsonSerializer();
using (var streamWriter = new StreamWriter(stream))
{
using (var jsonWriter = new JsonTextWriter(streamWriter))
{ serializer.Serialize(jsonTextWriter, dto); }
}
});
using (var stream = await client.PostAsync(url, dtoContent).Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(stream))
{
using (var jsonReader = new JsonTextReader(streamReader))
{
document = JsonSerializer().Deserialize<Document>(jsonReader);
}
}
}
如果您的DTO很小并且您不介意在内存中使用完整的JSON而不是client.PostAsync(url),那么您还可以使用在HttpClientExtensions命名空间中的client.PostAsJsonAsync(url,dto)导入系统.Net.Http.Formatting.dll。