Исключение BinaryWrite "OutputStream недоступен, когда используется пользовательский TextWriter" в MVC 2 ASP.NET 4
У меня есть представление рендеринга потока с использованием метода ответа BinaryWrite. Это все работало нормально в ASP.NET 4 с использованием Beta 2, но выдает это исключение в выпуске 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>
Представление генерируется с помощью перенаправления на стороне клиента (вызов местоположения jquery replace на предыдущей странице с использованием помощника Url.Action для отображения ссылки, конечно). Это все в фрейме.
У кого-нибудь есть идея, почему это происходит?
3 ответа
Когда ViewPage начинает выполняться, он предполагает определенные вещи относительно оставшейся части запроса. Особенность, которая сбивает вас с толку, заключается в том, что ViewPage предполагает, что оставшаяся часть запроса будет обычным HTML или каким-либо другим текстовым ответом, поэтому он переключает TextWriter ответа со своим собственным модулем записи.
В вашем случае вы должны создать новый производный от ActionResult класс, чей метод ExecuteResult инкапсулирует логику в вашем методе Page_Load. Ваш метод действия должен возвращать экземпляр вашего пользовательского класса, и вызывающий будет запускать метод ExecuteResult в соответствующее время. Это полностью обходит механизмы представления, что предотвращает ошибку, с которой вы работаете, и дает небольшое повышение производительности.
Я сделал ответ Леви. Это на самом деле очень просто. Мой код записывает в ответ изображение, которое ранее получалось из файловой системы после различных проверок.
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);
Кто-то пометит ответ Леви как ответ!
Еще один способ сделать что-то подобное, это использовать встроенный File
ActionResult
:
var bytes = GetPdfBytes("Performance Report", htmlString);
return File(bytes, "binary/octet-stream", "Performance Report.pdf");