Ich stoße auf ein Problem, das Senden von Dateien in einer Datenbank gespeichert zurück an den Benutzer in ASP.NET MVC. Was ich will, ist eine Ansicht, die zwei Links auflistet, eine, um die Datei anzuzeigen und lassen Sie den Mimetyp an den Browser gesendet bestimmen, wie es behandelt werden soll, und die andere, um einen Download zu erzwingen.
Wenn ich eine Datei namens SomeRandomFile.bak
und der Browser kein zugehöriges Programm zum Öffnen von Dateien dieses Typs hat, dann habe ich kein Problem damit, dass er standardmäßig das Download-Verhalten anwendet. Wenn ich jedoch eine Datei namens SomeRandomFile.pdf
ou SomeRandomFile.jpg
Ich möchte, dass die Datei einfach geöffnet wird. Aber ich möchte auch einen Download-Link auf der Seite, so dass ich eine Download-Aufforderung unabhängig vom Dateityp erzwingen kann. Ist dies sinnvoll?
Ich habe versucht FileStreamResult
und es funktioniert für die meisten Dateien, sein Konstruktor akzeptiert standardmäßig keinen Dateinamen, so dass unbekannte Dateien einen Dateinamen auf der Grundlage der URL zugewiesen werden (die nicht weiß, welche Erweiterung auf der Grundlage des Inhaltstyps zu geben). Wenn ich den Dateinamen erzwinge, indem ich ihn angebe, kann der Browser die Datei nicht mehr direkt öffnen und ich erhalte eine Aufforderung zum Herunterladen. Hat jemand dieses Problem schon einmal gehabt?
Dies sind die Beispiele, die ich bisher ausprobiert habe.
//Gives me a download prompt.
return File(document.Data, document.ContentType, document.Name);
//Opens if it is a known extension type, downloads otherwise (download has bogus name and missing extension)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType);
//Gives me a download prompt (lose the ability to open by default if known type)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType) {FileDownloadName = document.Name};
Irgendwelche Vorschläge?
UPDATE: Diese Frage scheint viele Leute zu beschäftigen, also dachte ich, ich bringe sie mal auf den neuesten Stand. Die Warnung in der akzeptierten Antwort unten, die von Oskar in Bezug auf internationale Zeichen hinzugefügt wurde, ist absolut gültig, und ich habe sie ein paar Mal getroffen, weil ich die ContentDisposition
Klasse. Ich habe seitdem meine Implementierung aktualisiert, um dies zu beheben. Während der Code unten von meiner neuesten Inkarnation dieses Problems in einer ASP.NET Core (Full Framework)-App ist, sollte es mit minimalen Änderungen in einer älteren MVC-Anwendung auch funktionieren, da ich die System.Net.Http.Headers.ContentDispositionHeaderValue
Klasse.
using System.Net.Http.Headers;
public IActionResult Download()
{
Document document = ... //Obtain document from database context
//"attachment" means always prompt the user to download
//"inline" means let the browser try and handle it
var cd = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = document.FileName
};
Response.Headers.Add(HeaderNames.ContentDisposition, cd.ToString());
return File(document.Data, document.ContentType);
}
// an entity class for the document in my database
public class Document
{
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Data { get; set; }
//Other properties left out for brevity
}