Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 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