Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Авторы: Стив Смит (Steve Smith) и Дейв Брок (Dave Brock)
В этом документе описываются представления, используемые в приложениях ASP.NET Core MVC. Для получения информации о
В шаблоне MVC (Model-View-Controller, модель — представление — контроллер) представление отвечает за отображение данных приложения и взаимодействие с пользователем. Представление — это HTML-шаблон со встроенной Razor разметкой. Razor разметка — это код, который взаимодействует с HTML-разметкой для создания веб-страницы, которая затем отправляется клиенту.
В ASP.NET Core MVC представления — это .cshtml файлы, которые используют язык программирования C# в Razor разметке. Как правило, файлы представлений объединяются в папки с именами, соответствующими отдельным контроллерам приложения. Папки хранятся в Views папке в корне приложения:
Папка Home внутри Views папки представляет Home контроллер. Папка Home содержит представления для веб-страниц About, Contact и Index (домашняя страница). Когда пользователь запрашивает одну из этих трех веб-страниц, действия контроллера в Home контроллере определяют, какие из трех представлений используются для сборки и возврата веб-страницы пользователю.
Макеты позволяют создавать единообразные разделы веб-страниц и сократить повторы в коде. Макеты часто содержат элементы верхнего и нижнего колонтитула, навигацию и меню. Верхний и нижний колонтитулы обычно содержат стандартную разметку для многих элементов метаданных и ссылки на веб-ресурсы скриптов и стилей. Макеты позволяют избежать использования этой стандартной разметки в представлениях.
Частичные представления сокращают дублирование кода, обеспечивая управление многократно используемыми частями представлений. Например, частичный вид будет полезным для биографии автора, которая отображается в различных видах на веб-сайте блога. Биография автора — это обычное содержимое представления, которое не требует выполнения кода для формирования содержимого веб-страницы. Содержание биографии автора доступно представлению исключительно через привязку модели, поэтому использование частичного представления идеально подходит для этого типа содержимого.
Компоненты представления похожи на частичные представления тем, что они также позволяют сократить повторы кода, однако они подходят для содержимого представления, которое требует выполнения кода на сервере для преобразования веб-страницы для просмотра. Компоненты представления полезны в тех случаях, когда для подготовки содержимого для просмотра требуется взаимодействие с базой данных, например для корзины на веб-сайте электронного магазина. При формировании выходных данных веб-страницы компоненты представления не ограничены привязкой модели.
Преимущества использования представлений
Представления помогают реализовать разделение задач в приложении MVC, изолируя разметку пользовательского интерфейса от других частей приложения. Соблюдение принципа SoC делает приложение модульным, что дает несколько преимуществ.
- Приложение проще обслуживать, так как оно лучше организовано. Представления, как правило, группируются по функциональным возможностям приложения. Это упрощает поиск связанных представлений при работе над определенной функцией.
- Части приложения слабо связаны друг с другом. Вы можете разрабатывать и обновлять представления приложения отдельно от компонентов бизнес-логики и доступа к данным. При обновлении представлений приложения не обязательно обновлять другие его части.
- Части пользовательского интерфейса проще тестировать, так как представления являются отдельными модулями.
- Благодаря более упорядоченной структуре меньше вероятность того, что разделы пользовательского интерфейса будут случайно повторяться.
Создание представления
Представления, относящиеся к контроллеру, создаются в папке Views/[ControllerName] . Представления (views), общие для контроллеров, помещаются в папку Views/Shared. Чтобы создать представление, добавьте новый файл и присвойте ему то же имя, что и связанное действие контроллера с расширением .cshtml файла. Чтобы создать представление, соответствующее About действию в контроллере Home , создайте About.cshtml файл в папке Views/Home :
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p>
Razor Разметка начинается с символа @ . Запустите инструкции C# путем размещения кода C# в Razor блоках кода, заданных фигурными скобками ({ ... }). Например, см. как термин "About" ассоциирован с ViewData["Title"], как показано ранее. Для отображения значений в коде HTML можно просто ссылаться на них с помощью символа @. См. содержимое элементов <h2> и <h3> ранее.
Отображаемое ранее содержимое было только частью всей веб-страницы, показанной пользователю. Остальная часть макета страницы и другие распространенные аспекты представления указываются в других файлах представления. Чтобы узнать больше, см. тему Макет.
Способы указания представлений контроллерами
Представления обычно возвращаются из действий как ViewResult, который является типом ActionResult. Метод действия может создавать и возвращать объект ViewResult напрямую, однако обычно так не делается. Поскольку большинство контроллеров наследуются от Controller, вы просто используете вспомогательный метод View для возврата ViewResult.
HomeController.cs:
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
Когда это действие возвращается, представление, показанное в последнем разделе, About.cshtml отображается как следующая веб-страница:
Вспомогательный метод View имеет несколько перегрузок. Вы можете дополнительно указать:
Представление, которое нужно вернуть, явным образом:
return View("Orders");Модель, которую нужно передать в представление:
return View(Orders);И то, и другое: представление и модель.
return View("Orders", Orders);
Обнаружение вида
Когда действие возвращает представление, происходит процесс, который называется обнаружением представления. Он служит для определения используемого файла представления на основе имени представления.
Метод View (return View();) по умолчанию возвращает представление с тем же именем, что и у метода действия, из которого он был вызван. Например, AboutActionResult имя метода контроллера используется для поиска файла представления с именем About.cshtml. Сначала среда выполнения ищет во папке Views/[ControllerName] представление. Если он не находит соответствующее представление там, он ищет папку Shared для представления.
Не имеет значения, возвращается ли ViewResult неявно с помощью метода return View(); или имя представления явно передается методу View с помощью return View("<ViewName>");. В обоих случаях обнаружение подходящего файла представления происходит в следующем порядке:
Views/\[ControllerName]/\[ViewName].cshtmlViews/Shared/\[ViewName].cshtml
Вместо имени представления можно указать путь к файлу представления. Если используется абсолютный путь, начинающийся с корневого каталога приложения (и который может начинаться с "/" или "~/"), необходимо указать расширение .cshtml.
return View("Views/Home/About.cshtml");
Можно также использовать относительный путь для указания представлений из разных каталогов без расширения .cshtml. Внутри HomeController вы можете вернуть Index представление ваших Manage представлений с относительным путем:
return View("../Manage/Index");
Аналогичным образом, можно указать каталог текущего контроллера с помощью префикса "./":
return View("./About");
Частичные представления и компоненты представлений используют похожие (но не одинаковые) механизмы обнаружения.
Вы можете настроить соглашение по умолчанию относительно того, как представления располагаются в приложении с помощью пользовательского IViewLocationExpander.
Обнаружение представлений предусматривает поиск файлов представлений по имени. Если базовая файловая система чувствительна к регистру символов, имена представлений, вероятно, тоже будут чувствительны к регистру. Для совместимости между операционными системами необходимо обеспечить совпадение регистра в названиях контроллеров и действий, а также в именах папок и файлов представлений. Если при работе в файловой системе, в которой учитывается регистр символов, возникает ошибка, связанная с тем, что не удается найти файл представления, проверьте, совпадает ли регистр символов в запрошенном и фактическом именах файлов представлений.
Для удобства и простоты работы следуйте рекомендациям по организации структуры файлов представлений, которая должна отражать взаимосвязи между контроллерами, действиями и представлениями.
Передача данных в представления
Существует несколько подходов к передаче данных в представления:
- Строго типизированные данные: viewmodel
- Слабо типизированные данные
-
ViewData(ViewDataAttribute) ViewBag
-
Строго типизированные данные (ViewModel)
Наиболее надежный подход — указание типа модели в представлении. Такая модель называется viewmodel. Экземпляр типа viewmodel передается из действия в представление.
Использование viewmodel для передачи данных в представление позволяет ему применять строгую проверку типов. Термин строгая типизация (или строго типизированный) означает, что каждая переменная и константа имеет явным образом определенный тип (например, string, int или DateTime). Допустимость типов, используемых в представлении, проверяется во время компиляции.
В Visual Studio и Visual Studio Code строго типизированные члены классов перечисляются с помощью функции IntelliSense. Чтобы просмотреть свойства viewmodel, введите имя переменной viewmodel с точкой (.) после него. Это позволяет писать код быстрее, допуская меньше ошибок.
Укажите модель с помощью директивы @model. Используйте модель с @Model:
@model WebApplication1.ViewModels.Address
<h2>Contact</h2>
<address>
@Model.Street<br>
@Model.City, @Model.State @Model.PostalCode<br>
<abbr title="Phone">P:</abbr> 425.555.0100
</address>
Чтобы предоставить модель для представления, контроллер передает ее в качестве параметра:
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
var viewModel = new Address()
{
Name = "Microsoft",
Street = "One Microsoft Way",
City = "Redmond",
State = "WA",
PostalCode = "98052-6399"
};
return View(viewModel);
}
В отношении типов моделей, которые можно предоставлять для представления, ограничений нет. Мы рекомендуем использовать модели представления типа POCO (Plain Old CLR Object) с минимальным количеством методов или без них вовсе. Как правило, классы viewmodel хранятся в Models папке или отдельной ViewModels папке в корне приложения. Модель представления, используемая Address в предыдущем примере, представляет собой модель представления POCO, хранящуюся в файле с именем Address.cs:
namespace WebApplication1.ViewModels
{
public class Address
{
public string Name { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
}
Ничто не мешает вам использовать одни и те же классы как для типов viewmodel, так и для типов бизнес-модели. Однако применение отдельных моделей позволяет изменять представления независимо от компонентов бизнес-логики и доступа к данным в приложении. Разделение моделей и моделей представлений также предоставляет преимущества в плане безопасности, когда модели используют привязку модели и проверку для данных, отправляемых в приложение пользователем.
Слабо типизированные данные (ViewData, [ViewData] атрибут и ViewBag)
ViewBag
Недоступно по умолчанию для использования в классах Razor PagesPageModel.
Помимо строго типизированных представлений, представления имеют доступ к нестрого типизированной (слабо типизированной) коллекции данных. В отличие от строгих типов, нестрогие типы (или слабые типы) предполагают, что тип используемых данных не объявляется явным образом. Коллекцию нестрого типизированных данных можно использовать для передачи небольших объемов данных в и из контроллеров и представлений.
| Передача данных между... | Пример |
|---|---|
| Контроллер и представление | Заполнение раскрывающегося списка данными. |
| Вид и представление макета | Установка содержимого элемента <title> на представление макета из файла вида. |
| Частичное представление и представление | Мини-приложение, в котором данные выводятся на основе запрошенной пользователем веб-страницы. |
На эту коллекцию можно ссылаться в контроллерах и представлениях посредством свойства ViewData или ViewBag. Свойство ViewData представляет собой словарь слабо типизированных объектов. Свойство ViewBag представляет собой оболочку для свойства ViewData, которая предоставляет динамические свойства для базовой коллекции ViewData. Примечание. Поиск ключей не учитывает регистр для обоих ViewData и ViewBag.
ViewData и ViewBag динамически определяются во время выполнения. Так как они не обеспечивают проверку типов во время компиляции, их использование обычно более подвержено ошибкам, чем использование ViewModel. По этой причине некоторые разработчики предпочитают как можно реже использовать свойства ViewData и ViewBag или не использовать их вовсе.
ViewData
ViewData — это объект, ViewDataDictionary к который осуществляется доступ с помощью string ключей. Строковые данные можно сохранять и использовать напрямую без приведения, однако при извлечении других значений объекта ViewData их необходимо приводить к соответствующим типам. С помощью свойства ViewData можно передавать данные, включая частичные представления и макеты, из контроллеров в представления и внутри представлений.
Ниже приведен пример, в котором с помощью свойства ViewData в действии задаются значения для приветствия и адреса.
public IActionResult SomeAction()
{
ViewData["Greeting"] = "Hello";
ViewData["Address"] = new Address()
{
Name = "Steve",
Street = "123 Main St",
City = "Hudson",
State = "OH",
PostalCode = "44236"
};
return View();
}
Работа с данными в представлении:
@{
// Since Address isn't a string, it requires a cast.
var address = ViewData["Address"] as Address;
}
@ViewData["Greeting"] World!
<address>
@address.Name<br>
@address.Street<br>
@address.City, @address.State @address.PostalCode
</address>
Атрибут [ViewData]
Другой подход, который используется ViewDataDictionary , — это ViewDataAttribute. Свойства контроллеров или моделей страниц Razor, помеченных атрибутом [ViewData], хранятся и загружаются из словаря.
В следующем примере контроллер содержит свойство Home, помеченное маркером Title[ViewData]. Метод About задает заголовок для представления About:
public class HomeController : Controller
{
[ViewData]
public string Title { get; set; }
public IActionResult About()
{
Title = "About Us";
ViewData["Message"] = "Your application description page.";
return View();
}
}
В макете заголовок считывается из словаря ViewData.
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
ViewBag
ViewBag — это объект, предоставляющий динамический Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData доступ к объектам, хранящимся в ViewData. Работать со свойством ViewBag может быть удобнее, так как оно не требует приведения. В следующем примере показано, как использовать ViewBag с тем же результатом, как и при использовании ViewData ранее.
public IActionResult SomeAction()
{
ViewBag.Greeting = "Hello";
ViewBag.Address = new Address()
{
Name = "Steve",
Street = "123 Main St",
City = "Hudson",
State = "OH",
PostalCode = "44236"
};
return View();
}
@ViewBag.Greeting World!
<address>
@ViewBag.Address.Name<br>
@ViewBag.Address.Street<br>
@ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode
</address>
Использование ViewData и ViewBag одновременно
ViewBag
по умолчанию недоступно для использования в Razor классах PagesPageModel.
Так как свойства ViewData и ViewBag ссылаются на одну и ту же базовую коллекцию ViewData, вы можете использовать ViewData и ViewBag вместе в различных сочетаниях при чтении и записи значений.
Задайте заголовок с помощью ViewBag и описание, используя ViewData в верхней части About.cshtml представления:
@{
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "About Contoso";
ViewData["Description"] = "Let us tell you about Contoso's philosophy and mission.";
}
Прочитайте свойства, но измените использование ViewData и ViewBag на обратное.
_Layout.cshtml В файле получите название с помощью ViewData и получите описание с помощьюViewBag:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"]</title>
<meta name="description" content="@ViewBag.Description">
...
Помните, что строки не требуют приведения значения ViewData.
@ViewData["Title"] можно использовать без приведения.
Свойства ViewData и ViewBag можно использовать одновременно, а также свободно сочетать их для чтения и записи. Следующая разметка будет представлена:
<!DOCTYPE html>
<html lang="en">
<head>
<title>About Contoso</title>
<meta name="description" content="Let us tell you about Contoso's philosophy and mission.">
...
Сводка различий между ViewData и ViewBag
ViewBag
по умолчанию недоступно для использования в Razor классах PagesPageModel.
ViewData- Производный от ViewDataDictionary, поэтому он имеет свойства словаря, которые могут быть полезны, например
ContainsKey,Add,RemoveиClear. - Ключи в словаре представляют собой строки, поэтому пробел допустим. Пример:
ViewData["Some Key With Whitespace"] - Любой тип, кроме
string, должен быть приведен в представлении так, чтобы он мог использоваться вViewData.
- Производный от ViewDataDictionary, поэтому он имеет свойства словаря, которые могут быть полезны, например
ViewBag- Производный от
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData, поэтому он позволяет создавать динамические свойства с помощью нотации точек (@ViewBag.SomeKey = <value or object>), и приведение не требуется. Синтаксис свойстваViewBagпозволяет быстрее добавлять его в контроллеры и представления. - Проще проверять значение NULL. Пример:
@ViewBag.Person?.Name
- Производный от
Когда следует использовать ViewData или ViewBag
Свойства ViewData и ViewBag в равной степени подходят для передачи небольших объемов данных между контроллерами и представлениями. Выбор одного из них зависит от предпочтений. Вы можете сочетать объекты ViewData и ViewBag, однако код будет проще для восприятия и обслуживания при последовательном применении одного подхода. Оба подхода определяются динамически во время выполнения и поэтому могут приводить к ошибкам во время выполнения. Некоторые команды разработчиков избегают их использования.
Динамические представления
Представления, в которых тип модели не объявляется с помощью @model, но в которые вместо этого передается экземпляр модели (например, return View(Address);), могут ссылаться на свойства экземпляра динамически.
<address>
@Model.Street<br>
@Model.City, @Model.State @Model.PostalCode<br>
<abbr title="Phone">P:</abbr> 425.555.0100
</address>
Эта возможность повышает гибкость, но не обеспечивает защиту компиляции или функцию IntelliSense. Если свойство не существует, создание веб-страницы завершается сбоем во время выполнения.
Больше функций представления
Вспомогательные функции тегов упрощают реализацию поведения на стороне сервера в существующих HTML-тегах. Использование Tag Helpers избавляет от необходимости писать пользовательский код или вспомогательные функции в ваших представлениях. Вспомогательные функции тегов применяются к элементам HTML как атрибуты и игнорируются редакторами, которые не поддерживают их. Это позволяет редактировать и визуализировать разметку представлений в различных средствах.
Пользовательская HTML-разметка может формироваться с помощью множества встроенных вспомогательных функций HTML. View Components могут обрабатывать более сложную логику пользовательского интерфейса. Компоненты представлений предоставляют те же возможности SoC, что и контроллеры и представления. Они могут устранить необходимость в действиях и представлениях, предназначенных для работы с данными, которые используются общими элементами пользовательского интерфейса.
Как и многие другие аспекты ASP.NET Core, представления поддерживают внедрение зависимостей, которое позволяет внедрять службы в представления.
Изоляция CSS
Изоляция стилей CSS для отдельных страниц, представлений и компонентов, чтобы сократить или избежать следующего:
- Зависимости от глобальных стилей, которые могут быть сложными в обслуживании.
- Конфликты стилей во вложенном содержимом.
Чтобы добавить CSS-файл с заданной областью для страницы или представления, поместите стили CSS в сопутствующий файл .cshtml.css, имя которого соответствует имени файла .cshtml. В следующем примере файл Index.cshtml.css предоставляет стили CSS, которые применяются только к представлению или странице Index.cshtml.
Pages/Index.cshtml.css (Razor Pages) или Views/Index.cshtml.css (MVC):
h1 {
color: red;
}
Изоляция CSS выполняется во время сборки. Платформа повторно создает селекторы CSS в соответствии с разметкой, отображаемой на страницах или в представлениях приложения. Переписанные стили CSS объединяются и создаются в виде статического ресурса {APP ASSEMBLY}.styles.css. Заполнитель {APP ASSEMBLY} — это имя сборки проекта. Ссылка на объединенные стили CSS помещается в макет приложения.
В содержимом <head> файла Pages/Shared/_Layout.cshtml приложения (Razor Pages) или Views/Shared/_Layout.cshtml (MVC) приложения добавьте ссылку на объединенные стили CSS или подтвердите ее наличие:
<link rel="stylesheet" href="~/{APP ASSEMBLY}.styles.css" />
В следующем примере имя сборки приложения — WebApp:
<link rel="stylesheet" href="WebApp.styles.css" />
Стили, определенные в файле CSS с заданной областью, применяются только к отображаемым выходным данным соответствующего файла. В предыдущем примере все объявления CSS h1, определенные в других частях приложения, не будут конфликтовать со стилем заголовка Index. Правила каскадов и наследования стилей CSS и дальше действуют для файлов CSS с заданной областью. Например, стили, примененные непосредственно к элементу <h1> в файле Index.cshtml, переопределяют стили файла CSS с заданной областью в Index.cshtml.css.
Примечание.
Чтобы обеспечить изоляцию стиля CSS при выполнении объединения, импорт CSS в блоки кода Razor не поддерживается.
Изоляция CSS применяется только к элементам HTML. Изоляция CSS не поддерживается для вспомогательных функций тегов.
В объединенном файле CSS каждая страница, представление или компонент Razor связаны с идентификатором области в формате b-{STRING}, где заполнитель {STRING} представляет собой строку из десяти символов, сгенерированную платформой. В следующем примере представлен стиль для предыдущего элемента <h1> на странице Index приложения Razor Pages:
/* /Pages/Index.cshtml.rz.scp.css */
h1[b-3xxtam6d07] {
color: red;
}
На странице Index, где применяется стиль CSS из объединенного файла, идентификатор области добавляется как атрибут HTML:
<h1 b-3xxtam6d07>
Идентификатор является уникальным для приложения. Во время сборки создается пакет проекта с использованием соглашения {STATIC WEB ASSETS BASE PATH}/Project.lib.scp.css, где метка {STATIC WEB ASSETS BASE PATH} является базовым путем к статическим веб-ресурсам.
Если используются другие проекты, такие как пакеты NuGet или библиотеки классов Razor, то объединенный файл:
- ссылается на стили с помощью импорта CSS;
- не публикуется как статический веб-ресурс приложения, использующего стили.
Поддержка препроцессоров CSS
Препроцессоры CSS полезны для улучшения разработки CSS с помощью таких функций, как переменные, вложенность, модули, примеси и наследование. Хотя изоляция CSS изначально не поддерживает препроцессоры CSS, такие как Sass и Less, интеграция препроцессоров CSS происходит без проблем, так как компиляция препроцессора выполняется до того, как платформа перезаписывает селекторы CSS в процессе сборки. С помощью Visual Studio, например, настройте существующую компиляцию препроцессора в качестве задачи перед сборкой в диспетчере выполнения задач Visual Studio.
Многие сторонние пакеты NuGet, такие как AspNetCore.SassCompiler, могут компилировать файлы SASS и SCSS в начале процесса сборки перед выполнением изоляции CSS, и дополнительная настройка не требуется.
Конфигурация изоляции CSS
Изоляция CSS позволяет настраивать некоторые сложные сценарии, например включающих зависимости от существующих инструментов или рабочих процессов.
Настройка формата идентификатора области
В этом разделе заполнитель {Pages|Views} — либо Pages для приложений Razor Pages, либо Views для приложений MVC.
По умолчанию идентификаторы областей используют формат b-{STRING}, где заполнитель {STRING} — это строка из десяти символов, сгенерированная платформой. Чтобы настроить формат идентификатора области, измените шаблон в файле проекта:
<ItemGroup>
<None Update="{Pages|Views}/Index.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
В предыдущем примере CSS, сформированный для Index.cshtml.css, изменяет свой идентификатор области с b-{STRING} на custom-scope-identifier.
Используйте идентификаторы областей, чтобы обеспечить наследование файлов CSS с назначенной областью. В следующем примере файла проекта файл BaseView.cshtml.css содержит общие стили для всех представлений. Файл DerivedView.cshtml.css наследует эти стили.
<ItemGroup>
<None Update="{Pages|Views}/BaseView.cshtml.css" CssScope="custom-scope-identifier" />
<None Update="{Pages|Views}/DerivedView.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Используйте оператор подстановочного знака (*), чтобы предоставить идентификаторы областей для нескольких файлов:
<ItemGroup>
<None Update="{Pages|Views}/*.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Изменение базового пути для статических веб-активов
Файл CSS с заданной областью создается в корне приложения. Чтобы изменить путь по умолчанию, используйте свойство StaticWebAssetBasePath в файле проекта. В следующем примере CSS-файл с областью действия и остальные ресурсы приложения размещаются на пути _content.
<PropertyGroup>
<StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>
Отключение автоматического объединения
Чтобы отказаться от того, как платформа публикует и загружает файлы с заданной областью во время выполнения, используйте свойство DisableScopedCssBundling. При использовании этого свойства за получение изолированных файлов CSS из каталога obj и их публикацию и загрузку во время выполнения отвечают другие средства или процессы:
<PropertyGroup>
<DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>
Поддержка библиотеки классов Razor (RCL)
Когда библиотека классов Razor (RCL) предоставляет изолированные стили, атрибут <link> тега href указывает на {STATIC WEB ASSET BASE PATH}/{PACKAGE ID}.bundle.scp.css со следующими заполнителями:
-
{STATIC WEB ASSET BASE PATH}: базовый путь статического веб-ресурса. -
{PACKAGE ID}: идентификатор пакета библиотеки. Если идентификатор пакета не указан в файле проекта, идентификатору пакета по умолчанию присваивается имя сборки проекта.
В следующем примере :
- Базовый путь к статическому веб-ресурсу —
_content/ClassLib. - Имя сборки библиотеки классов —
ClassLib.
Pages/Shared/_Layout.cshtml (Razor Pages) или Views/Shared/_Layout.cshtml (MVC):
<link href="_content/ClassLib/ClassLib.bundle.scp.css" rel="stylesheet">
Дополнительные сведения о RCL см. в следующих статьях:
- Повторно используемый пользовательский интерфейс Razor в библиотеках классов с ASP.NET Core
- Использование компонентов ASP.NET Core Razor из библиотеки классов Razor (RCL)
Сведения об изоляции CSS в Blazor см. в статье Изоляция CSS Blazor в ASP.NET Core.
ASP.NET Core