首先,我非常喜欢ASP.NET MVC。这个问题并不是在批评它,而是想确认自己所看到的并确保没有遗漏什么重要信息。请耐心听我讲述一下背景...
这个问题涉及到在HTTP Post请求中返回数据流。在ASP.NET MVC之前的旧时代,你可以通过将数据直接传送到响应流中来完成此操作。例如,你可能会像这样做:
someObjectThatDumpsOutputToWhateverStreamYouHandIt.WriteTo(Response.OutputStream);
请注意这段代码的一个关键方面:我没有实现任何后备存储。我不必将信息流式传输到字节数组中,也不必将其转储到临时文件中。相反,ASP.NET已经为与浏览器通信返回响应而设置了一个流,并且我直接将所需输出转储到该流中。与将所有数据复制到某个临时位置然后将其移动到响应流中相比,这样更有效率,更节省CPU、内存和执行时间。然而,这对于单元测试来说并不太友好。事实上,在ASP.NET MVC中仍然可以编写这种代码,但惯例是避免这样做。相反,ASP.NET MVC会鼓励你返回ActionResult。ActionResult是一个ASP.NET MVC概念,主要存在于单元测试友好性。它允许您“声明”您想要做什么。单元测试可以运行控制器操作并确认它获取了预期的ActionResult。该单元测试可以在浏览器之外运行。
ASP.NET MVC提供了一种返回数据流的ActionResult。它称为FileStreamResult。不要被名称中的“File”一词所迷惑。它是关于返回数据流的,就像我们上面所说的那样。
然而,这里有一个问题,也是我的问题的基础:如果您使Controller方法返回一个FileStreamResult,并将其设置为要返回的Stream,则似乎再也没有办法直接将数据转储到响应流中了。现在,您似乎被迫使用带有后备存储(例如内存或文件)的自己的Stream,将数据转储到其中,然后将该Stream交给您返回的FileStreamResult。
所以,看起来我必须像这样做(故意省略dispose/using等):
MemoryStream myIntermediateStream = new MemoryStream();
someObjectThatDumpsOutputToWhateverStreamYouHandIt.WriteTo(myIntermediateStream );
return new FileStreamResult(myIntermediateStream, "application/pdf");
注意,myIntermediateStream会导致大量数据的内容被临时存储在内存中,以便FileStreamResult稍后可以将其再次复制到Response输出流中。
因此,我的问题是:我是否忽略了什么,或者说使用FileStreamResult强制您拥有一个中间存储位置,如果直接写入Response的输出流,则不需要这样做?
谢谢。
FileStreamResult
的主要用例;当你只是从已提供给你的流中读取时,该结果类型更好,而不是向你创建的空流写入。这一切都取决于上下文;FileStreamResult
有其用途,但听起来这不是其中之一。 - Aaronaught