Zasugerowałem, że powinienem użyć FileResult, aby umożliwić użytkownikom pobieranie plików z mojej aplikacji Asp.Net MVC. Ale jedyne przykłady, jakie mogę znaleźć, zawsze dotyczą plików obrazów (określając typ zawartości image / jpeg).
Ale co, jeśli nie mogę poznać typu pliku? Chcę, aby użytkownicy mogli pobierać praktycznie dowolny plik z obszaru plików mojej witryny.
Przeczytałem jedną z metod, aby to zrobić (zobacz kod w poprzednim poście ), która faktycznie działa dobrze, z wyjątkiem jednej rzeczy: nazwa pliku pojawiająca się w oknie dialogowym Zapisz jako jest połączona ze ścieżką pliku z podkreślnikami ( folder_folder_plik.ext). Ponadto wydaje się, że ludzie myślą, że powinienem zwrócić FileResult zamiast używać tej niestandardowej klasy, którą znalazłem BinaryContentResult.
Czy ktoś zna „prawidłowy” sposób takiego pobrania w MVC?
EDYCJA: Mam odpowiedź (poniżej), ale pomyślałem, że powinienem opublikować pełny działający kod, jeśli ktoś inny jest zainteresowany:
public ActionResult Download(string filePath, string fileName)
{
string fullName = Path.Combine(GetBaseDir(), filePath, fileName);
byte[] fileBytes = GetFile(fullName);
return File(
fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
byte[] GetFile(string s)
{
System.IO.FileStream fs = System.IO.File.OpenRead(s);
byte[] data = new byte[fs.Length];
int br = fs.Read(data, 0, data.Length);
if (br != fs.Length)
throw new System.IO.IOException(s);
return data;
}
źródło
Response.ContentType = MimeMapping.GetMimeMapping(filePath);
, ze stackoverflow.com/a/22231074/4573839Odpowiedzi:
Możesz po prostu określić ogólny typ MIME strumienia oktetów:
źródło
ReadAllBytes
został dodany wiele lat później w edycji. Dlaczego to moja druga najbardziej uprzywilejowana odpowiedź? No cóż.non-invocable member "File" cannot be used like a method.
Struktura MVC obsługuje to natywnie. Kontroler System.Web.MVC.Controller.File zapewnia metody zwracania pliku według nazwy / strumienia / tablicy .
Na przykład używając wirtualnej ścieżki do pliku, możesz wykonać następujące czynności.
źródło
Jeśli korzystasz z .NET Framework 4.5, wówczas używasz MimeMapping.GetMimeMapping (ciąg FileName), aby uzyskać typ MIME dla swojego pliku. Tak to wykorzystałem w swojej akcji.
źródło
Phil Haack ma fajny artykuł, w którym stworzył niestandardową klasę Wynik działania pobierania pliku. Musisz jedynie określić wirtualną ścieżkę pliku i nazwę, którą chcesz zapisać.
Użyłem go raz i oto mój kod.
W moim przykładzie przechowywałem fizyczną ścieżkę plików, więc użyłem tej metody pomocnika - że znalazłem gdzieś, czego nie pamiętam - aby przekonwertować ją na ścieżkę wirtualną
Oto pełna klasa zaczerpnięta z artykułu Phill Haack
źródło
Server.MapPath(this.VirtualPath)
), więc używanie tego bezpośrednio bez zmian jest odrobinę naiwne. Powinieneś stworzyć alternatywę, która akceptuje,PhysicalPath
biorąc pod uwagę, że to jest ostatecznie wymagane i to jest to, co przechowujesz. Byłoby to znacznie bezpieczniejsze, ponieważ przyjęto założenie, że ścieżka fizyczna i ścieżka względna byłyby takie same (z wyłączeniem katalogu głównego). Pliki danych są często przechowywane w App_Data. Nie jest to dostępne jako ścieżka względna.Dzięki Ian Henry !
W przypadku, gdy potrzebujesz pobrać plik z MS SQL Server tutaj jest rozwiązanie.
Gdzie AppModel jest
EntityFramework
modelem, a MyFiles przedstawia tabelę w bazie danych. FileData znajduje sięvarbinary(MAX)
w tabeli MyFiles .źródło
jego proste po prostu podaj ścieżkę fizyczną w katalogu ścieżka z nazwą pliku
źródło
źródło
if (string.IsNullOrWhiteSpace (fileName)) zwraca treść („brak nazwy pliku”);
źródło
GetFile powinien zamykać plik (lub otwierać go w trakcie używania). Następnie możesz usunąć plik po konwersji na bajty - pobieranie zostanie wykonane w tym buforze bajtów.
Więc w metodzie pobierania ...
źródło