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…“
 
Keine Bearbeitungszusammenfassung
 
(Eine dazwischenliegende Version von einem anderen Benutzer wird nicht angezeigt)
Zeile 3: Zeile 3:




== 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? ===
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.
* '''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.
== 1. Was sind View Components? ==
* '''Dynamischer Inhalt:''' Daten an Partial Views übergeben, um sie an verschiedene Kontexte anzupassen.
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.


----
----


== Grundlagen von Partial Views ==
== 2. Implementierungsschritte ==
Um eine View Component zu implementieren, folgen Sie im Allgemeinen diesen drei Schritten:
# Erstellen einer View Component Klasse: Leiten Sie von <code>ViewComponent</code> ab.
# 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.
 
=== Schritt 1: Die View Component Klasse ===
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.


=== Namenskonvention ===
'''Best Practice''': Benennen Sie die Klasse mit dem Suffix <code>ViewComponent</code> (z. B. <code>GridViewComponent</code>).
Partial Views werden typischerweise mit einem führenden Unterstrich benannt (z. B. _ListPartialView.cshtml). Dies hilft, sie von vollständigen Views zu unterscheiden.


=== Speicherort ===
<syntaxhighlight lang="csharp">
Standardmäßig sucht ASP.NET Core nach Partial Views in:
// GridViewComponent.cs
# Dem gleichen Ordner wie die View, die sie rendert.
using Microsoft.AspNetCore.Mvc;
# Dem Ordner Views/Shared.
using System.Threading.Tasks;
using System.Collections.Generic;


Sie können bei Bedarf auch den vollständigen Pfad angeben.
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 ===
Erstellen Sie eine Razor-View-Datei. Der Suchpfad für die View ist:
<code>Views/Shared/Components/{ViewComponent Name}/{View Name}.cshtml</code>
 
Für das obige Beispiel würde sich die Datei hier befinden:
<code>Views/Shared/Components/Grid/Sample.cshtml</code>


== Rendern von Partial Views ==
=== Schritt 3: Aufrufen der View Component ===
Sie können Partial Views in Ihren Haupt-Views mithilfe von Tag Helpers oder HTML Helpers rendern.
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.


=== 1. Tag Helpers (Empfohlen) ===
<syntaxhighlight lang="html">
Der <partial> Tag Helper ist sauberer und leichter zu lesen.
<!-- Standard-Syntax (Bevorzugt) -->
<source lang="html">
@await Component.InvokeAsync("Grid")
<!-- Einfaches Rendern -->
<partial name="_ListPartialView" />


<!-- Mit einem Model -->
<!-- Tag Helper Syntax -->
<partial name="_ListPartialView" model="yourModel" />
<vc:grid></vc:grid>
</syntaxhighlight>


<!-- Mit ViewData -->
----
<partial name="_ListPartialView" view-data="yourViewData" />
</source>


=== 2. HTML Helpers ===
== 3. Stark typisierte View Components ==
Die Methoden Html.PartialAsync oder Html.RenderPartialAsync können ebenfalls verwendet werden.
Genau wie Standard-Views sollten View Components stark typisierte Modelle für Typsicherheit, IntelliSense und Wartbarkeit verwenden.
<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) -->
=== Das View Model ===
@{ await Html.RenderPartialAsync("_ListPartialView"); }
Definieren Sie eine Klasse, um die Daten zu halten:
</source>
''Hinweis: RenderPartialAsync ist im Allgemeinen schneller, da es direkt in den Antwort-Stream schreibt.''


----
<syntaxhighlight lang="csharp">
public class PersonGridModel
{
    public string GridTitle { get; set; }
    public List<Person> Persons { get; set; }
}
</syntaxhighlight>


== Datenübertragung: ViewBag vs. Streng Typisiert ==
=== Die Component View (<code>Sample.cshtml</code>) ===
Verwenden Sie die <code>@model</code> Direktive, um die View an die Klasse zu binden.


=== Option 1: Verwendung von ViewBag (Nicht empfohlen für komplexe Daten) ===
<syntaxhighlight lang="html">
Sie können ViewBag oder ViewData verwenden, um Daten zu übergeben, aber es fehlt die Typsicherheit.
@model PersonGridModel


'''Partial View (_ListPartialView.cshtml):'''
<div class="box">
<source lang="html">
     <h3>@Model.GridTitle</h3>  
<div class="list-container">
     <table class="table w-100">
     <h3>@ViewBag.ListTitle</h3>
        <thead>
     <ul class="list">
            <tr>
    @foreach (string item in ViewBag.ListItems)
                <th>Lfd. Nr.</th>
    {
                <th>Name</th>
        <li>@item</li>
            </tr>
    }
        </thead>
     </ul>
        <tbody>
            @foreach (Person person in Model.Persons)
            {
                <tr>
                    <td>@person.PersonName</td>
                    <td>@person.JobTitle</td>
                </tr>
            }
        </tbody>
     </table>
</div>
</div>
</source>
</syntaxhighlight>


'''Haupt-View (Index.cshtml):'''
----
<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" />
== 4. Parameter übergeben ==
</source>
Sie können Parameter an <code>InvokeAsync</code> übergeben, um die Ausgabe anzupassen.


=== Option 2: Streng typisierte Partial Views (Empfohlen) ===
'''View Component Klasse:'''
Die Verknüpfung einer Partial View mit einer Modellklasse bietet Typsicherheit zur Kompilierzeit und IntelliSense.
Aktualisieren Sie <code>InvokeAsync</code>, um Argumente zu akzeptieren.


'''Das Modell (ListModel.cs):'''
<syntaxhighlight lang="csharp">
<source lang="csharp">
public class GridViewComponent : ViewComponent
namespace PartialViewsExample.Models
{
{
     public class ListModel
     public async Task<IViewComponentResult> InvokeAsync(PersonGridModel grid) 
     {
     {
         public string ListTitle { get; set; } = "";
         return View("Sample", grid);
        public List<string> ListItems { get; set; } = new List<string>();
     }
     }
}
}
</source>
</syntaxhighlight>
 
'''Streng typisierte Partial View (_ListPartialView.cshtml):'''
<source lang="html">
@model ListModel


<div class="list-container">
'''Aufruf mit Parametern:'''
    <h3>@Model.ListTitle</h3>
Übergeben Sie ein anonymes Objekt, bei dem die Eigenschaftsnamen mit den Parameternamen übereinstimmen.
    <ul class="list">
    @foreach (string item in Model.ListItems)
    {
        <li>@item</li>
    }
    </ul>
</div>
</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>


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


----
----


== Rückgabe von Partial Views aus Controllern (PartialViewResult) ==
== 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).
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).


=== Controller Action ===
<syntaxhighlight lang="csharp">
<source lang="csharp">
[Route("friends-list")]
[Route("programming-languages")]
public IActionResult LoadFriendsList()
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 nur das HTML der Partial View zurück
     // Gibt das View Component Result zurück
     return PartialView("_ListPartialView", listModel);
     return ViewComponent("Grid", new { grid = personGridModel });
}
}
</source>
</syntaxhighlight>


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


<script>
== 6. Best Practices ==
    document.querySelector("#load-btn").addEventListener("click", async function() {
* '''Benennung''': Klassennamen sollten mit <code>ViewComponent</code> enden.
        // Das HTML der Partial View vom Controller abrufen
* '''Speicherort''': Detaillierte Ordnerstruktur (<code>Views/Shared/Components/...</code>).
        var response = await fetch("programming-languages");
* '''Asynchron''': Verwenden Sie <code>InvokeAsync</code>, um blockierende Threads zu vermeiden.
        var html = await response.text();
* '''Einfachheit''': Halten Sie Geschäftslogik aus der Komponente heraus; delegieren Sie an Services.
       
* '''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>
 
----


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

Aktuelle 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).