在MVC 2 ASP.NET 4中使用自定义TextWriter时,BinaryWrite异常“OutputStream不可用”

时间:2010-02-14 13:32:40

标签: asp.net-mvc-2 response httpexception

我有一个使用响应BinaryWrite方法渲染流的视图。在使用Beta 2的ASP.NET 4下,这一切都运行良好,但在RC版本中引发了这个异常:

  

“HttpException”,“OutputStream不是   自定义TextWriter时可用   用过的。”   

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">
protected void  Page_Load(object sender, EventArgs e)
{
    if (ViewData["Error"] == null)
    {

        Response.Buffer = true;
        Response.Clear();
        Response.ContentType = ViewData["DocType"] as string;
        Response.AddHeader("content-disposition", ViewData["Disposition"] as string);
        Response.CacheControl = "No-cache";
        MemoryStream stream = ViewData["DocAsStream"] as MemoryStream;
        Response.BinaryWrite(stream.ToArray());
        Response.Flush();
        Response.Close();
    }
}   
</script>


</script>

视图是从客户端重定向生成的(使用Url.Action帮助程序在前一页中使用jquery替换位置调用来渲染链接)。这都在iframe中。

任何人都知道为什么会这样?

3 个答案:

答案 0 :(得分:17)

当ViewPage开始执行时,它会假定有关请求的其余部分的某些事情。绊倒你的特殊事情是,ViewPage假定请求的其余部分将是普通的HTML或其他一些文本响应,因此它会将响应的TextWriter切换为自己的编写器。

在您的情况下,您应该创建一个新的ActionResult派生类,其ExecuteResult方法将逻辑封装在Page_Load方法中。您的action方法应返回自定义类的实例,并且调用者将在适当的时间运行ExecuteResult方法。这完全绕过了视图引擎,这可以防止您运行的错误并为您带来轻微的性能提升。

答案 1 :(得分:11)

我做了Levi的回答。这实际上非常简单。我的代码将一个图像写入响应,该响应先前是在各种检查后从文件系统中获取的。

public class BookImageResult : ActionResult
{
    private readonly GraphicReport graphicReport;

    public BookImageResult(GraphicReport graphicReport)
    {
        this.graphicReport = graphicReport;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.RequestContext.HttpContext.Response;
        response.Clear();
        response.ContentType = graphicReport.ContentType;
        response.BinaryWrite(graphicReport.Image);
        response.End();
    }
}

控制器末尾的行看起来像这样:

return new BookImageResult(graphicReport);

有人将Levi的回答标记为答案!

答案 2 :(得分:2)

执行类似操作的另一种方法是使用内置File ActionResult

var bytes = GetPdfBytes("Performance Report", htmlString);
return File(bytes, "binary/octet-stream", "Performance Report.pdf");