File di stream utilizzando ASP.NET MVC FileContentResult in un browser con un nome?

C’è un modo per lo streaming di un file utilizzando ASP.NET MVC FileContentResult all’interno del browser con un nome specifico?

Ho notato che puoi avere un FileDialog (Apri / Salva) o puoi eseguire il stream del file in una finestra del browser, ma poi userà ActionName quando proverai a salvare il file.

Ho il seguente scenario:

byte[] contents = DocumentServiceInstance.CreateDocument(orderId, EPrintTypes.Quote); result = File(contents, "application/pdf", String.Format("Quote{0}.pdf", orderId)); 

Quando lo uso, posso trasmettere i byte in streaming, ma all’utente viene data una finestra di dialogo del file OPEN / SAVE. Mi piacerebbe in realtà lo streaming di questo file in una finestra del browser.

Se utilizzo solo FilePathResult, mostra il file in una finestra del browser, ma quando faccio clic sul pulsante “Salva” per salvare il file in PDF, mi mostra il nome dell’azione come nome del file.

Qualcuno ha incontrato questo?

 public ActionResult Index() { byte[] contents = FetchPdfBytes(); return File(contents, "application/pdf", "test.pdf"); } 

e per aprire il PDF all’interno del browser è necessario impostare l’intestazione Content-Disposition :

 public ActionResult Index() { byte[] contents = FetchPdfBytes(); Response.AddHeader("Content-Disposition", "inline; filename=test.pdf"); return File(contents, "application/pdf"); } 

In realtà, il modo più semplice è quello di fare quanto segue …

 byte[] content = your_byte[]; FileContentResult result = new FileContentResult(content, "application/octet-stream") { FileDownloadName = "your_file_name" }; return result; 

Questo potrebbe essere utile per chiunque altro affronta questo problema. Finalmente ho trovato una soluzione. Risulta, anche se usiamo l’inline per “content-disposition” e specificiamo un nome di file, i browser non usano ancora il nome del file. Invece i browser cercano e interpretano il nome del file in base al percorso / URL.

Puoi leggere ulteriori informazioni su questo URL: Scarica in modo sicuro il file all’interno del browser con il nome file corretto

Questo mi ha dato un’idea, ho appena creato la mia URL route che avrebbe convertito l’URL e terminato con il nome del file che volevo dare al file. Quindi, ad esempio, la mia chiamata al controller originale consisteva semplicemente nel passare l’ID ordine dell’ordine in fase di stampa. Mi aspettavo che il nome del file fosse del formato Ordine {0} .pdf dove {0} è l’ID ordine. Allo stesso modo per le virgolette, volevo il preventivo {0} .pdf.

Nel mio controller, sono andato avanti e ho aggiunto un parametro aggiuntivo per accettare il nome del file. Ho passato il nome file come parametro nel metodo URL.Action.

Ho quindi creato una nuova route che avrebbe mappato quell’URL nel formato: http: //localhost/ShoppingCart/PrintQuote/1054/Quote1054.pdf

routes.MapRoute("", "{controller}/{action}/{orderId}/{fileName}", new { controller = "ShoppingCart", action = "PrintQuote" } , new string[] { "xxxControllers" } );
routes.MapRoute("", "{controller}/{action}/{orderId}/{fileName}", new { controller = "ShoppingCart", action = "PrintQuote" } , new string[] { "xxxControllers" } ); 

Questo ha praticamente risolto il mio problema. Sperando che questo aiuti qualcuno!

Cheerz, Anup

Le risposte precedenti sono corrette: aggiungendo la linea …

 Response.AddHeader("Content-Disposition", "inline; filename=[filename]"); 

… causerà l’invio di più intestazioni Content-Disposition nel browser. Ciò accade b / c FileContentResult applica internamente l’intestazione se lo si fornisce con un nome di file. Una soluzione alternativa, piuttosto semplice, è semplicemente creare una sottoclass di FileContentResult e sovrascrivere il suo metodo ExecuteResult() . Ecco un esempio che crea un’istanza della class System.Net.Mime.ContentDisposition (lo stesso object utilizzato nell’implementazione interna di FileContentResult ) e la passa nella nuova class:

 public class FileContentResultWithContentDisposition : FileContentResult { private const string ContentDispositionHeaderName = "Content-Disposition"; public FileContentResultWithContentDisposition(byte[] fileContents, string contentType, ContentDisposition contentDisposition) : base(fileContents, contentType) { // check for null or invalid ctor arguments ContentDisposition = contentDisposition; } public ContentDisposition ContentDisposition { get; private set; } public override void ExecuteResult(ControllerContext context) { // check for null or invalid method argument ContentDisposition.FileName = ContentDisposition.FileName ?? FileDownloadName; var response = context.HttpContext.Response; response.ContentType = ContentType; response.AddHeader(ContentDispositionHeaderName, ContentDisposition.ToString()); WriteFile(response); } } 

Nel tuo Controller o in un Controller base, puoi scrivere un semplice helper per creare un’istanza di FileContentResultWithContentDisposition e quindi chiamarlo dal tuo metodo di azione, in questo modo:

 protected virtual FileContentResult File(byte[] fileContents, string contentType, ContentDisposition contentDisposition) { var result = new FileContentResultWithContentDisposition(fileContents, contentType, contentDisposition); return result; } public ActionResult Report() { // get a reference to your document or file // in this example the report exposes properties for // the byte[] data and content-type of the document var report = ... return File(report.Data, report.ContentType, new ContentDisposition { Inline = true, FileName = report.FileName }); } 

Ora il file verrà inviato al browser con il nome del file scelto e con un’intestazione content-disposition di “inline; filename = [nomefile]”.

Spero che aiuti!

Il modo più semplice in assoluto per eseguire lo streaming di un file nel browser utilizzando ASP.NET MVC è questo:

 public ActionResult DownloadFile() { return File(@"c:\path\to\somefile.pdf", "application/pdf", "Your Filename.pdf"); } 

Questo è più semplice del metodo suggerito da @ azarc3 poiché non hai nemmeno bisogno di leggere i byte.

Il merito va a: http://prideparrot.com/blog/archive/2012/8/uploading_and_returning_files#how_to_return_a_file_as_response

** Modificare **

Apparentemente la mia “risposta” è la stessa della domanda dell’OP. Ma non sto affrontando il problema che sta avendo. Probabilmente si trattava di un problema con la versione precedente di ASP.NET MVC?

 public FileContentResult GetImage(int productId) { Product prod = repository.Products.FirstOrDefault(p => p.ProductID == productId); if (prod != null) { return File(prod.ImageData, prod.ImageMimeType); } else { return null; } }