Was ist der Unterschied zwischen den vier Dateiergebnissen in ASP.NET MVC?

136

ASP.NET bietet vier verschiedene Arten von Dateiergebnissen:

  • FileContentResult: Sendet den Inhalt einer Binärdatei an die Antwort.
  • FilePathResult: Sendet den Inhalt einer Datei an die Antwort
  • FileResult: Gibt die Binärausgabe zurück, um in die Antwort zu schreiben
  • FileStreamResult: Sendet mithilfe einer Stream-Instanz binären Inhalt an die Antwort

Diese Beschreibungen stammen von MSDN und mit Ausnahme des FileStreamResult klingen die ersten drei identisch. Was ist der Unterschied zwischen ihnen?

Robert MacLean
quelle

Antworten:

176

FileResult ist eine abstrakte Basisklasse für alle anderen.

  • FileContentResult - Sie verwenden es, wenn Sie ein Byte-Array haben, das Sie als Datei zurückgeben möchten
  • FilePathResult - Wenn Sie eine Datei auf der Festplatte haben und deren Inhalt zurückgeben möchten (geben Sie einen Pfad an)
  • FileStreamResult - Wenn Sie einen Stream geöffnet haben, möchten Sie dessen Inhalt als Datei zurückgeben

Sie müssen diese Klassen jedoch selten verwenden - Sie können nur eine der Controller.FileÜberladungen verwenden und ASP.NET MVC die Magie für Sie erledigen lassen.

maciejkow
quelle
29

Gute Frage ... und verdient mehr Details. Ich befinde mich hier aufgrund einer interessanten Situation. Wir haben einige PDF-Anhänge über die MVC3 / C # -Umgebung bereitgestellt. Unser Code wurde veröffentlicht und wir erhielten einige Antworten von unseren Kunden, dass sich die Downloads bei Verwendung von Chrome merkwürdig verhalten und der Dateityp in "pdf-, Anhang.pdf-, Anhang" konvertiert wurde. Yup ... du hast es ... die ganze Sache. Man könnte es also so umschreiben, dass es nur "pdf" ist und die Datei immer noch intakt gespeichert wird, aber was für ein Durcheinander!

Um die anfängliche Situation zu beschreiben, haben wir den Header 'Content-Disposition' gesetzt und dann ein FileContentResult zurückgegeben ...

var cd = new System.Net.Mime.ContentDisposition
            {
                FileName = result.Attachment.FileName,
                Inline = false
            };
            Response.AppendHeader("Content-Disposition", cd.ToString());

return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName);

Schien gut zu sein. Hat im IE gut funktioniert. Also habe ich einige Nachforschungen angestellt und versucht, stattdessen FileStreamResult zu implementieren (wobei der Content-Disposition-Setter beibehalten wurde):

MemoryStream dataStream = new MemoryStream();
dataStream.Write(result.Attachment.Data, 0, result.Attachment.Data.Length);
dataStream.Position = 0;
return new FileStreamResult(dataStream, MimeExtensionHelper.GetMimeType(result.Attachment.FileName));

Es hat das Problem in Chrome behoben! Hmmm ... aber warum zum Teufel sollte ich mein perfektes Byte-Array nehmen und es streamen und dann über dieses zurückgeben müssen, damit der Dateiname richtig funktioniert?

Dann kam der Geiger.

Mit FileContentResult habe ich 2 Content-Dispositionen im Header. Mit FileStreamResult habe ich 1 bekommen.

FileContentResult fügt einen Content-Disposition-Header hinzu, wenn der Dateiname angegeben wird, und Chrome betrachtet Vielfache dieses Headers als Fehler.

Seltsame Reaktion ... aber definitiv eine, die gut zu wissen ist.

beauXjames
quelle
3
Nur ein Tipp: In .NET 4+ können Sie System.Web.MimeMapping.GetMimeMapping(filename)den MIME-Typ erfassen, wenn Sie nicht einfach darauf zugreifen können.
GONeale
4
Wenn Sie einem FileErgebnis einen Dateinamen geben , müssen Sie dessen FileDownloadNameEigenschaft festlegen, wodurch die Content-DispositionHeader für Sie festgelegt werden. Und es unterstützt die utf-8-Dateinamen korrekt, was der ContentDispositionKlasse nicht hilft (siehe meinen Kommentar hier für weitere Details).
Frédéric
1
Ja, danke @ Frédéric, du allein von all den SO-Posts hast mir erklärt, was los war!
Nacht