День 1224. #ЗаметкиНаПолях
Несколько Папок для Статических Файлов в ASP.NET Core
Если вам по какой-то причине нужно разделить ваши статические файлы (к примеру, JS/CSS/картинки в одной папке, и файлы, которые могут скачивать пользователи – в другой), наивным – но неправильным - решением будет использовать UseStaticFiles дважды:
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
// Добавляем ещё папку
FileProvider = new PhysicalFileProvider(
Path.Combine(
builder.Environment.ContentRootPath,
"Docs"
))
});
На первый взгляд, это работает. Промежуточное ПО будет искать файлы в обычной папке wwwroot, а затем в папке Docs и возвращать их. Проблема возникает, если вы попытаетесь использовать что-нибудь, типа asp-append-version в представлениях для файлов из Docs. Версия просто не будет добавляться. Добавление версии в URL зависит от контрольной суммы файла. В этом случае система не может её найти, и этот атрибут просто будет проигнорирован.
StaticFiles на самом деле используют не просто промежуточное ПО для поиска файла, а полагаются на WebRootFileProvider. Но что такое FileProvider?
В документации есть хорошая статья об этом. Если коротко, это сервис, который знает, как находить файлы разными способами. Платформа имеет несколько реализаций, включая PhysicalFileProvider или ManifestEmbeddedFileProvider. В нашем плохом примере выше используется PhysicalFileProvider. А на самом деле UseStaticFiles использует WebRootFileProvider для поиска статических файлов (и этот провайдер просто ищет в wwwroot). Таким образом, реальный способ справиться с проблемой — изменить WebRootFileProvider приложения.
Итак, нам нужен способ использовать оба провайдера сразу. Сначала создадим нужные нам провайдеры (в данном примере два):
var webRootProvider =
new PhysicalFileProvider(
builder.Environment.WebRootPath
);
var docPathProvider =
new PhysicalFileProvider(
Path.Combine(
builder.Environment.ContentRootPath,
"Docs"
));
Теперь нам нужен третий тип, который позволит объединить наши провайдеры. Этот провайдер называется CompositeFileProvider:
var compositeProvider =
new CompositeFileProvider(
webRootProvider,
docPathProvider
);
И наконец, заменяем WebRootFileProvider нашим новым CompositeFileProvider:
app.Environment.WebRootFileProvider = compositeProvider;
app.UseStaticFiles();
Источник: wildermuth.com/2022/04…pnetcore