问题描述
由于一些奇怪的原因,我想直接写HTML从控制器操作的响应流。
(我的理解MVC分离,但这是一个特例。)
For some strange reasons, I want to write HTML directly to the Response stream from a controller action.(I understand MVC separation, but this is a special case.)
我可以直接写入到的Htt presponse流?在这种情况下,它的iView对象应控制器动作应该返回?我可以返回'空'?
Can I write directly into the HttpResponse stream? In that case, which IView object should the controller action should return? Can I return 'null'?
推荐答案
我使用 FileResult
派生的类来实现这个正常使用MVC模式:
I used a class derived from FileResult
to achieve this using normal MVC pattern:
/// <summary>
/// MVC action result that generates the file content using a delegate that writes the content directly to the output stream.
/// </summary>
public class FileGeneratingResult : FileResult
{
/// <summary>
/// The delegate that will generate the file content.
/// </summary>
private readonly Action<System.IO.Stream> content;
private readonly bool bufferOutput;
/// <summary>
/// Initializes a new instance of the <see cref="FileGeneratingResult" /> class.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="content">Delegate with Stream parameter. This is the stream to which content should be written.</param>
/// <param name="bufferOutput">use output buffering. Set to false for large files to prevent OutOfMemoryException.</param>
public FileGeneratingResult(string fileName, string contentType, Action<System.IO.Stream> content,bool bufferOutput=true)
: base(contentType)
{
if (content == null)
throw new ArgumentNullException("content");
this.content = content;
this.bufferOutput = bufferOutput;
FileDownloadName = fileName;
}
/// <summary>
/// Writes the file to the response.
/// </summary>
/// <param name="response">The response object.</param>
protected override void WriteFile(System.Web.HttpResponseBase response)
{
response.Buffer = bufferOutput;
content(response.OutputStream);
}
}
控制器方法现在会是这样的:
The controller method would now be like this:
public ActionResult Export(int id)
{
return new FileGeneratingResult(id + ".csv", "text/csv",
stream => this.GenerateExportFile(id, stream));
}
public void GenerateExportFile(int id, Stream stream)
{
stream.Write(/**/);
}
注意,如果缓冲被关闭,
Note that if buffering is turned off,
stream.Write(/**/);
变得极为缓慢。的解决方案是使用一个BufferedStream。约这样做更好的性能在一个案件100倍。见
becomes extremely slow. The solution is to use a BufferedStream. Doing so improved performance by approximately 100x in one case. See
这篇关于写入输出流的操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!