Возврат PDF из контроллера ASP.NET Core 2 - PullRequest
0 голосов
/ 01 сентября 2018

Я пытаюсь вернуть файл PDF с моего контроллера ASP.NET Core 2. У меня есть этот код (в основном заимствовано из этого ТАКого вопроса ):

var net = new System.Net.WebClient();
//a random pdf file link
var fileLocation = "https://syntera.io/documents/T&C.pdf";/
var data = net.DownloadData(fileLocation);
MemoryStream content = null;
try
{
    content = new MemoryStream(data);
    return new FileStreamResult(content, "Application/octet-stream");
}
finally
{
    content?.Dispose();
}

Этот код выше является частью класса обслуживания, который вызывает мой контроллер. Это код моего контроллера.

public async Task<IActionResult> DownloadFile(string fileName)
{
    var result = await _downloader.DownloadFileAsync(fileName);
    return result;
}

Но я продолжаю получать ObjectDisposedException: Cannot access a closed Stream.

Блок try and finally был попыткой исправить это из другого вопроса SO.

Основной вопрос: а) Является ли это правильным способом отправки PDF-файла обратно в браузер и б) если это не так, как я могу изменить код для отправки PDF в браузер?

В идеале я не хочу сначала сохранять файл на сервере, а затем возвращать его в контроллер. Я бы предпочел вернуть его, сохранив все в памяти.

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

finally всегда будет вызываться ( даже после return), поэтому он всегда удаляет поток контента, прежде чем его можно будет отправить клиенту, поэтому возникает ошибка.

В идеале я не хочу сначала сохранять файл на сервере, а затем возвращать его в контроллер. Я бы предпочел вернуть его, сохранив все в памяти.

Используйте класс FileContentResult, чтобы взять необработанные данные массива байтов и вернуть их напрямую.

FileContentResult : представляет ActionResult, который при выполнении запишет двоичный файл в ответ.

async Task<IActionResult> DownloadFileAsync(string fileName){
    using(var net = new System.Net.WebClient()) {
        byte[] data = await net.DownloadDataTaskAsync(fileName);
        return new FileContentResult(data, "application/pdf") {
            FileDownloadName = "file_name_here.pdf"
        };
    }
}

Нет необходимости в дополнительном потоке памяти

0 голосов
/ 01 сентября 2018

Вы должны указать:

Response.AppendHeader("content-disposition", "inline; filename=file.pdf");
return new FileStreamResult(stream, "application/pdf")

Чтобы файл открывался напрямую в браузере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...