由于某些奇怪的原因,我想将HTML直接写入控制器动作的响应流。
(我明白MVC的分离,但这是一个特例)
(我明白MVC的分离,但这是一个特例)
我可以直接写入HttpResponse流吗?在那种情况下,控制器动作应该返回哪个IView对象?我可以返回’null’吗?
解决方法
我使用从FileResult派生的类来实现这个使用正常的MVC模式:
/// <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); } }
控制器方法现在是这样的:
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(/**/); }
请注意,如果缓冲关闭,
stream.Write(/**/);