由於一些奇怪的原因,我想直接從控制器操作將HTML寫入Response流。 (我理解MVC分離,但這是一個特殊情況。)從動作寫入輸出流
我可以直接寫入HttpResponse
流嗎?在那種情況下,控制器動作應該返回哪個IView
對象?我可以返回'空'嗎?
由於一些奇怪的原因,我想直接從控制器操作將HTML寫入Response流。 (我理解MVC分離,但這是一個特殊情況。)從動作寫入輸出流
我可以直接寫入HttpResponse
流嗎?在那種情況下,控制器動作應該返回哪個IView
對象?我可以返回'空'嗎?
你可以做return Content(...);
的地方,如果我沒有記錯,...
將要直接寫入到輸出流,或者什麼都沒有的東西。
看看在Controller
的Content
方法:http://aspnet.codeplex.com/SourceControl/changeset/view/22907#266451
而且ContentResult
:http://aspnet.codeplex.com/SourceControl/changeset/view/22907#266450
是的,你可以直接寫入響應。完成後,您可以調用CompleteRequest(),並且不需要返回任何內容。
例如:
// GET: /Test/Edit/5
public ActionResult Edit(int id)
{
Response.Write("hi");
HttpContext.ApplicationInstance.CompleteRequest();
return View(); // does not execute!
}
寫自己的操作結果。這裏的礦井中的一個的示例:
public class RssResult : ActionResult
{
public RssFeed RssFeed { get; set; }
public RssResult(RssFeed feed) {
RssFeed = feed;
}
public override void ExecuteResult(ControllerContext context) {
context.HttpContext.Response.ContentType = "application/rss+xml";
SyndicationResourceSaveSettings settings = new SyndicationResourceSaveSettings();
settings.CharacterEncoding = new UTF8Encoding(false);
RssFeed.Save(context.HttpContext.Response.OutputStream, settings);
}
}
我用從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(/**/);
變得非常緩慢。解決方案是使用BufferedStream。在一種情況下,性能提高了約100倍。見
如果你不想得到你自己的結果類型,你可以簡單地寫Response.OutputStream
並返回new EmptyResult()
。
您應該避免Response.End()http://stevesmithblog.com/blog/use-httpapplication-completerequest-instead-of-response-end/ – 2009-06-03 05:10:26
然後更新以使用CompleteRequest()。 – womp 2009-06-03 06:09:05