У меня есть физический файл, который я хочу, чтобы пользователь мог загрузить. Файл находится в той же папке, что и моя текущая страница Razor. Вот что я пробовал.
Разметка
<a asp-page-handler = "DownloadHelp" title = "Template Help"><img src = "~/images/help.png" /></a>
Код
public IActionResult OnGetDownloadHelp(
{
return File("TemplateHelp.pdf", MediaTypeNames.Application.Pdf);
}
Результат
Я получаю сообщение об ошибке: TemplateHelp.pdf не найден. Как ни странно, исключение останавливается на строке await next.Invoke(context);
в одном из моих классов промежуточного программного обеспечения. Я не уверен, почему там происходит исключение.
Разметка
<a download href = "TemplateHelp.pdf" title = "Download Template Documentation"><img src = "~/images/help.png" /></a>
Результат
Имя файла отображается в списке загрузок, но отображается сообщение «Не удалось загрузить — нет файла».
Кажется, это должно быть прямолинейно. Кто-нибудь знает, как это сделать?
Файл должен находиться на пути к статическим файлам (обычно wwwroot
), это место, где asp.net ищет статические файлы и может передать их клиенту.
Спасибо, но, как уже объяснялось, мой файл не там. Что вы имеете в виду, когда ASP.NET ищет статические файлы? Для какой операции? Метод, который я использую, принимает полный путь. Он не должен искать в wwwroot.
Когда вы публикуете свое приложение, папка wwwroot копируется в папку вывода сборки. Промежуточное программное обеспечение статических файлов вернет эти файлы, если URL-адрес совпадает. Все остальное — это исходный код, который компилируется в сборки. Вы не хотите, чтобы ваши файлы .cs
или .cshtml
можно было загрузить. См. Learn.microsoft.com/en-us/aspnet/core/fundamentals/…
@JeremyLakeman: Хорошая мысль. Спасибо.
Где хранится ваш файл в вашем приложении? В подобных случаях лучше указать полный путь к загружаемому файлу. Может быть, ошибка связана с тем, что приложению не удалось найти указанный файл?
Код должен выглядеть следующим образом:
public IActionResult OnGetDownloadHelp()
{
byte[] file = System.IO.File.ReadAllBytes("your_path_to_the_file.pdf");
var contentDisposition = new ContentDispositon();
contentDisposition.Inline = false;
Response.Headers.Add("content-disposition", contentDisposition.ToString());
return File(file,"application/pdf");
}
Встроенный параметр может автоматически загружать/не загружать файл в вашей локальной системе в зависимости от его значения. True для неавтоматической загрузки и false для автоматической загрузки.
Надеюсь, это поможет!
Как я объяснил, файл находится в той же папке, что и страница Razor, которая обращается к нему. Но вся суть в том, что я не знаю точного пути на сервере. И даже если бы я мог это определить, я бы никогда не стал жестко запрограммировать путь, потому что на другом сервере он мог бы быть другим путем, если бы мне когда-либо пришлось его переместить.
Если это так, участвует ли в вашем приложении база данных? Потому что тогда вы могли бы сохранить файл там и поместить ссылку внутри действия.
По умолчанию по прямому запросу доступны только файлы в папке wwwroot.
Судя по документу MS, страницы Razor в основном используются для обработки динамического контента, тогда как статический контент (например, PDF) должен обслуживаться из каталога wwwroot, если не настроена специальная маршрутизация или промежуточное программное обеспечение.
Этот дизайн предназначен для защиты кода приложения и других нестатических файлов от раскрытия. Файлы за пределами wwwroot не доступны автоматически через URL. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/file-providers?view=aspnetcore-8.0
Можно попробовать PageContext.HttpContext.Request.Path, чтобы получить текущий путь.
поместите в специальную папку «wwwroot» и используйте href = "~/TemplateHelp.pdf». Нет необходимости использовать контроллер, если вам не нужно защищать файл от глубоких ссылок. Если вы хотите убедиться, что загрузка разрешена, вы должны поместить этот файл в папку, где его сможет получить только контроллер, затем попросить контроллер проверить авторизацию/аутентификацию, а затем вернуть файл. (например: AppContext.BaseDirectory + «/PDFs/TemplateHelp.pdf»). Файл может принимать поток памяти, файловый поток и т. д.