Webframeworkk/ASP.NET Core/View Components: Unterschied zwischen den Versionen

Aus Dokument
Zur Navigation springen Zur Suche springen
Die Seite wurde neu angelegt: „ == Einführung == In ASP.NET Core MVC ist eine '''Partial View''' (Teilansicht) ein wiederverwendbarer Block von Razor-Markup (.cshtml), der in andere Views eingebettet werden kann. Sie sind dafür konzipiert, spezifische UI-Elemente wie Listen, Formulare, Navigationsleisten oder Widgets zu kapseln. === Warum Partial Views verwenden? === * '''Wiederverwendbarkeit:''' Code einmal schreiben und in mehreren Views verwenden, was Duplikate und Inkonsistenzen…“
 
imported>Import
Version 188
Zeile 2: Zeile 2:
----
----


Dieses Tutorial erklärt, was View Components in ASP.NET Core sind, wann man sie verwendet und wie man sie effektiv implementiert. Es deckt Standard-View Components, stark typisierte Implementierungen, die Übergabe von Parametern und die Rückgabe aus Controllern ab.


== Einführung ==
== 1. Was sind View Components? ==
In ASP.NET Core MVC ist eine '''Partial View''' (Teilansicht) ein wiederverwendbarer Block von Razor-Markup (.cshtml), der in andere Views eingebettet werden kann. Sie sind dafür konzipiert, spezifische UI-Elemente wie Listen, Formulare, Navigationsleisten oder Widgets zu kapseln.


=== Warum Partial Views verwenden? ===
View Components (Ansichtskomponenten) sind eigenständige, wiederverwendbare UI-Bausteine in ASP.NET Core MVC. Sie sind dafür konzipiert, Rendering-Logik zu kapseln, die komplexer ist als das, was man typischerweise in eine Partial View (Teilansicht) packen würde, aber nicht die Komplexität eines vollwertigen Controllers rechtfertigt.
* '''Wiederverwendbarkeit:''' Code einmal schreiben und in mehreren Views verwenden, was Duplikate und Inkonsistenzen reduziert.
* '''Modularität:''' Komplexe Views in kleinere, überschaubare Komponenten aufteilen, wodurch der Code leichter zu lesen und zu warten ist.
* '''Dynamischer Inhalt:''' Daten an Partial Views übergeben, um sie an verschiedene Kontexte anzupassen.


----
=== Hauptmerkmale ===


== Grundlagen von Partial Views ==
* '''Komplexität kapseln''': Gruppieren Sie zusammenhängende UI-Rendering-Logik in einer zusammenhängenden Einheit.
* '''Wiederverwendbarkeit''': Verwenden Sie View Components in mehreren Ansichten, um Code-Duplizierung zu vermeiden.
* '''Testbarkeit''': Aufgrund ihrer eigenständigen Natur leichter per Unit Test zu testen.
* '''Rendering-Logik''': Ideal für dynamische Widgets, Navigationsmenüs, Login-Formulare, Warenkorb-Zusammenfassungen oder jedes UI-Element, das Datenabrufe oder Logik vor dem Rendern erfordert.


=== Namenskonvention ===
=== Wann man View Components verwendet ===
Partial Views werden typischerweise mit einem führenden Unterstrich benannt (z. B. _ListPartialView.cshtml). Dies hilft, sie von vollständigen Views zu unterscheiden.


=== Speicherort ===
* '''Komplexe UI-Elemente''': Wenn ein UI-Element komplexe Rendering-Logik erfordert.
Standardmäßig sucht ASP.NET Core nach Partial Views in:
* '''Datengetriebene Elemente''': Wenn Sie Daten abrufen oder Berechnungen durchführen müssen, bevor gerendert wird.
# Dem gleichen Ordner wie die View, die sie rendert.
* '''Wiederverwendbare Widgets''': Wenn Sie ein wiederverwendbares Widget für verschiedene Teile Ihrer Anwendung erstellen möchten.
# Dem Ordner Views/Shared.


Sie können bei Bedarf auch den vollständigen Pfad angeben.


----
-----


== Rendern von Partial Views ==
== 2. Implementierungsschritte ==
Sie können Partial Views in Ihren Haupt-Views mithilfe von Tag Helpers oder HTML Helpers rendern.


=== 1. Tag Helpers (Empfohlen) ===
Um eine View Component zu implementieren, folgen Sie im Allgemeinen diesen drei Schritten:
Der <partial> Tag Helper ist sauberer und leichter zu lesen.
<source lang="html">
<!-- Einfaches Rendern -->
<partial name="_ListPartialView" />


<!-- Mit einem Model -->
# Erstellen einer View Component Klasse: Leiten Sie von <code>ViewComponent</code> ab.
<partial name="_ListPartialView" model="yourModel" />
# Erstellen einer View: Erstellen Sie eine Razor-View-Datei (<code>.cshtml</code>).
# Aufruf in Ihrer View: Verwenden Sie die Helper-Methode oder den Tag Helper.


<!-- Mit ViewData -->
=== Schritt 1: Die View Component Klasse ===
<partial name="_ListPartialView" view-data="yourViewData" />
</source>


=== 2. HTML Helpers ===
Erstellen Sie eine Klasse, die von <code>ViewComponent</code> erbt. Sie sollte normalerweise in einem Ordner <code>ViewComponents</code> platziert werden. Die Klasse muss eine <code>Invoke</code> oder <code>InvokeAsync</code> Methode implementieren.
Die Methoden Html.PartialAsync oder Html.RenderPartialAsync können ebenfalls verwendet werden.
<source lang="csharp">
<!-- Gibt IHtmlContent zurück -->
@await Html.PartialAsync("_ListPartialView")
@await Html.PartialAsync("_ListPartialView", yourModel)


<!-- Rendert direkt in den Antwort-Stream (void Rückgabe) -->
'''Best Practice''': Benennen Sie die Klasse mit dem Suffix <code>ViewComponent</code> (z. B. <code>GridViewComponent</code>).
@{ await Html.RenderPartialAsync("_ListPartialView"); }
</source>
''Hinweis: RenderPartialAsync ist im Allgemeinen schneller, da es direkt in den Antwort-Stream schreibt.''


----
<syntaxhighlight lang="csharp">// GridViewComponent.cs
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using System.Collections.Generic;


== Datenübertragung: ViewBag vs. Streng Typisiert ==
public class GridViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync()
    {
        // Daten kommen normalerweise aus einer Datenbank oder einem Service
        PersonGridModel model = new PersonGridModel()
        {
            GridTitle = "Personenliste",
            Persons = new List<Person>() {
                new Person() { PersonName = "John", JobTitle = "Manager" },
                // ... mehr Daten
            }
        };
        // Gibt die View zurück (sucht nach Default.cshtml oder dem angegebenen View-Namen)
        return View("Sample", model);
    }
}</syntaxhighlight>
=== Schritt 2: Die View ===


=== Option 1: Verwendung von ViewBag (Nicht empfohlen für komplexe Daten) ===
Erstellen Sie eine Razor-View-Datei. Der Suchpfad für die View ist: <code>Views/Shared/Components/{ViewComponent Name}/{View Name}.cshtml</code>
Sie können ViewBag oder ViewData verwenden, um Daten zu übergeben, aber es fehlt die Typsicherheit.


'''Partial View (_ListPartialView.cshtml):'''
Für das obige Beispiel würde sich die Datei hier befinden: <code>Views/Shared/Components/Grid/Sample.cshtml</code>
<source lang="html">
 
<div class="list-container">
=== Schritt 3: Aufrufen der View Component ===
    <h3>@ViewBag.ListTitle</h3>
 
    <ul class="list">
Sie können die Komponente in jeder Razor-View (z. B. <code>Index.cshtml</code>) mit <code>Component.InvokeAsync</code> oder einem Tag Helper aufrufen.
    @foreach (string item in ViewBag.ListItems)
 
    {
<syntaxhighlight lang="html"><!-- Standard-Syntax (Bevorzugt) -->
        <li>@item</li>
@await Component.InvokeAsync("Grid")
    }
 
    </ul>
<!-- Tag Helper Syntax -->
</div>
<vc:grid></vc:grid></syntaxhighlight>
</source>
 
-----
 
== 3. Stark typisierte View Components ==


'''Haupt-View (Index.cshtml):'''
Genau wie Standard-Views sollten View Components stark typisierte Modelle für Typsicherheit, IntelliSense und Wartbarkeit verwenden.
<source lang="html">
@{
    // Daten über ein neues ViewDataDictionary übergeben, um das Haupt-ViewData nicht zu verunreinigen
    var myViewData = new ViewDataDictionary(ViewData);
    myViewData["ListTitle"] = "Länder";
    myViewData["ListItems"] = new List<string>() { "USA", "Deutschland", "Japan" };
}


<partial name="_ListPartialView" view-data="myViewData" />
=== Das View Model ===
</source>


=== Option 2: Streng typisierte Partial Views (Empfohlen) ===
Definieren Sie eine Klasse, um die Daten zu halten:
Die Verknüpfung einer Partial View mit einer Modellklasse bietet Typsicherheit zur Kompilierzeit und IntelliSense.


'''Das Modell (ListModel.cs):'''
<syntaxhighlight lang="csharp">public class PersonGridModel
<source lang="csharp">
namespace PartialViewsExample.Models
{
{
     public class ListModel
     public string GridTitle { get; set; }
    {
    public List<Person> Persons { get; set; }
        public string ListTitle { get; set; } = "";
}</syntaxhighlight>
        public List<string> ListItems { get; set; } = new List<string>();
=== Die Component View (<code>Sample.cshtml</code>) ===
     }
 
}
Verwenden Sie die <code>@model</code> Direktive, um die View an die Klasse zu binden.
</source>
 
<syntaxhighlight lang="html">@model PersonGridModel
 
<div class="box">
    <h3>@Model.GridTitle</h3>
    <table class="table w-100">
        <thead>
            <tr>
                <th>Lfd. Nr.</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            @foreach (Person person in Model.Persons)
            {
                <tr>
                    <td>@person.PersonName</td>
                    <td>@person.JobTitle</td>
                </tr>
            }
        </tbody>
     </table>
</div></syntaxhighlight>
 
-----
 
== 4. Parameter übergeben ==
 
Sie können Parameter an <code>InvokeAsync</code> übergeben, um die Ausgabe anzupassen.


'''Streng typisierte Partial View (_ListPartialView.cshtml):'''
'''View Component Klasse:''' Aktualisieren Sie <code>InvokeAsync</code>, um Argumente zu akzeptieren.
<source lang="html">
@model ListModel


<div class="list-container">
<syntaxhighlight lang="csharp">public class GridViewComponent : ViewComponent
    <h3>@Model.ListTitle</h3>
{
     <ul class="list">
     public async Task<IViewComponentResult> InvokeAsync(PersonGridModel grid)
    @foreach (string item in Model.ListItems)  
     {
     {
         <li>@item</li>
         return View("Sample", grid);
     }
     }
    </ul>
}</syntaxhighlight>
</div>
'''Aufruf mit Parametern:''' Übergeben Sie ein anonymes Objekt, bei dem die Eigenschaftsnamen mit den Parameternamen übereinstimmen.
</source>
 
'''Haupt-View (Index.cshtml):'''
<source lang="html">
@using PartialViewsExample.Models


@{
<syntaxhighlight lang="html">@{
     ListModel listModel = new ListModel();
     PersonGridModel myData = new PersonGridModel() { /* ... init ... */ };
    listModel.ListTitle = "Länder";
    listModel.ListItems = new List<string>() { "USA", "Kanada", "Japan" };
}
}
@await Component.InvokeAsync("Grid", new { grid = myData }) </syntaxhighlight>
'''Tag Helper Syntax:'''


<!-- Das Modell an die Partial View übergeben -->
<syntaxhighlight lang="html"><vc:grid grid="myData"></vc:grid> </syntaxhighlight>
<partial name="_ListPartialView" model="listModel" />  
</source>


----
-----


== Rückgabe von Partial Views aus Controllern (PartialViewResult) ==
== 5. Rückgabe aus Controllern (ViewComponentResult) ==


PartialViewResult wird verwendet, wenn Sie ''nur'' das HTML der Partial View zurückgeben möchten, oft für AJAX-Anfragen (z. B. Aktualisierung eines Teils der Seite ohne vollständiges Neuladen).
Sie können eine View Component direkt aus einer Controller-Action zurückgeben. Dies ist nützlich für API-ähnliche Endpunkte, die HTML-Fragmente zurückgeben (z. B. für AJAX-Updates).


=== Controller Action ===
<syntaxhighlight lang="csharp">[Route("friends-list")]
<source lang="csharp">
public IActionResult LoadFriendsList()
[Route("programming-languages")]
public IActionResult GetLanguages()
{
{
     ListModel listModel = new ListModel() {
     PersonGridModel personGridModel = new PersonGridModel()
         ListTitle = "Programmiersprachen",
    {
         ListItems = new List<string>() { "Python", "C#", "Go" }
         GridTitle = "Freunde",
         Persons = new List<Person>() { /* ... */ }
     };
     };
    // Gibt das View Component Result zurück
    return ViewComponent("Grid", new { grid = personGridModel });
}</syntaxhighlight>


    // Gibt nur das HTML der Partial View zurück
-----
    return PartialView("_ListPartialView", listModel);
}
</source>


=== Client-seitiges Beispiel (AJAX) ===
== 6. Best Practices ==
<source lang="html">
<button id="load-btn">Sprachen laden</button>
<div id="content-area"></div>


<script>
* '''Benennung''': Klassennamen sollten mit <code>ViewComponent</code> enden.
    document.querySelector("#load-btn").addEventListener("click", async function() {
* '''Speicherort''': Detaillierte Ordnerstruktur (<code>Views/Shared/Components/...</code>).
        // Das HTML der Partial View vom Controller abrufen
* '''Asynchron''': Verwenden Sie <code>InvokeAsync</code>, um blockierende Threads zu vermeiden.
        var response = await fetch("programming-languages");
* '''Einfachheit''': Halten Sie Geschäftslogik aus der Komponente heraus; delegieren Sie an Services.
        var html = await response.text();
* '''Typsicherheit''': Bevorzugen Sie immer stark typisierte Modelle gegenüber <code>ViewBag</code> oder <code>ViewData</code>.
       
        // Das HTML in das div einfügen
        document.querySelector("#content-area").innerHTML = html;
    });
</script>
</source>


----
== 7. Dinge, die man vermeiden sollte ==


== Wichtige Punkte ==
* '''Übermäßiger Gebrauch''': Verwenden Sie View Components nicht für einfache UI-Teile, die eine Partial View handhaben könnte.
# '''Kapselung:''' Verwenden Sie Partial Views, um Code zu organisieren und das DRY-Prinzip (Don't Repeat Yourself) einzuhalten.
* '''Starke Kopplung''': Koppeln Sie Komponenten nicht an spezifische Controller.
# '''Typsicherheit:''' Bevorzugen Sie '''streng typisierte''' Partial Views (@model) gegenüber ViewData/ViewBag für bessere Wartbarkeit und Fehlerprüfung.
* '''Direkter Datenbankzugriff''': Verwenden Sie stattdessen Dependency Injection und Services.
# '''Benennung:''' Stellen Sie Partial View-Dateinamen einen Unterstrich voran (z. B. _Header.cshtml).
# '''AJAX:''' Verwenden Sie PartialViewResult in Controllern, um HTML-Fragmente für dynamische Seitenaktualisierungen bereitzustellen.


----
----
''Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).''
''Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).''

Version vom 18. Februar 2026, 20:36 Uhr

Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).


Dieses Tutorial erklärt, was View Components in ASP.NET Core sind, wann man sie verwendet und wie man sie effektiv implementiert. Es deckt Standard-View Components, stark typisierte Implementierungen, die Übergabe von Parametern und die Rückgabe aus Controllern ab.

1. Was sind View Components?

View Components (Ansichtskomponenten) sind eigenständige, wiederverwendbare UI-Bausteine in ASP.NET Core MVC. Sie sind dafür konzipiert, Rendering-Logik zu kapseln, die komplexer ist als das, was man typischerweise in eine Partial View (Teilansicht) packen würde, aber nicht die Komplexität eines vollwertigen Controllers rechtfertigt.

Hauptmerkmale

  • Komplexität kapseln: Gruppieren Sie zusammenhängende UI-Rendering-Logik in einer zusammenhängenden Einheit.
  • Wiederverwendbarkeit: Verwenden Sie View Components in mehreren Ansichten, um Code-Duplizierung zu vermeiden.
  • Testbarkeit: Aufgrund ihrer eigenständigen Natur leichter per Unit Test zu testen.
  • Rendering-Logik: Ideal für dynamische Widgets, Navigationsmenüs, Login-Formulare, Warenkorb-Zusammenfassungen oder jedes UI-Element, das Datenabrufe oder Logik vor dem Rendern erfordert.

Wann man View Components verwendet

  • Komplexe UI-Elemente: Wenn ein UI-Element komplexe Rendering-Logik erfordert.
  • Datengetriebene Elemente: Wenn Sie Daten abrufen oder Berechnungen durchführen müssen, bevor gerendert wird.
  • Wiederverwendbare Widgets: Wenn Sie ein wiederverwendbares Widget für verschiedene Teile Ihrer Anwendung erstellen möchten.



2. Implementierungsschritte

Um eine View Component zu implementieren, folgen Sie im Allgemeinen diesen drei Schritten:

  1. Erstellen einer View Component Klasse: Leiten Sie von ViewComponent ab.
  2. Erstellen einer View: Erstellen Sie eine Razor-View-Datei (.cshtml).
  3. Aufruf in Ihrer View: Verwenden Sie die Helper-Methode oder den Tag Helper.

Schritt 1: Die View Component Klasse

Erstellen Sie eine Klasse, die von ViewComponent erbt. Sie sollte normalerweise in einem Ordner ViewComponents platziert werden. Die Klasse muss eine Invoke oder InvokeAsync Methode implementieren.

Best Practice: Benennen Sie die Klasse mit dem Suffix ViewComponent (z. B. GridViewComponent).

// GridViewComponent.cs
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using System.Collections.Generic;

public class GridViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync() 
    {
        // Daten kommen normalerweise aus einer Datenbank oder einem Service
        PersonGridModel model = new PersonGridModel()
        {
            GridTitle = "Personenliste",
            Persons = new List<Person>() {
                new Person() { PersonName = "John", JobTitle = "Manager" },
                // ... mehr Daten
            }
        };
        // Gibt die View zurück (sucht nach Default.cshtml oder dem angegebenen View-Namen)
        return View("Sample", model); 
    }
}

Schritt 2: Die View

Erstellen Sie eine Razor-View-Datei. Der Suchpfad für die View ist: Views/Shared/Components/{ViewComponent Name}/{View Name}.cshtml

Für das obige Beispiel würde sich die Datei hier befinden: Views/Shared/Components/Grid/Sample.cshtml

Schritt 3: Aufrufen der View Component

Sie können die Komponente in jeder Razor-View (z. B. Index.cshtml) mit Component.InvokeAsync oder einem Tag Helper aufrufen.

<!-- Standard-Syntax (Bevorzugt) -->
@await Component.InvokeAsync("Grid")

<!-- Tag Helper Syntax -->
<vc:grid></vc:grid>

3. Stark typisierte View Components

Genau wie Standard-Views sollten View Components stark typisierte Modelle für Typsicherheit, IntelliSense und Wartbarkeit verwenden.

Das View Model

Definieren Sie eine Klasse, um die Daten zu halten:

public class PersonGridModel
{
    public string GridTitle { get; set; }
    public List<Person> Persons { get; set; }
}

Die Component View (Sample.cshtml)

Verwenden Sie die @model Direktive, um die View an die Klasse zu binden.

@model PersonGridModel 

<div class="box">
    <h3>@Model.GridTitle</h3> 
    <table class="table w-100">
        <thead>
            <tr>
                <th>Lfd. Nr.</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            @foreach (Person person in Model.Persons)
            {
                <tr>
                    <td>@person.PersonName</td>
                    <td>@person.JobTitle</td>
                </tr>
            }
        </tbody>
    </table>
</div>

4. Parameter übergeben

Sie können Parameter an InvokeAsync übergeben, um die Ausgabe anzupassen.

View Component Klasse: Aktualisieren Sie InvokeAsync, um Argumente zu akzeptieren.

public class GridViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(PersonGridModel grid)  
    {
        return View("Sample", grid);
    }
}

Aufruf mit Parametern: Übergeben Sie ein anonymes Objekt, bei dem die Eigenschaftsnamen mit den Parameternamen übereinstimmen.

@{
    PersonGridModel myData = new PersonGridModel() { /* ... init ... */ };
}
 
@await Component.InvokeAsync("Grid", new { grid = myData })

Tag Helper Syntax:

<vc:grid grid="myData"></vc:grid>

5. Rückgabe aus Controllern (ViewComponentResult)

Sie können eine View Component direkt aus einer Controller-Action zurückgeben. Dies ist nützlich für API-ähnliche Endpunkte, die HTML-Fragmente zurückgeben (z. B. für AJAX-Updates).

[Route("friends-list")]
public IActionResult LoadFriendsList()
{
    PersonGridModel personGridModel = new PersonGridModel()
    {
        GridTitle = "Freunde",
        Persons = new List<Person>() { /* ... */ }
    };
 
    // Gibt das View Component Result zurück
    return ViewComponent("Grid", new { grid = personGridModel });
}

6. Best Practices

  • Benennung: Klassennamen sollten mit ViewComponent enden.
  • Speicherort: Detaillierte Ordnerstruktur (Views/Shared/Components/...).
  • Asynchron: Verwenden Sie InvokeAsync, um blockierende Threads zu vermeiden.
  • Einfachheit: Halten Sie Geschäftslogik aus der Komponente heraus; delegieren Sie an Services.
  • Typsicherheit: Bevorzugen Sie immer stark typisierte Modelle gegenüber ViewBag oder ViewData.

7. Dinge, die man vermeiden sollte

  • Übermäßiger Gebrauch: Verwenden Sie View Components nicht für einfache UI-Teile, die eine Partial View handhaben könnte.
  • Starke Kopplung: Koppeln Sie Komponenten nicht an spezifische Controller.
  • Direkter Datenbankzugriff: Verwenden Sie stattdessen Dependency Injection und Services.

Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).