Пользовательское имя файла не отображается при просмотре встроенного файла в ASP.NET Core 2.2 MVC - PullRequest
0 голосов
/ 11 декабря 2018

Я хочу доставлять вложения из сторонней системы.Они хранятся как .attach файлы в файловой системе, оригинальные файлы присутствуют в его базе данных.Следуя этому подходу , мои действия выглядят так:

    public async Task<IActionResult> GetAttachment(int id) {
        var attachment = await myAttachmentManager.GetAttachmentAsync(id);
        // attachmentsPath = T:\attachments, FilePath = 1234.attach
        string fullPath = Path.Combine(attachmentsPath, attachment.FilePath); 
        var content = await File.ReadAllBytesAsync(fullPath);

        var fileContentProvider = new FileExtensionContentTypeProvider();
        string mimeType;
        if (!fileContentProvider.TryGetContentType(attachment.FileName, out mimeType)) // FileName = my-file.pdf
            mimeType = "application/octet-stream";
        var file = new FileContentResult(content, mimeType);

        // This should display "my-file.pdf" as title
        var contentHeader = new ContentDispositionHeaderValue("inline") {
            FileName = attachment.FileName
        }.ToString();
        Response.Headers["Content-Disposition"] = contentHeader;

        return file;
    }

Это работает, PDF-файлы встроены в браузер, а двоичные файлы, такие как zip, загружены.Но при просмотре PDF-файлов браузер показывает мне 1234.attach в качестве заголовка в этом примере.Я хочу отобразить реальное имя файла (my-pdf.pdf здесь) и нашел для этого заголовок Content-Disposition.

Хотя Firefox и Chrome по-прежнему отображают идентификатор вместо my-pdf.pdf.При просмотре страницы, он показывает тег заголовка:

<title>1234</title>

Что я делаю не так?

Не устанавливайте имя файла в качестве идентификатора

Найдено этот вопрос где кажется, что параметр id get используется в качестве имени файла.В моем случае это реальный числовой идентификатор (1234), и мне нужно сохранить его, поскольку файлы были проверены базой данных, в которой используются эти идентификаторы.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Кажется, что Chrome pdf Viewer прочитает файл pdf и использует Title документа pdf в качестве заголовка вашей страницы .

Воспроизведение

В целях тестирования давайте сначала загрузим стандарт протокола MQTT .Свойство Title находится в 7184-й строке

<</Title(MQTT Version 3.1.1) /Author(OASIS Message Queuing Telemetry Transport \(MQTT\) TC) /Creator .... >>

В строке указано заголовок этого PDF-документа: MQTT Version 3.1.1.

Теперь давайте проверим этот PDF-файл с помощью Chrome.Отправьте HTTP-запрос на /home/getattachment/123.pdf:

GET /home/getattachment/123.pdf HTTP/1.1
Host: localhost:5001
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7

и HTTP-ответ с сервера:

HTTP/1.1 200 OK
Content-Type: application/pdf
Server: Kestrel
Transfer-Encoding: chunked
Content-Disposition: inline; filename=wont_work_mqtt-v3.1.1-os.pdf; filename*=UTF-8''wont_work_mqtt-v3.1.1-os.pdf

Примечание последний сегмент URL равен 123.pdf, а мы указываем имя файла как wont_work_mqtt-v3.1.1-os.pdf в Content-Disposition

и на скриншоте нижепоказывает, что заголовок Tab и заголовок просмотра PDF оба являются оригинальными Title документа PDF:

enter image description here

Walkaround

Если я изменю свойство Title документа pdf на (itminus_MQTT Version 3.1.1), как показано ниже:

<<
/Title (itminus_MQTT Version 3.1.1)
/CreationDate (D:20141105132636-05'00')
/ModDate (D:20141105132636-05'00')
/Author (OASIS Message Queuing Telemetry Transport \(MQTT\) TC)
/Producer (Select.Pdf for .NET v2018.4.0)
/Creator (Microsoft� Word 2010)
>>

ответ будет:

enter image description here

Таким образом, обходной путь заключается в изменении свойства Title документа PDF.Вы можете выбрать свою любимую библиотеку, чтобы сделать это, как вам нравится.Здесь я использую SelectPdf для целей тестирования:

var cdhv= new ContentDispositionHeaderValue("inline");
cdhv.SetHttpFileName( attachmentFileName);
Response.Headers["Content-Disposition"] = cdhv.ToString();
if(mimeType == "application/pdf"){
    SelectPdf.PdfDocument doc = null;
    try{
        doc = new SelectPdf.PdfDocument(fullPath);
        var docinfo = doc.DocumentInformation;
        docinfo.Title = attachmentFileName;
        doc.Save(Response.Body);
    }finally{
        doc?.Close();
    }
}else{
    Response.Body.Write(content);
}
return ;

Это работает для меня.

0 голосов
/ 11 декабря 2018

Вы должны установить свойство FileDownloadName FileContentResult

byte[] content = your_byte[];

FileContentResult result = new FileContentResult(content, "application/octet-stream") 
                 {
                     FileDownloadName = String.Format("{0}.csv", fileName)
                 };

return result;

или

var file = new FileContentResult(content, mimeType);
file.FileDownloadName = String.Format("{0}.csv", fileName);
...