Sugeri que eu usasse o FileResult para permitir que os usuários baixassem arquivos do meu aplicativo Asp.Net MVC. Mas os únicos exemplos disso que encontro sempre têm a ver com arquivos de imagem (especificando o tipo de conteúdo image / jpeg).
Mas e se eu não souber o tipo de arquivo? Quero que os usuários possam baixar praticamente qualquer arquivo da área de arquivos do meu site.
Eu tinha lido um método para fazer isso (consulte uma postagem anterior para o código), que realmente funciona bem, exceto por uma coisa: o nome do arquivo que aparece na caixa de diálogo Salvar como é concatenado no caminho do arquivo com sublinhados ( folder_folder_file.ext). Além disso, parece que as pessoas pensam que eu deveria retornar um FileResult em vez de usar essa classe personalizada que eu encontrei BinaryContentResult.
Alguém conhece a maneira "correta" de fazer esse download no MVC?
EDIT: recebi a resposta (abaixo), mas pensei em postar o código de trabalho completo se outra pessoa estiver interessada:
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;
}
fonte
Response.ContentType = MimeMapping.GetMimeMapping(filePath);
, a partir stackoverflow.com/a/22231074/4573839Respostas:
Você pode apenas especificar o tipo MIME genérico de octet-stream:
fonte
ReadAllBytes
foi adicionado anos depois em uma edição. Por que essa é a minha segunda resposta mais votada? Ah bem.non-invocable member "File" cannot be used like a method.
A estrutura MVC suporta isso nativamente. O controlador System.Web.MVC.Controller.File fornece métodos para retornar um arquivo por nome / fluxo / matriz .
Por exemplo, usando um caminho virtual para o arquivo, você pode fazer o seguinte.
fonte
Se você estiver usando o .NET Framework 4.5, use o MimeMapping.GetMimeMapping (string FileName) para obter o Tipo MIME do seu arquivo. É assim que eu o usei na minha ação.
fonte
Phil Haack tem um bom artigo em que criou uma classe de resultado de ação de download de arquivo personalizado. Você só precisa especificar o caminho virtual do arquivo e o nome a ser salvo como.
Eu usei uma vez e aqui está o meu código.
No meu exemplo, eu estava armazenando o caminho físico dos arquivos, então usei esse método auxiliar - que encontrei em algum lugar que não me lembro - para convertê-lo em um caminho virtual
Aqui está a aula completa tirada do artigo de Phill Haack
fonte
Server.MapPath(this.VirtualPath)
), portanto consumi-lo diretamente sem alterações é um pouco ingênuo. Você deve produzir uma alternativa que aceite,PhysicalPath
dado que é o que é eventualmente necessário e é o que você está armazenando. Isso seria muito mais seguro, pois você assumiu que o caminho físico e o caminho relativo seriam os mesmos (excluindo a raiz). Os arquivos de dados geralmente são armazenados como App_Data. Isso não está acessível como um caminho relativo.Graças a Ian Henry !
Caso você precise obter um arquivo do MS SQL Server, aqui está a solução.
Onde AppModel é
EntityFramework
modelo e MyFiles apresenta a tabela em seu banco de dados. FileData estávarbinary(MAX)
na tabela MyFiles .fonte
é simples, basta fornecer seu caminho físico no directoryPath com o nome do arquivo
fonte
fonte
if (string.IsNullOrWhiteSpace (fileName)) retorna Content ("nome do arquivo não presente");
fonte
GetFile deve fechar o arquivo (ou abri-lo dentro de um uso). Em seguida, você pode excluir o arquivo após a conversão em bytes - o download será feito no buffer de bytes.
Então, no seu método de download ...
fonte