Подтвердить что ты не робот

Поток файла с использованием ASP.NET MVC FileContentResult в браузере с именем?

Есть ли способ передать файл с помощью ASP.NET MVC FileContentResult в браузере с определенным именем?

Я заметил, что вы можете либо иметь FileDialog (Open/Save), либо вы можете передать файл в окне браузера, но затем он будет использовать ActionName при попытке сохранить файл.

У меня есть следующий сценарий:

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

Когда я использую это, я могу передавать байты, но пользователю предоставляется диалоговое окно OPEN/SAVE. Я хотел бы фактически передать этот файл в окне браузера.

Если я просто использую FilePathResult, он отображает файл в окне браузера, но затем, когда я нажимаю кнопку "Сохранить", чтобы сохранить файл в формате PDF, он показывает мне имя действия как имя файла.

Кто-нибудь сталкивался с этим?

4b9b3361

Ответ 1

Это может быть полезно для тех, кто сталкивается с этой проблемой. Наконец я понял решение. Оказывается, даже если мы используем inline для "content-disposition" и укажите имя файла, браузеры все еще не используют имя файла. Вместо этого браузеры пытаются интерпретировать имя файла на основе пути /URL.

Вы можете прочитать далее по этому URL-адресу: Секретная загрузка файла внутри браузера с правильным именем файла

Это дало мне представление, я только что создал свой URL-адрес, который преобразует URL-адрес и заканчивает его именем файла, который я хотел бы предоставить. Так, например, мой первоначальный вызов контроллера состоял только в том, чтобы передать идентификатор заказа печатаемого ордера. Я ожидал, что имя файла будет иметь формат Order {0}.pdf, где {0} - идентификатор заказа. Точно так же для цитат мне нужна Quote {0}.pdf.

В моем контроллере я просто пошел вперед и добавил дополнительный параметр, чтобы принять имя файла. Я передал имя файла как параметр в методе URL.Action.

Затем я создал новый маршрут, который отобразил бы этот URL-адрес в формат: http://localhost/ShoppingCart/PrintQuote/1054/Quote1054.pdf


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

Это в значительной степени решило мою проблему. Надеюсь, это поможет кому-то!

Cheerz, Anup

Ответ 2

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

и для открытия PDF внутри браузера вам нужно установить заголовок Content-Disposition:

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

Ответ 3

На самом деле, самый простой способ - сделать следующее...

byte[] content = your_byte[];

FileContentResult result = new FileContentResult(content, "application/octet-stream") 
                 {
                     FileDownloadName = "your_file_name"
                 };

return result;

Ответ 4

Предыдущие ответы верны: добавление строки...

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

... приведет к тому, что несколько заголовков Content-Disposition будут отправлены в браузер. Это происходит, когда b/c FileContentResult внутренне применяет заголовок, если вы снабжаете его именем файла. Альтернативным и довольно простым решением является просто создать подкласс FileContentResult и переопределить его метод ExecuteResult(). Вот пример, который создает экземпляр класса System.Net.Mime.ContentDisposition (тот же объект, который используется во внутренней реализации FileContentResult), и передает его в новый класс:

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);
    }
}

В Controller или в базе Controller вы можете написать простой помощник для создания экземпляра FileContentResultWithContentDisposition, а затем вызвать его из вашего метода действий, например:

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
    });
}

Теперь файл будет отправлен в браузер с выбранным именем файла и с заголовком содержимого-содержимого "inline; filename = [filename]".

Я надеюсь, что это поможет!

Ответ 5

Абсолютно простым способом потоковой передачи файла в браузер с помощью ASP.NET MVC является следующее:

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

Это проще, чем метод, предложенный @azarc3, ​​поскольку вам даже не нужно читать байты.

Кредит: http://prideparrot.com/blog/archive/2012/8/uploading_and_returning_files#how_to_return_a_file_as_response

** Изменить **

По-видимому, мой "ответ" совпадает с вопросом ОП. Но я не сталкиваюсь с проблемой, которую он испытывает. Вероятно, это была проблема со старой версией ASP.NET MVC?

Ответ 6

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; 
     } 
}

Ответ 7

Как экспортировать в документ Word, используя метод Aspose.wrod? Прямо сейчас вот как мой метод экспорта в PDF:

        var tnr = (EventService)RemotingHelper.GetObject(typeof(EventService));
        string test= tnr.CreateEventReportForEventList(eventIDs, false, null, true);
        byte[] eventData = System.Text.Encoding.UTF8.GetBytes(test);
        MemoryStream ms = new MemoryStream(eventData);
        Response.Cookies.Add(new HttpCookie("fileDownloadToken", "token"));

        var doc = new Aspose.Words.Document(ms);
        doc.Save(Response, "fileName.pdf", Aspose.Words.ContentDisposition.Attachment, null);
        Response.End();