2010-02-14 4 views
15

Ich habe eine Ansicht, die einen Stream mit der Antwort-BinaryWrite-Methode rendert. Das alles hat gut funktioniert unter ASP.NET 4 mit der Beta 2 aber wirft diese Ausnahme in der RC-Version:BinaryWrite-Ausnahme "OutputStream ist nicht verfügbar, wenn ein benutzerdefinierter TextWriter verwendet wird" in MVC 2 ASP.NET 4

„Httpexception“, „Output ist nicht verfügbar, wenn eine benutzerdefinierte Textwriter ist verwendet. "

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

Die Ansicht von einem Client-Seite Redirect erzeugt wird (unter Verwendung von Url.Action helper die Verbindung natürlich machen jquery Lage Anruf in der vorherige Seite ersetzen). Dies ist alles in einem Iframe.

Jeder hat eine Idee, warum dies geschieht?

Antwort

16

Wenn eine ViewPage mit der Ausführung beginnt, werden bestimmte Dinge über den Rest der Anforderung angenommen. Das Besondere daran ist, dass eine ViewPage davon ausgeht, dass der Rest der Anfrage eine normale HTML- oder eine andere textuelle Antwort ist, so dass sie den TextWriter der Antwort mit einem eigenen Schreiber umschaltet.

In Ihrem Fall sollten Sie eine neue ActionResult-abgeleitete Klasse erstellen, deren ExecuteResult-Methode die Logik in Ihrer Page_Load-Methode einkapselt. Ihre Aktionsmethode sollte eine Instanz Ihrer benutzerdefinierten Klasse zurückgeben, und der Aufrufer führt die ExecuteResult-Methode zur entsprechenden Zeit aus. Dadurch werden die View-Engines vollständig umgangen, wodurch der Fehler, in den Sie geraten, verhindert wird und Sie einen leichten Leistungsschub erhalten.

+2

Dies ist die richtige Antwort für ein Hinzufügen einer Codebeispiel –

10

Ich habe Levi's Antwort. Es ist wirklich super einfach. Mein Code schreibt ein Bild in die Antwort, die zuvor nach verschiedenen Prüfungen aus dem Dateisystem abgerufen wurde.

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

Die Linie am Ende des Controller sieht aus wie folgt:

return new BookImageResult(graphicReport); 

Jemand Marke Levis Antwort als die Antwort!

+2

Dank. –

+0

Was ist mit Webforms? Ich versuche, Reportviewer zu verwenden. innerhalb einer Pagelad Methode. – JoshYates1980

2

Eine andere Möglichkeit, etwas Ähnliches zu tun, ist die eingebaute in FileActionResult zu verwenden:

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