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 Seiten finden Sie in der Einführung in Razor Seiten in ASP.NET Core.

Im Muster Model-View-Controller (MVC) verarbeitet die Ansicht die Darstellung der App-Daten und der Benutzerinteraktion. Eine Ansicht ist eine HTML-Vorlage mit eingebettetem Razor Markup. Razor Markup ist Code, der mit HTML-Markup interagiert, um eine Webseite zu erstellen, die an den Client gesendet wird.

In ASP.NET Core MVC sind .cshtml Ansichten Dateien, die die C#-Programmiersprache im Razor Markup verwenden. In der Regel werden Ansichtsdateien in Ordnern gruppiert, die für jeden Controller der App benannt werden. Die Ordner werden in einem Views Ordner im Stammverzeichnis der App gespeichert:

Views folder in Solution Explorer of Visual Studio is open with the Home folder open to show About.cshtml, Contact.cshtml, and Index.cshtml files

Der Home Controller wird durch einen Home Ordner innerhalb des Views Ordners dargestellt. Der Home Ordner enthält die Ansichten für die AboutContactWebseiten , und Index (Homepage). Wenn ein Benutzer eine dieser drei Webseiten anfordert, bestimmen Controlleraktionen im Home Controller, welche der drei Ansichten verwendet werden, um eine Webseite an den Benutzer 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 für einen Controller spezifisch sind, werden im Views/[ControllerName] Ordner erstellt. Ansichten, die für Controller freigegeben sind, werden im Views/Shared Ordner platziert. Um eine Ansicht zu erstellen, fügen Sie eine neue Datei hinzu, und geben Sie ihm denselben Namen wie die zugehörige Controlleraktion mit der .cshtml Dateierweiterung. Um eine Ansicht zu erstellen, die der About Aktion im Controller entspricht, erstellen Sie eine About.cshtml Datei im HomeViews/Home Ordner:

@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<p>Use this area to provide additional information.</p>

Razor Markup beginnt mit dem @ Symbol. Führen Sie C#-Anweisungen aus, indem Sie C#-Code innerhalb von Razor Codeblöcken platzieren, die durch geschweifte Geschweifte ({ ... }) festgelegt 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 aus Aktionen als ViewResultEine zurückgegeben, die ein Typ von 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 Controllererben, verwenden Sie einfach die View Hilfsmethode, um die ViewResult:

HomeController.cs:

public IActionResult About()
{
    ViewData["Message"] = "Your application description page.";

    return View();
}

Wenn diese Aktion zurückgegeben wird, wird die About.cshtml im letzten Abschnitt angezeigte Ansicht als folgende Webseite gerendert:

About page rendered in the Edge browser

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 Methodenname des Controllers wird beispielsweise verwendet, AboutActionResult um nach einer Ansichtsdatei namens zu About.cshtmlsuchen. Zuerst sucht die Laufzeit im Views/[ControllerName] Ordner nach der Ansicht. Wenn dort keine übereinstimmende Ansicht gefunden wird, durchsucht sie den Shared Ordner nach der Ansicht.

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:

  1. Views/\[ControllerName]/\[ViewName].cshtml
  2. Views/Shared/\[ViewName].cshtml

Anstelle eines Ansichtsnamens kann auch ein Pfad zu einer Ansichtsdatei verwendet werden. Wenn Sie einen absoluten Pfad verwenden, der am App-Stamm beginnt (optional mit "/" oder "~/"), muss die .cshtml Erweiterung angegeben werden:

return View("Views/Home/About.cshtml");

Sie können auch einen relativen Pfad verwenden, um Ansichten in verschiedenen Verzeichnissen ohne die .cshtml Erweiterung anzugeben. Innerhalb der HomeController, können Sie die Index Ansicht Ihrer Manage Ansichten mit einem relativen Pfad zurückgeben:

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 so anpassen, wie sich Ansichten in der App befinden, indem Sie eine benutzerdefinierte IViewLocationExpander.

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 Models Regel werden Ansichtsmodellklassen entweder im Ordner oder in einem separaten ViewModels Ordner im Stammverzeichnis der App gespeichert. Das Address im obigen Beispiel verwendete Ansichtsmodell ist ein POCO-Ansichtsmodell, das in einer Datei mit dem Namen " 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; }
    }
}

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 typierte Daten (ViewData, [ViewData] Attribut und ViewBag)

ViewBagist standardmäßig nicht verfügbar für die Verwendung in Razor PagesclassesPageModel.

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 Festlegen des <title> Elementinhalts in der Layoutansicht aus einer Ansichtsdatei.
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: Wichtige Nachschlagevorgänge sind sowohl als auch für ViewDataViewBag.

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 Objekt, auf das ViewDataDictionary ü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 weiterer Ansatz, der verwendet ViewDataDictionary wird, ist ViewDataAttribute. Eigenschaften für Controller oder Razor Seitenmodelle, die mit dem [ViewData] Attribut gekennzeichnet sind, haben ihre Werte gespeichert und aus dem Wörterbuch geladen.

Im folgenden Beispiel enthält der Home Controller eine Title Eigenschaft, die mit [ViewData]. 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

ViewBagist standardmäßig nicht verfügbar für die Verwendung in Razor PagesclassesPageModel.

ViewBagist ein Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData Objekt, das dynamischen Zugriff auf die in .ViewData 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>

Verwenden ViewData und ViewBag gleichzeitig

ViewBagist standardmäßig nicht verfügbar für die Verwendung in Razor PagesclassesPageModel.

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 den Titel mithilfe ViewBag und die Beschreibung ViewData oben in einer About.cshtml Ansicht 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 den Titel mithilfe der Beschreibung ab ViewData , und rufen Sie die Beschreibung mit ViewBag:

<!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

ViewBagist standardmäßig nicht verfügbar für die Verwendung in Razor PagesclassesPageModel.

  • ViewData
    • Abgeleitet von ViewDataDictionary, damit es Wörterbucheigenschaften hat, die nützlich sein können, z ContainsKey. B. , Add, Remove, und Clear.
    • 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, sodass ViewData verwendet werden kann.
  • ViewBag
    • Abgeleitet von Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData, sodass es die Erstellung dynamischer Eigenschaften mithilfe von Punktnotation (@ViewBag.SomeKey = <value or object>) ermöglicht, und es ist keine Umwandlung erforderlich. Über die Syntax von ViewBag können Controller und Ansichten schneller hinzugefügt werden.
    • Es ist einfacher, nach NULL-Werten zu suchen. Beispiel: @ViewBag.Person?.Name

Wann oder ViewDataViewBag

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. Delegate.SassBuilder, 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 die restlichen Ressourcen 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:

Informationen zur CSS-Isolation in Blazor finden Sie unter CSS-Isolation in Blazor in ASP.NET Core.