Ansichten in ASP.NET Core MVC
Von Steve Smith und Dave Brock
In diesem Artikel werden die Ansichten erläutert, die in ASP.NET Core MVC-Anwendungen verwendet werden. Informationen zu Razor Pages finden Sie unter Einführung in Razor Pages in ASP.NET Core.
Im Muster Model-View-Controller (MVC) verarbeitet die Ansicht die Darstellung der App-Daten und der Benutzerinteraktion. Bei einer Ansicht handelt es sich um eine HTML-Vorlage mit eingebettetem Razor-Markup. Bei Razor-Markup handelt es sich um Code, der mit HTML-Markup interagiert, um eine Webseite zu generieren, die an den Client gesendet wird.
In ASP.NET Core MVC sind Ansichten .cshtml
-Dateien, die die Programmiersprache C# in Razor-Markup verwenden. In der Regel werden Ansichtsdateien in Ordnern gruppiert, die für jeden Controller der App benannt werden. Die Ordner werden im Ordner Views
im Stammverzeichnis der App gespeichert:
Der Home
-Controller wird durch einen Home
-Ordner innerhalb des Ordners Views
dargestellt. Der Ordner Home
enthält die Ansichten für die Webseiten About
, Contact
und Index
(Homepage). Wenn ein*e Benutzer*in eine dieser drei Webseiten aufruft, legen Controlleraktionen im Home
-Controller fest, welche der drei Ansichten verwendet werden, um Webseiten zu erstellen und diese an den oder die Benutzer*in zurückzugeben.
Verwenden Sie Layouts, damit die Abschnitte der Webseiten konsistent angezeigt werden und die Wiederholung von Code vermieden wird. Layouts bestehen in der Regel aus der Kopfzeile, der Navigation, Menüelementen und der Fußzeile. Die Kopf- und die Fußzeile enthalten in der Regel Markupbausteine für viele Metadatenelemente sowie Links zu Skripts und Stilelemente. Mithilfe von Layouts können Sie die Markupbausteine in Ihren Ansichten vermeiden.
Über Teilansichten wird weniger Code dupliziert, indem wiederverwendbare Bestandteile der Ansichten verwaltet werden. Sie sind z.B. nützlich für Autorenbiografien auf einem Blog, die in verschiedenen Ansichten angezeigt werden. Bei einer Autorenbiografie handelt es sich um gewöhnlichen Inhalt von Ansichten. Sie erfordern keinen Code, der ausgeführt werden muss, um den Inhalt für die Webseite herzustellen. Die Ansicht kann auf die Inhalte der Autorenbiografie über eine Modellbindung zugreifen. Daher sollten idealerweise Teilansichten für diese Art von Inhalt verwendet werden.
Über Ansichtskomponenten können Sie genauso wie über Teilansichten Wiederholungen von Code reduzieren. Sie sind besonders geeignet für Inhalt von Ansichten, für den Code auf dem Server ausgeführt werden muss, um die Webseite zu rendern. Ansichtskomponenten sind nützlich, wenn der gerenderte Inhalt Datenbankinformationen erfordert, z.B. bei einem Warenkorb auf einer Website. Ansichtskomponenten sind nicht auf Modellbindungen beschränkt, um Webseitenausgaben herzustellen.
Vorteile der Verwendung von Ansichten
Über Ansichten kann in einer MVC-App eine Trennung von Belangen erfolgen, indem das Markup der Benutzeroberfläche von anderen Bestandteilen der App getrennt wird. Das SoC-Design macht Ihre App modularer. Dies hat folgende Vorteile:
- Die App kann einfacher verwaltet werden, da sie besser organisiert ist. Ansichten werden in der Regel nach App-Features gruppiert. Dadurch können Sie zugehörige Ansichten leichter finden, wenn Sie an einem Feature arbeiten.
- Die Bestandteile der App sind lose miteinander verknüpft. Sie können die Ansichten der App getrennt von der Geschäftslogik und den Datenzugriffskomponenten erstellen und aktualisieren. Sie können die Ansichten der App verändern, müssen dafür aber nicht unbedingt andere Bestandteile der App aktualisieren.
- Sie können die Bestandteile der Benutzeroberfläche der App leichter testen, da es sich bei den Ansichten um voneinander getrennte Einheiten handelt.
- Durch die verbesserte Organisation sinkt die Wahrscheinlichkeit, dass Sie versehentlich Code für die Benutzeroberfläche wiederholt schreiben.
Erstellen einer Ansicht
Ansichten, die nur für bestimmte Controller gelten, werden im Ordner Views/[ControllerName]
erstellt. Ansichten, die von mehreren Controllern verwendet werden können, werden im Ordner Views/Shared
gespeichert. Wenn Sie eine Ansicht erstellen möchten, fügen Sie eine neue Datei hinzu, und geben Sie ihr denselben Namen wie der zugehörigen Controlleraktion mit der Erweiterung .cshtml
. Wenn Sie eine Ansicht erstellen möchten, die mit der Aktion About
im Home
-Controller übereinstimmt, erstellen Sie eine About.cshtml
-Datei im Ordner Views/Home
:
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p>
Das Razor-Markup beginnt mit dem Symbol @
. Führen Sie C#-Anweisungen aus, indem Sie C#-Code in den Razor-Codeblöcken speichern, die von geschweiften Klammern ({ ... }
) umgeben sind. Weitere Informationen finden Sie im obenstehenden Beispiel für die Zuweisung von „Hilfe“ zu ViewData["Title"]
. Sie können Werte innerhalb von HTML-Code angeben, indem Sie auf den Wert mit dem Symbol @
verweisen. Weitere Informationen finden Sie in den Inhalten der obenstehenden Elemente <h2>
und <h3>
.
Der obenstehende Inhalt der Ansicht ist nur ein Teil der gesamten Webseite, die für den Benutzer gerendert wird. Der Rest des Seitenlayouts und andere häufig auftretende Aspekte werden in anderen Ansichtsdateien angegeben. Weitere Informationen dazu finden Sie im Artikel Layout.
Angeben von Ansichten durch Controller
Ansichten werden in der Regel von Aktionen als ViewResult zurückgegeben. Dabei handelt es sich um eine Art ActionResult. Über Ihre Aktionsmethode kann eine ViewResult
-Klasse direkt erstellt und zurückgegeben werden. Diese Methode wird allerdings selten genutzt. Da die meisten Controller von Controller erben, können Sie einfach die View
-Hilfsprogrammmethode verwenden, um ViewResult
zurückzugeben:
HomeController.cs
:
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
Wenn diese Aktion zurückgegeben wird, wird die im letzten Abschnitt angezeigte About.cshtml
-Ansicht als folgende Webseite gerendert:
Für die View
-Hilfsprogrammmethode gibt es einige Überladungen. Sie können bei Bedarf folgende Elemente angeben:
Eine explizite Ansicht, die zurückgegeben werden soll:
return View("Orders");
Ein Modell, das an die Ansicht übergeben werden soll:
return View(Orders);
Sowohl eine Ansicht als auch ein Modell:
return View("Orders", Orders);
Ansichtsermittlung
Wenn eine Aktion eine Ansicht zurückgibt, wird ein Prozess namens Ansichtsermittlung ausgelöst. Über diesen Prozess wird auf Grundlage des Ansichtsnamens festgelegt, welche Ansichtsdatei verwendet wird.
Standardmäßig gibt die View
-Methode (return View();
) eine Ansicht zurück, die denselben Namen wie die Aktionsmethode besitzt, über die diese aufgerufen wird. Der About
ActionResult
-Methodenname des Controllers wird verwendet, um nach einer Ansichtsdatei mit dem Namen About.cshtml
zu suchen. Zuerst sucht die Runtime im Ordner Views/[ControllerName]
nach der Ansicht. Wenn keine passende Ansicht gefunden wird, wird im Ordner Shared
nach der Ansicht gesucht.
Es macht keinen Unterschied, ob Sie implizit ViewResult
mit return View();
zurückgeben, oder den Ansichtsnamen mit return View("<ViewName>");
explizit an die View
-Methode übergeben. In beiden Fällen sucht die Ansichtsermittlung nach einer passenden Ansichtsdatei in diesem Ordner:
Views/\[ControllerName]/\[ViewName].cshtml
Views/Shared/\[ViewName].cshtml
Anstelle eines Ansichtsnamens kann auch ein Pfad zu einer Ansichtsdatei verwendet werden. Wenn Sie einen absoluten Pfad im Stammverzeichnis der App verwenden (der mit „/“ oder „~/“ beginnt), muss die Erweiterung .cshtml
angegeben sein:
return View("Views/Home/About.cshtml");
Sie können auch einen relativen Pfad verwenden, um Ansichten in verschiedenen Verzeichnissen ohne die Erweiterung .cshtml
anzugeben. In der HomeController
-Klasse können Sie die Ansicht Index
in Ihrer Manage
-Ansicht mit einem relativen Pfad angeben:
return View("../Manage/Index");
Genauso können Sie auch das aktuelle controllerspezifische Verzeichnis mit dem Präfix „./“ angeben:
return View("./About");
Teilansichten und Ansichtskomponenten verwenden ähnliche (aber nicht identische) Ermittlungsmechanismen.
Sie können die Standardkonvention zum Suchen von Ansichten in der App anpassen, indem Sie eine benutzerdefinierte IViewLocationExpander-Schnittstelle verwenden.
Die Ansichtsermittlung ist davon abhängig, ob Ansichtsdateien über Dateinamen gefunden werden. Wenn das zugrunde liegende Dateisystem die Groß-/Kleinschreibung beachtet, wird wahrscheinlich auch bei den Ansichtsnamen zwischen Groß- und Kleinschreibung unterschieden. Damit die Kompatibilität für alle Betriebssysteme eingehalten werden kann, müssen Sie Groß-/Kleinbuchstaben zwischen dem Controller und den Aktionsnamen sowie den zugeordneten Ansichtsordnern und Dateinamen aufeinander abstimmten. Wenn ein Fehler ausgelöst wird und eine Ansichtsdatei nicht gefunden werden kann, während Sie mit einem Dateisystem arbeiten, das zwischen Groß- und Kleinbuchstaben unterscheidet, bestätigen Sie, dass die Groß-/Kleinschreibung der gesuchten Ansichtsdatei mit dem tatsächlichen Dateinamen der Ansicht übereinstimmt.
Halten Sie sich an die bewährten Methoden zum Organisieren der Dateistruktur Ihrer Ansichten, um die Beziehungen zwischen Controllern, Aktionen und Ansichten auf die Verwaltbarkeit und Klarheit auszurichten.
Übergeben von Daten an Ansichten
Übergeben Sie Daten über verschiedene Ansätze an Ansichten:
- Stark typisierte Daten: viewmodel
- Schwach typisierte Daten
ViewData
(ViewDataAttribute
)ViewBag
Stark typisierte Daten (viewmodel)
Wenn Sie Stabilität wünschen, sollten Sie einen Modell-Typen in der Ansicht angeben. Das Modell wird häufig als Ansichtsmodell bezeichnet. Übergeben Sie eine Instanz des Ansichtsmodelltyps an die Ansicht aus der Aktion.
Wenn Sie ein Ansichtsmodell verwenden, um eine Ansicht zu übergeben, kann die Ansicht die Vorteile der starken Typüberprüfung nutzen. Man spricht von starker Typisierung (oder stark typisiert als Adjektiv), wenn es für jede Variable und jede Konstante einen explizit definierten Typ gibt, z.B. string
, int
oder DateTime
. Die Gültigkeit der in der Ansicht verwendeten Typen wird zur Kompilierzeit überprüft.
Visual Studio und Visual Studio Code erstellen Listen von stark typisierten Klassenmembern mithilfe des Features IntelliSense. Wenn Sie die Eigenschaften eines Ansichtsmodell anzeigen wollen, geben Sie den Namen der Variablen für dieses an, und setzen Sie einen Punkt (.
). Dadurch können Sie Code schneller schreiben, und Sie machen weniger Fehler.
Geben Sie mithilfe der @model
-Anweisung ein Modell an. Verwenden Sie das Modell mit @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>
Der Controller übergibt das Modell als Parameter, um es für die Ansicht bereitzustellen:
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);
}
Es gibt keine Einschränkungen der Modelltypen, die in einer Ansicht enthalten sein sollten. Es wird empfohlen, Plain Old CLR Object-Ansichtsmodelle (POCO) mit wenigen oder gar keinen definierten Methoden zu verwenden. In der Regel werden Ansichtsmodellklassen weder im Ordner Models
noch in einem separaten ViewModels
-Ordner im Stammverzeichnis der App gespeichert. Bei dem im zuvor genannten Beispiel verwendeten Address
-Ansichtsmodell handelt es sich um ein POCO-Ansichtsmodell, das in einer Datei mit dem Namen Address.cs
gespeichert ist:
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; }
}
}
Es ist möglich, für die Ansichtsmodelltypen und Unternehmensmodelltypen dieselben Klassen zu verwenden. Wenn Sie allerdings unterschiedliche Modelle verwenden, können Ihre Ansichten unabhängig von der Geschäftslogik und den Bestandteilen zum Datenzugriff Ihrer App variieren. Wenn Sie Modelle und Ansichtsmodelle trennen, wird mehr Sicherheit geboten, wenn Modelle die Modellbindung und die Validierung von Daten verwenden, die vom Benutzer an die App gesendet werden.
Schwach typisierte Daten (ViewData
, [ViewData]
-Attribut und ViewBag
)
ViewBag
ist standardmäßig nicht für die Verwendung in Razor Pages-PageModel
-Klassen verfügbar.
Ansichten haben nicht nur Zugriff auf stark typisierte Datensammlungen, sondern auch auf schwach typisierte (auch als lose typisiert bezeichnet). Im Gegensatz zu starken Typen werden bei schwachen Typen (oder losen Typen) nicht explizit die Datentypen deklariert, die Sie verwenden. Sie können die Sammlung schwach typisierter Daten verwenden, um kleinere Datenmengen an Controller und Ansichten zu übergeben oder sie ihnen zu entnehmen.
Übergeben von Daten zwischen... | Beispiel |
---|---|
einem Controller und einer Ansicht | Auffüllen einer Dropdownliste mit Daten |
einer Ansicht und einer Layoutansicht | Legt den <title> -Elementinhalt in der Layoutansicht über eine Ansichtsdatei fest |
einer Teilansicht und einer Ansicht | Ein Widget, das Daten anzeigt, die der Webseite zugrunde liegen, die der Benutzer angefordert hat. |
Auf diese Sammlung kann entweder über die Eigenschaft ViewData
oder über die Eigenschaft ViewBag
auf Controller und Ansichten verwiesen werden. Die ViewData
-Eigenschaft ist ein Wörterbuch, das aus schwach typisierten Objekten besteht. Bei der ViewBag
-Eigenschaft handelt es sich um einen Wrapper um ViewData
, der dynamische Eigenschaften für die zugrunde liegende ViewData
-Sammlung bereitstellt. Hinweis: Bei Lookupvorgängen für Schlüssel wird für ViewData
und ViewBag
die Groß-/Kleinschreibung nicht beachtet.
ViewData
und ViewBag
werden zur Laufzeit dynamisch aufgelöst. Da in diesen Elementen keine Typüberprüfung zur Kompilierzeit enthalten sind, sind beide in der Regel fehleranfälliger als Ansichtsmodelle. Aus diesem Grund verwenden Entwickler ViewData
und ViewBag
selten oder nie.
ViewData
ViewData
ist ein ViewDataDictionary-Objekt, auf das über string
-Schlüssel zugegriffen wird. Zeichenfolgendaten können gespeichert und ohne Umwandlung direkt verwendet werden. Trotzdem müssen Sie für die Extraktion andere ViewData
-Objektwerte in bestimmte Typen umwandeln. Sie können ViewData
verwenden, um Daten von Controllern an Ansichten und innerhalb von Ansichten zu übergeben, einschließlich Teilansichten und Layouts.
Im Folgenden finden Sie ein Beispiel, über das Werte für eine Begrüßung und eine Anrede mithilfe von ViewData
in einer Aktion festgelegt werden:
public IActionResult SomeAction()
{
ViewData["Greeting"] = "Hello";
ViewData["Address"] = new Address()
{
Name = "Steve",
Street = "123 Main St",
City = "Hudson",
State = "OH",
PostalCode = "44236"
};
return View();
}
Arbeiten Sie mit den Daten in einer Ansicht:
@{
// 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]
-Attribut
Ein anderer Ansatz, der ViewDataDictionary verwendet, ist ViewDataAttribute. Die Werte der Eigenschaften in Controllern oder Razor Pages-Modellen, die mit dem [ViewData]
-Attribut gekennzeichnet sind, werden im Wörterbuch gespeichert und daraus geladen.
Im folgenden Beispiel enthält der Home-Controller eine Title
-Eigenschaft, die mit [ViewData]
gekennzeichnet ist. Die About
-Methode legt den Titel der Infoansicht fest:
public class HomeController : Controller
{
[ViewData]
public string Title { get; set; }
public IActionResult About()
{
Title = "About Us";
ViewData["Message"] = "Your application description page.";
return View();
}
}
Im Layout wird der Titel aus dem ViewData-Wörterbuch gelesen:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
ViewBag
ViewBag
ist standardmäßig nicht für die Verwendung in Razor Pages-PageModel
-Klassen verfügbar.
ViewBag
ist ein Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData
-Objekt, das den dynamischen Zugriff auf die in ViewData
gespeicherten Objekte ermöglicht. Es ist angenehmer, mit ViewBag
zu arbeiten, da keine Umwandlung erforderlich ist. Im Folgenden finden Sie ein Beispiel, in dem dargestellt wird, wie Sie mit ViewBag
das gleiche Ergebnis wie mit ViewData
erzielen:
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>
Gleichzeitiges Verwenden von ViewData
und ViewBag
ViewBag
ist standardmäßig nicht für die Verwendung in Razor Pages-PageModel
-Klassen verfügbar.
Da ViewData
und ViewBag
beide auf dieselbe zugrunde liegende ViewData
-Sammlung verweisen, können Sie sowohl ViewData
als auch ViewBag
verwenden, und zwischen beiden Elementen wechseln, wenn Sie Werte schreiben und lesen.
Legen Sie oben in einer ViewBag
-Ansicht mithilfe von ViewData
den Titel und mithilfe von About.cshtml
die Beschreibung fest:
@{
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "About Contoso";
ViewData["Description"] = "Let us tell you about Contoso's philosophy and mission.";
}
Lesen Sie die Eigenschaften, aber verwenden Sie ViewData
und ViewBag
in umgekehrter Reihenfolge. Rufen Sie in der _Layout.cshtml
-Datei mithilfe von ViewData
den Titel und mithilfe von ViewBag
die Beschreibung ab:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"]</title>
<meta name="description" content="@ViewBag.Description">
...
Bedenken Sie, dass für Zeichenfolgen mit ViewData
keine Umwandlung erforderlich ist. @ViewData["Title"]
kann ohne Umwandlung verwendet werden.
Sie können ViewData
und ViewBag
gleichzeitig verwenden und zwischen dem Lesen und Schreiben der Eigenschaften abwechseln. Das folgende Markup wird gerendert:
<!DOCTYPE html>
<html lang="en">
<head>
<title>About Contoso</title>
<meta name="description" content="Let us tell you about Contoso's philosophy and mission.">
...
Zusammenfassung der Unterschiede zwischen ViewData
und ViewBag
ViewBag
ist standardmäßig nicht für die Verwendung in Razor Pages-PageModel
-Klassen verfügbar.
ViewData
- Wird von ViewDataDictionary abgeleitet und verfügt daher über Wörterbucheigenschaften wie
ContainsKey
,Add
,Remove
undClear
, die nützlich sein können. - Schlüssel sind Zeichenfolgen im Wörterbuch. Daher sind Leerzeichen erlaubt. Beispiel:
ViewData["Some Key With Whitespace"]
- Jeder Typ, der von
string
abweicht, muss in der Ansicht umgewandelt werden, sodassViewData
verwendet werden kann.
- Wird von ViewDataDictionary abgeleitet und verfügt daher über Wörterbucheigenschaften wie
ViewBag
- Wird von
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData
abgeleitet und ermöglicht daher die Erstellung von dynamischen Eigenschaften über die Punktnotation (@ViewBag.SomeKey = <value or object>
), und es ist keine Umwandlung erforderlich. Über die Syntax vonViewBag
können Controller und Ansichten schneller hinzugefügt werden. - Es ist einfacher, nach NULL-Werten zu suchen. Beispiel:
@ViewBag.Person?.Name
- Wird von
Verwendung von ViewData
oder ViewBag
ViewData
und ViewBag
sind beides gültige Ansätze, wenn Sie kleinere Datenmengen zwischen Controllern und Ansichten übergeben möchten. Sie können beliebig entscheiden, welche Methode Sie verwenden möchten. Sie können zwar ViewData
- und ViewBag
-Objekte miteinander vermischen, jedoch ist es einfacher, den Code zu lesen und zu verwalten, wenn nur ein Ansatz verwendet wird. Beide Ansätze werden zur Laufzeit dynamisch aufgelöst, wodurch häufig Laufzeitfehler entstehen. Einige Entwicklerteams vermeiden diese Ansätze daher.
Dynamische Ansichten
Ansichten, die einen Modelltyp nicht mit @model
deklarieren, an die aber eine Modellinstanz übergeben wird (z.B. return View(Address);
), können dynamisch auf die Eigenschaften der Instanz verweisen:
<address>
@Model.Street<br>
@Model.City, @Model.State @Model.PostalCode<br>
<abbr title="Phone">P:</abbr> 425.555.0100
</address>
Dieses Feature bietet zwar Flexibilität, jedoch weder Kompilierungsschutz noch IntelliSense. Wenn die Eigenschaft nicht vorhanden ist, löst die Webseitengenerierung zur Laufzeit einen Fehler aus.
Weitere Ansichtsfeatures
Mithilfe von Taghilfsprogrammen können Sie einfach serverseitiges Verhalten zu vorhandenen HTML-Tags hinzufügen. Wenn Sie Taghilfsprogramme verwenden, müssen Sie keinen benutzerdefinierten Code oder Hilfsprogramme in Ihren Ansichten schreiben. Taghilfsprogramme werden als Attribute für HTML-Elemente angewendet und werden von Editors ignoriert, da sie diese nicht verarbeiten können. Dadurch können Sie Ansichtsmarkups in verschiedenen Tools bearbeiten und rendern.
Sie können benutzerdefinierte HTML-Markups über verschiedene integrierte HTML-Hilfsprogramme generieren. Eine komplexere Logik von Benutzeroberflächen kann über Ansichtskomponenten verarbeitet werden. Ansichtskomponenten stellen dieselben SoC-Designs bereit, die Controller und Ansichten bereitstellen. Wenn diese verwendet werden, werden keine Aktionen und Ansichten benötigt, die Daten verarbeiten, die von häufig verwendeten Benutzeroberflächenelementen verwendet werden.
Wie viele andere Aspekte von ASP.NET Core unterstützen Ansichten Dependency Injection und lassen zu, dass Dienste in Ansichten eingefügt werden.
CSS-Isolation
Isolieren Sie zur Reduzierung oder Vermeidung CSS-Formatvorlagen auf einzelne Seiten, Ansichten und Komponenten:
- Abhängigkeiten von globalen Stilen, die eine Herausforderung darstellen können
- Formatkonflikte in geschachtelten Inhalten
Um eine bereichsbezogene CSS-Datei für eine Seite oder Ansicht hinzuzufügen, platzieren Sie die CSS-Stile in der Begleitdatei .cshtml.css
, die dem Namen der .cshtml
-Datei entspricht. Im folgenden Beispiel liefert eine Index.cshtml.css
-Datei CSS-Stile, die nur auf die Index.cshtml
-Seite oder -Ansicht angewendet werden.
Pages/Index.cshtml.css
(Razor Pages) oder Views/Index.cshtml.css
(MVC):
h1 {
color: red;
}
Die CSS-Isolation erfolgt zum Zeitpunkt der Erstellung. Das Framework schreibt CSS-Selektoren so um, dass sie mit Markup übereinstimmen, das von den Seiten oder Ansichten der App gerendert wird. Die umgeschriebenen CSS-Stile werden gebündelt und als statisches Objekt ({APP ASSEMBLY}.styles.css
) erzeugt. Der Platzhalter {APP ASSEMBLY}
ist der Assemblyname des Projekts. Ein Link zu den gebündelten CSS-Stilen wird im Layout der App platziert.
Im Inhalt von <head>
der Datei Pages/Shared/_Layout.cshtml
(Razor Pages) oder Views/Shared/_Layout.cshtml
(MVC) der App fügen Sie den Link zu den gebündelten CSS-Styles hinzu oder bestätigen ihn:
<link rel="stylesheet" href="~/{APP ASSEMBLY}.styles.css" />
Im folgenden Beispiel lautet der Assemblyname der App WebApp
:
<link rel="stylesheet" href="WebApp.styles.css" />
Die in einer bereichsbezogenen CSS-Datei definierten Stile werden nur auf die gerenderte Ausgabe der entsprechenden Datei angewendet. Im vorherigen Beispiel stehen alle CSS-Deklarationen von h1
, die an anderer Stelle in der App definiert sind, nicht in Konflikt mit dem Überschriftenstil von Index
. CSS- und Vererbungsregeln bleiben für bereichsbezogene CSS-Dateien gültig. Beispielsweise überschreiben Stile, die direkt auf ein <h1>
-Element in der Index.cshtml
-Datei angewendet werden, die Stile der bereichsbezogenen CSS-Datei in Index.cshtml.css
.
Hinweis
Um die Isolation des CSS-Stils beim Bündeln zu gewährleisten, wird der Import von CSS in Razor-Codeblöcken nicht unterstützt.
CSS-Isolation gilt nur für HTML-Elemente. CSS-Isolation wird für Taghilfsprogramme nicht unterstützt.
Innerhalb der gebündelten CSS-Datei ist jede Seite, Ansicht oder Razor-Komponente mit einem Bereichsbezeichner im Format b-{STRING}
verknüpft, wobei der Platzhalter {STRING}
eine zehnstellige Zeichenfolge ist, die vom Framework generiert wird. Das folgende Beispiel liefert den Stil für das vorherige <h1>
-Element der Seite Index
einer Razor Pages-App:
/* /Pages/Index.cshtml.rz.scp.css */
h1[b-3xxtam6d07] {
color: red;
}
Auf der Seite Index
, auf der der CSS-Stil aus der gebündelten Datei angewendet wird, wird der Bereichsbezeichner als HTML-Attribut angefügt:
<h1 b-3xxtam6d07>
Der Bezeichner ist für eine App eindeutig. Zum Zeitpunkt der Erstellung wird ein Projektbündel mit der Konvention {STATIC WEB ASSETS BASE PATH}/Project.lib.scp.css
erstellt, wobei der Platzhalter {STATIC WEB ASSETS BASE PATH}
der statische Basispfad für Webressourcen ist.
Wenn andere Projekte verwendet werden, z. B. NuGet-Pakete oder Razor-Klassenbibliotheken, gilt für die gebündelte Datei Folgendes:
- Verweise auf Stile erfolgen mithilfe von CSS-Importen.
- Sie wird nicht als statische Webressource der App veröffentlicht, die die Stile verwendet.
Unterstützung für CSS-Präprozessoren
CSS-Präprozessoren tragen zur Verbesserung der CSS-Entwicklung bei, indem sie Features wie Variablen, Schachtelung, Module, Mischung und Vererbung nutzen. CSS-Isolation unterstützt CSS-Präprozessoren wie Sass oder Less zwar nicht nativ, dennoch können CSS-Präprozessoren nahtlos integriert werden, sofern die Kompilierung des Präprozessors erfolgt, bevor das Framework die CSS-Selektoren während des Buildprozesses umschreibt. Konfigurieren Sie z. B. mithilfe von Visual Studio die vorhandene Präprozessorkompilierung als Aufgabe Vor Build im Aufgabenausführungs-Explorer von Visual Studio.
Viele NuGet-Pakete von Drittanbietern wie z. B. AspNetCore.SassCompiler
, können die SASS-/SCSS-Dateien am Anfang des Buildprozesses – noch vor der CSS-Isolation – kompilieren, ohne dass eine Konfiguration erforderlich ist.
Konfiguration der CSS-Isolation
CSS-Isolation ermöglicht die Konfiguration einiger fortgeschrittener Szenarien, z. B. wenn Abhängigkeiten von vorhandenen Tools oder Workflows bestehen.
Anpassen des Formats von Bereichsbezeichnern
In diesem Abschnitt ist der Platzhalter {Pages|Views}
entweder Pages
für Razor Pages-Apps oder Views
für MVC-Apps.
Standardmäßig verwenden Bereichsbezeichner das Format b-{STRING}
, wobei der Platzhalter {STRING}
eine vom Framework generierte Zeichenfolge mit zehn Zeichen ist. Um das Format der Bereichsbezeichner anzupassen, aktualisieren Sie die Projektdatei mit dem gewünschten Muster:
<ItemGroup>
<None Update="{Pages|Views}/Index.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Im vorherigen Beispiel ändert der für Index.cshtml.css
generierte CSS-Code seinen Bereichsbezeichner von b-{STRING}
in custom-scope-identifier
.
Verwenden Sie Bereichsbezeichner, um eine Vererbung mit bereichsbezogenen CSS-Dateien zu erzielen. Im folgenden Beispiel für eine Projektdatei enthält eine BaseView.cshtml.css
-Datei allgemeine Stile für Ansichten. Eine DerivedView.cshtml.css
-Datei erbt diese Stile.
<ItemGroup>
<None Update="{Pages|Views}/BaseView.cshtml.css" CssScope="custom-scope-identifier" />
<None Update="{Pages|Views}/DerivedView.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Verwenden Sie den Platzhalteroperator (*
), um Bereichsbezeichner für mehrere Dateien freizugeben:
<ItemGroup>
<None Update="{Pages|Views}/*.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Ändern des Basispfads für statische Webressourcen
Die bereichsbezogene CSS-Datei wird im Stammverzeichnis der App generiert. Verwenden Sie in der Projektdatei die StaticWebAssetBasePath
-Eigenschaft, um den Standardpfad zu ändern. Im folgenden Beispiel werden die bereichsbezogene CSS-Datei und der Rest der rest der App unter dem Pfad _content
gespeichert:
<PropertyGroup>
<StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>
Deaktivieren der automatischen Bündelung
Wenn Sie das Verhalten des Frameworks beim Veröffentlichen und Laden bereichsbezogener Dateien zur Laufzeit ändern möchten, verwenden Sie die DisableScopedCssBundling
-Eigenschaft. Die Verwendung dieser Eigenschaft bedeutet, dass die isolierten CSS-Dateien durch andere Tools oder Prozesse aus dem Verzeichnis obj
übernommen und zur Laufzeit veröffentlicht und geladen werden:
<PropertyGroup>
<DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>
Unterstützung für Razor-Klassenbibliothek (RCL)
Wenn eine Razor-Klassenbibliothek (RCL) isolierte Stile bereitstellt, zeigt das href
-Attribut des <link>
-Tags auf {STATIC WEB ASSET BASE PATH}/{PACKAGE ID}.bundle.scp.css
, wobei die Platzhalter für Folgendes stehen:
{STATIC WEB ASSET BASE PATH}
: Basispfad der statischen Webressource{PACKAGE ID}
: Der Paketbezeichner der Bibliothek. Der Paketbezeichner ist standardmäßig der Assemblyname des Projekts, wenn der Paketbezeichner nicht in der Projektdatei angegeben ist.
Im folgenden Beispiel:
- Der Basispfad der statischen Webressource lautet
_content/ClassLib
. - Der Assemblyname der Klassenbibliothek lautet
ClassLib
.
Pages/Shared/_Layout.cshtml
(Razor Pages) oder Views/Shared/_Layout.cshtml
(MVC):
<link href="_content/ClassLib/ClassLib.bundle.scp.css" rel="stylesheet">
Weitere Informationen zu RCLs finden Sie in den folgenden Artikeln:
- Wiederverwendbare -Benutzeroberfläche in Klassenbibliotheken mit ASP.NET CoreRazor
- Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL)
Informationen zur CSS-Isolation in Blazor finden Sie unter CSS-Isolation in Blazor in ASP.NET Core.