2010-02-14 15 views
15

Mam widok renderujący strumień przy użyciu metody BinaryWrite odpowiedzi. To wszystko działało w porządku pod ASP.NET 4 z wykorzystaniem Beta 2, ale rzuca ten wyjątek w wersji RC:wyjątek BinaryWrite "OutputStream nie jest dostępny, gdy niestandardowy TextWriter jest używany" w MVC 2 ASP.NET 4

"HttpException", „OutputStream nie jest dostępna, gdy zwyczaj TextWriter jest używany. "

<%@ 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> 

Widok jest generowany z przekierowaniem po stronie klienta (jQuery zastąpić połączenie lokalizacji w poprzedniej strony za pomocą Url.Action pomocnika do renderowania link oczywiście). To wszystko w iframe.

Ktoś wie, dlaczego tak się dzieje?

Odpowiedz

16

Po uruchomieniu funkcji ViewPage przyjmuje ona pewne elementy dotyczące pozostałej części żądania. Szczególną rzeczą, która Cię trapi jest to, że ViewPage zakłada, że ​​pozostała część żądania będzie normalnym kodem HTML lub inną odpowiedzią tekstową, więc przełącza TextWriter odpowiedzi na swój własny autor.

W twoim przypadku powinieneś utworzyć nową klasę pochodną ActionResult, której metoda ExecuteResult zapewnia hermetyzację logiki w twojej metodzie Page_Load. Twoja metoda działania powinna zwrócić instancję klasy niestandardowej, a wywoływacz uruchomi metodę ExecuteResult we właściwym czasie. Pomija to całkowicie mechanizmy wyświetlania, co zapobiega występowaniu błędu i nieznacznie poprawia wydajność.

+2

To jest poprawna odpowiedź –

10

Zrobiłem odpowiedź Leviego. To naprawdę bardzo proste. Mój kod zapisuje obraz do odpowiedzi, która została wcześniej pobrana z systemu plików po różnych sprawdzeniach.

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(); 
    } 
} 

Linia na końcu kontroler tylko wygląda następująco: odpowiedź znaku

return new BookImageResult(graphicReport); 

Ktoś Leviego jako odpowiedź!

+2

Dzięki za dodanie do próbki kodu. –

+0

Co z formularzami internetowymi? Próbuję użyć reportviewera. w ramach metody pageload. – JoshYates1980

2

Innym sposobem, aby zrobić coś podobnego jest użycie wbudowanych FileActionResult:

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