2009-08-06 5 views
1

Ich versuche, eine Ansicht, die eine HTML-Tabelle als herunterladbare Datei für den Benutzer enthält, als eine Excel-Datei zu senden.Serving einer Ansicht als Datei in asp.net mvc

Ich bekomme immer den Fehler "Server kann Inhaltstyp nicht festlegen, nachdem HTTP-Header gesendet wurden.". Ich kann nicht herausfinden, was falsch läuft ...

Hier einige Code:

Excel.aspx:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %> 
<html> 
<head runat="server"> 
    <title>Excel</title> 
</head> 
<body> 
.... 
</body> 
</html> 

ControllerAction:

public FileResult Excel() 
    { 
     string view = RenderViewToString(this.ControllerContext, "~/Views/Shared/Excel.aspx", null, this.ViewData, this.TempData); 

     MemoryStream stream = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(view)); 

     string mimetype = RainbowsDotNet.FileHandling.MimeType.GetMimetypeFromExtension(".xls"); 

     FileStreamResult filestreamresult = new FileStreamResult(stream, mimetype); 
     filestreamresult.FileDownloadName = "Employees_{0}.xls".FormatWith(DateTime.Now.ToString("ddMMyyyy_HHmmss")); 

     return filestreamresult; 
    } 

Während des Debuggens, string „-Ansicht "enthält:

"\r\n<html>\r\n<body>............................" 

Irgendeine Idee? Ich mache genau das gleiche mit einem Blob und das gibt nett ein Dokument zum Download zurück.

+0

Ich weiß, das ist offensichtlich, aber Ihre Header wurden bereits an den Client gesendet, so dass Sie herausfinden müssen, warum. Was bewirkt, dass die Header bereits gesendet wurden. Möglicherweise haben Sie keine Pufferung aktiviert? Deaktivieren Sie die Pufferung absichtlich anderswo? –

+0

Ihre "Ansicht" -Daten sind ein YSOD (Yellow Screen Of Death), ich würde dort anfangen – mxmissile

+0

hmm, ich habe die Pufferung nicht berührt, aber immer noch. Ich mache genau das gleiche wie in einem anderen Controller, wo ich auch Dokumente zurückgebe und es funktioniert gut dort ... nur ein FileResult, das ein FileStreamResult zurückgibt. –

Antwort

1

Haben Sie die RenderViewToString-Methode aus diesem Post verwendet: Render a view as a string?

Wenn Sie dann getan haben, gibt es einen Response.Flush in diesem Code, der die Header sendet. Die Pufferung ist standardmäßig aktiviert, aber wenn Sie Response.Flush aufrufen, wird alles an den Client gesendet. Und dann, warum Sie versuchen, die Datei mit den aktualisierten Headern zu senden, erhalten Sie diesen Fehler.

+0

Ja, das ist der, den ich benutze! Das scheint das Problem zu sein. Nun, wie lösen Sie es? :-) Ich würde gerne diese Methode verwenden. –

+0

Nicht sicher ... Es fühlt sich definitiv nicht korrekt an, dass Sie in RenderViewToString einen Flush aufrufen müssen, um den String-Inhalt einer View abzurufen. Ich frage mich, ob es eine andere Möglichkeit gibt, die Ansicht direkt in einen Stream zu schreiben? –

+0

Keine Ahnung .. Ich denke, das ist meine Strafe für die Verwendung von Code, den ich nicht verstehe. –

4

Sie könnten dieses Problem umgehen, indem Sie dies in den Controller setzen. Sie können HTML in eine Ansicht einfügen und dann an den Browser senden.

public ActionResult Excel() 
{ 
    this.Response.AddHeader("Content-Disposition", "Employees_{0}.xls".FormatWith(DateTime.Now.ToString("ddMMyyyy_HHmmss"))); 
    this.Response.ContentType = "application/vnd.ms-excel"; 
    //Do model stuff 
    Model model = new Model(); 
    return View(model); 
} 

Klingt hacky? Es ist ein bisschen. Ich hatte das gleiche Problem, das Sie erwähnt haben, und die Frage, auf die Jeff hinweist, ist auch eine von meinen. :)

Wie in meinem Kommentar erwähnt, sollten Sie sicherstellen, dass Ihre Sicht nicht folgendes hat:

<html> 
    <head> 
    ... 
    </head> 
    <body> 
    </body> 
</html> 

All dies erforderlich ist, und auf Ihrer Seite als HTML gerendert wird führen können, anstatt das Excel-Dokument wird zurückgegeben. Alles, was du gerendert hast, sind also die eigentlichen Tabellen-Tags und alles drin.

+0

funktioniert das für Sie? Alles, was es hier tut, ist HTML im Browser anzeigen –

+0

Sorry, ich werde meinen letzten Kommentar löschen. Ich meinte, es funktioniert! :) Aber, Sie könnten versuchen, den This.Response Code in der Ansicht zu setzen. Wie auch immer, es sollte funktionieren. Sie können auch sicherstellen, dass die Ansicht (oder höchstwahrscheinlich der Master) nichts außerhalb der Tabellen-Tags (html, head, body) enthält. –

+0

Leider funktioniert das nicht für mich, wo ich 20 oder 30 Ansichten auf Zeichenfolgen (E-Mail-Vorlagen) rendern muss. Irgendwelche anderen Ideen, egal wie hacky? –

Verwandte Themen