正确的方式来读写web api响应流

时间:2017-03-29 18:57:43

标签: c# asp.net-web-api stream

我在寻找合适的咒语方面遇到了一些麻烦,这种咒语将允许我写入响应流,然后在测试中读取内容。目前我有这个

var res = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
var ms = new MemoryStream();
res.Content = new StreamContent(ms);
using (var sw = new StreamWriter(ms, System.Text.Encoding.UTF8))
using (var csv = new CsvHelper.CsvWriter(sw))
  csv.WriteRecords(allData.ToList());
return res;

在我的测试中,我正在尝试阅读此回复

  var controller = appContainer().Resolve<MyController>();
  var res = (await controller.Get()) as HttpResponseMessage;
  res.ShouldNotEqual(null);
  var csv = await res.Content.ReadAsStringAsync();

最后一行产生错误

Error while copying content to a stream.
  ----> System.ObjectDisposedException : Cannot access a closed Stream.

所以这里有几件事情

  • 为什么会发生此错误?如何在测试中正确预防?
  • 使用MemoryStream并不适合我,我不应该直接写入内容的流吗?是不是MemoryStream可能会大大增加我的内存使用量?

1 个答案:

答案 0 :(得分:0)

只是把它放在那里,尽管还不是很完美...使用PushStreamContent可以完成很多工作,但是它却带来了令人头疼的麻烦-即匿名方法可能产生的任何异常都会被吞噬并且难以跟踪下来而没有对问题的全面再现。当炸弹爆炸顺利通过时,管道api未处理的异常处理程序将生效,并且xmlhttprequest似乎无法识别关闭。

例如像

HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new PushStreamContent((stream, content, context) =>
{
     // write your output here
});
return response;

只要内部方法绝不会滑倒或以任何方式出错,

将为您提供所需的东西。

PushStreamContent会在调用匿名方法之前立即刷新您的http标头,因此您被分块了,无法稍后再卷回它。

您可以在匿名方法中添加try / catch以便在出现问题时给自己留下注释,但是以我的经验,XmlHttpRequest无法识别远程服务器何时强行关闭请求,因此它一直处于等待状态。才开始弄清楚当我把Fiddler放进去时发生了什么,而Fiddler嘎嘎作响。