Freigeben über


Bereiche in ASP.NET Core

Von Dhananjay Kumar und Rick Anderson

Bereiche sind ein Feature von ASP.NET, das verwendet wird, um verwandte Funktionen wie folgt in einer Gruppe zusammenzufassen:

  • Namespace für das Routing
  • Ordnerstruktur für Ansichten und Razor Pages

Mithilfe von Bereichen wird außerdem eine Hierarchie zu Routingzwecken erstellt, indem ein weiterer Routenparameter (area) zu controller und action oder zu einer Razor Page (page) hinzugefügt wird.

Bereiche ermöglichen es, eine ASP.NET Core-Web-App in kleinere funktionale Gruppen zu partitionieren. Jede dieser Gruppen hat dabei ihren eigenen Satz von Razor Pages, Controllern, Ansichten und Modellen. Ein Bereich ist im Grunde genommen eine Struktur in einer App. In einem ASP.NET Core-Webprojekt werden logische Komponenten wie Seiten, Modelle, Controller und Ansichten in verschiedenen Ordner aufbewahrt. Die ASP.NET Core-Runtime verwendet Namenskonventionen, um die Beziehung zwischen diesen Komponenten zu erstellen. Bei einer großen App kann es von Vorteil sein, die App in mehrere Bereiche auf hoher Funktionalitätsebene zu unterteilen, Dies gilt z.B. für eine E-Commerce-App mit mehreren Geschäftseinheiten, wie Auftragsabschluss, Abrechnung und Suche. Jede dieser Einheiten hat ihren eigenen Bereich für Ansichten, Controller, Razor Pages und Modelle.

Die Verwendung von Bereichen in einem Projekt ist erwägenswert, wenn:

  • Ihre App aus mehreren funktionalen Komponenten auf hoher Ebene besteht, die logisch getrennt sein können.
  • Sie Ihre App partitionieren möchten, damit jeder funktionale Bereich unabhängig voneinander bearbeitet werden kann.

Wenn Sie Razor Pages verwenden, lesen Sie Bereiche mit Razor Pages in diesem Dokument.

Bereiche für Controller mit Ansichten

Eine typische ASP.NET Core-Web-App, die Bereiche, Controller und Ansichten verwendet, beinhaltet Folgendes:

  • Eine Bereichsordnerstruktur.

  • Controller werden mit dem Attribut [Area] versehen, um den Controller mit dem Bereich zu verknüpfen:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • Die Bereichsroute, die hinzugefügt wurdeProgram.cs:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllersWithViews();
    
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapControllerRoute(
        name: "MyArea",
        pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    
    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    
    app.Run();
    

Bereichsordnerstruktur

Stellen Sie sich eine App vor, die zwei logische Gruppen hat, Produkte und Dienste. Wenn Bereiche verwendet werden, würde die Ordnerstruktur ähnlich dem Folgenden aussehen:

  • Projektname
    • Bereiche
      • Products
        • Controller
          • HomeController.cs
          • ManageController.cs
        • Ansichten
          • Home
            • Index.cshtml
          • Verwalten
            • Index.cshtml
            • About.cshtml
      • Dienste
        • Controller
          • HomeController.cs
        • Ansichten
          • Home
            • Index.cshtml

Während das vorherige Layout typisch ist, wenn Bereiche verwendet werden, müssen nur die Ansichtsdateien diese Ordnerstruktur verwenden. Die Ansichtsermittlung sucht nach einer passenden Bereichsansichtsdatei im folgenden Ordner:

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

Zuordnen eines Controllers zu einem Bereich

Bereichscontroller werden mit dem Attribut [Area] versehen:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Docs.Samples;

namespace MVCareas.Areas.Products.Controllers;

[Area("Products")]
public class ManageController : Controller
{
    public IActionResult Index()
    {
        ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
        return View();
    }

    public IActionResult About()
    {
        ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
        return View();
    }
}

Hinzufügen einer Bereichsroute

Bereichsrouten verwenden normalerweise konventionelles Routing anstatt Attributrouting. Beim herkömmlichen Routing ist die Reihenfolge wichtig. Routen mit Bereichen werden im Allgemeinen früher in der Routentabelle aufgeführt als die spezifischeren Routen ohne Bereich.

{area:...} kann als Token in Routenvorlagen verwendet werden, wenn der URL-Raum in allen Bereichen einheitlich ist:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "MyArea",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Im vorherigen Code wendet exists eine Einschränkung an: Die Route muss mit einem Bereich übereinstimmen. Die Verwendung von {area:...} mit MapControllerRoute:

  • ist die unkomplizierteste Methode, um Bereichen Routing hinzuzufügen.
  • Gleicht alle Controller mit dem Attribut [Area("Area name")] ab.

Im folgenden Code wird MapAreaControllerRoute verwendet, um zwei benannte Bereichsrouten zu erstellen:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapAreaControllerRoute(
    name: "MyAreaProducts",
    areaName: "Products",
    pattern: "Products/{controller=Home}/{action=Index}/{id?}");

app.MapAreaControllerRoute(
    name: "MyAreaServices",
    areaName: "Services",
    pattern: "Services/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Weitere Informationen finden Sie im Artikel Routing zu Controlleraktionen in ASP.NET Core.

Im folgenden Code aus dem Beispieldownload sehen Sie die Erstellung eines Links mit dem angegebenen Bereich:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage",
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

Der Beispieldownload enthält eine Teilansicht mit Folgendem:

  • Die obigen Links
  • Ähnliche Links wie die obigen, aber ohne Angabe von area

In der Layoutdatei wird auf die partielle Ansicht verwiesen. Jede Seite in der App stellt also die erstellen Links dar. Die Links, die ohne Angabe eines Bereichs erstellt werden, sind nur gültig, wenn auf sie von einer Seite im selben Bereich und Controller verwiesen wird.

Wenn der Bereich oder der Kontroller nicht angegeben werden, hängt das Routing von den Umgebungswerten ab. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt. Oftmals hat die Verwendung der Umgebungswerte für die Beispiel-App die Generierung ungültiger Links mit Markup ohne Bereichsangabe zur Folge.

Weitere Informationen finden Sie unter Routing zu Controlleraktionen in ASP.NET Core.

Freigegebenes Layout für Bereiche unter Verwendung der _ViewStart.cshtml-Datei

Um ein allgemeines Layout für die gesamte App freizugeben, lassen Sie _ViewStart.cshtml im Stammordner der Anwendung. Weitere Informationen finden Sie unter Layout in ASP.NET Core.

Stammordner der Anwendung

Der Stammordner der Anwendung ist der Ordner, der die Datei Program.cs in einer Web-App enthält, die mit den ASP.NET Core-Vorlagen erstellt wurde.

_ViewImports.cshtml

/Views/_ViewImports.cshtml (für MVC) und /Pages/_ViewImports.cshtml (für Razor Pages) werden nicht in Ansichten in Bereichen importiert. Verwenden Sie einen der folgenden Ansätze, um Ansichtsimporte für alle Ansichten bereitzustellen:

  • Fügen Sie _ViewImports.cshtml dem Stammordner der Anwendung hinzu. Eine Datei vom Typ _ViewImports.cshtml im Stammordner der Anwendung gilt für alle Ansichten in der App.
  • Kopieren Sie die Datei _ViewImports.cshtml in den entsprechenden Ansichtsordner unter Bereichen. Beispielsweise hat eine Razor Pages-App, die mit einzelnen Benutzerkonten erstellt wurde, eine Datei vom Typ _ViewImports.cshtml in den folgenden Ordnern:
    • /Areas/Identity/Pages/_ViewImports.cshtml
    • /Pages/_ViewImports.cshtml

Die Datei _ViewImports.cshtml enthält in der Regel Importe vom Typ Taghilfsprogramme, @using und @inject-Anweisungen. Weitere Informationen finden Sie unter Importieren gemeinsam verwendeter Anweisungen.

Ändern des Standardbereichsordners, in dem Ansichten gespeichert sind

Der folgende Code ändert den Standardbereichsordner von "Areas" in "MyAreas":

using Microsoft.AspNetCore.Mvc.Razor;

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<RazorViewEngineOptions>(options =>
{
    options.AreaViewLocationFormats.Clear();
    options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
    options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
    options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
});

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "MyArea",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Bereiche mit Razor Pages

Für Bereiche mit Razor Pages muss ein Ordner namens Areas/<area name>/Pages im Stammverzeichnis der App vorhanden sein. Die folgende Ordnerstruktur wird mit dem Beispiel-App verwendet.

  • Projektname
    • Bereiche
      • Products
        • Seiten
          • _ViewImports
          • Info
          • Index
      • Dienste
        • Seiten
          • Verwalten
            • Info
            • Index

Im folgenden Code aus dem Beispieldownload sehen Sie die Erstellung eines Links mit dem angegebenen Bereich (z.B. asp-area="Products"):

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

Im Beispieldownload ist eine partielle Ansicht enthalten, die die vorherigen Links und dieselben Links beinhaltet, ohne dass der Bereich angegeben wird. In der Layoutdatei wird auf die partielle Ansicht verwiesen. Jede Seite in der App stellt also die erstellen Links dar. Die Links, die ohne Angabe eines Bereichs erstellt werden, sind nur gültig, wenn auf sie von einer Seite im selben Bereich verwiesen wird.

Wenn der Bereich nicht angegeben wird, hängt das Routing von den Umgebungswerten ab. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt. Oft werden ungültige Links erstellt, wenn für die Beispiel-App die Umgebungswerte verwendet werden. Betrachten Sie hierzu die aus dem folgenden Code generierten Links:

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

Für den Code oben gilt:

  • Der aus <a asp-page="/Manage/About"> generierte Link stimmt nur, wenn die letzte Anforderung für eine Seite im Services-Bereich erfolgte. Beispiel: /Services/Manage/, /Services/Manage/Index oder /Services/Manage/About.
  • Der aus <a asp-page="/About"> generierte Link stimmt nur, wenn die letzte Anforderung für eine Seite in /Home erfolgte.
  • Der Code stammt aus dem Beispieldownload.

Importieren von Namespace und Taghilfsprogrammen mit der _ViewImports-Datei

Eine Datei vom Typ _ViewImports.cshtml kann dem Ordner Pages jedes Bereichs hinzugefügt werden, um den Namespace und die Taghilfsprogramme für jede Razor-Seite im Ordner zu importieren.

Betrachten Sie den Bereich Services des Beispielcodes, der keine _ViewImports.cshtml-Datei enthält. Das folgende Markup zeigt die Razor-Seite /Services/Manage/About:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<div>
  ViewData["routeInfo"]:  @ViewData["routeInfo"]
</div>

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

Im obenstehenden Markup:

  • Der vollqualifizierte Klassenname muss verwendet werden, um das Modell (@model RPareas.Areas.Services.Pages.Manage.AboutModel) anzugeben.
  • Taghilfsprogramme werden durch @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers aktiviert.

Im Beispieldownload enthält der Bereich „Products“ die folgende _ViewImports.cshtml-Datei:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Das folgende Markup zeigt die Razor-Seite /Products/About:

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

In der vorherigen Datei werden Namespace und @addTagHelper-Anweisung von der Datei Areas/Products/Pages/_ViewImports.cshtml in die Datei importiert.

Weitere Informationen finden Sie unter Verwalten des Taghilfsprogrammbereichs und Importieren gemeinsam verwendeter Anweisungen.

Gemeinsam genutztes Layout für Razor Pages-Bereiche

Um ein gemeinsames Layout für die gesamte App freizugeben, verschieben Sie _ViewStart.cshtml in den Stammordner der Anwendung.

Veröffentlichen von Bereichen

Alle *.cshtml-Dateien und Dateien im wwwroot-Verzeichnis werden in der Ausgabe veröffentlicht, wenn <Project Sdk="Microsoft.NET.Sdk.Web"> in der *.csproj-Datei enthalten ist.

Hinzufügen eines MVC-Bereichs mit Visual Studio

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Hinzufügen > Neues Gerüstelement und anschließend MVC-Bereich aus.

Zusätzliche Ressourcen

Bereiche sind ein Feature von ASP.NET, das verwendet wird, um verwandte Funktionen wie folgt in einer Gruppe zusammenzufassen:

  • Namespace für das Routing
  • Ordnerstruktur für Ansichten und Razor Pages

Mithilfe von Bereichen wird außerdem eine Hierarchie zu Routingzwecken erstellt, indem ein weiterer Routenparameter (area) zu controller und action oder zu einer Razor Page (page) hinzugefügt wird.

Bereiche ermöglichen es, eine ASP.NET Core-Web-App in kleinere funktionale Gruppen zu partitionieren. Jede dieser Gruppen hat dabei ihren eigenen Satz von Razor Pages, Controllern, Ansichten und Modellen. Ein Bereich ist im Grunde genommen eine Struktur in einer App. In einem ASP.NET Core-Webprojekt werden logische Komponenten wie Seiten, Modelle, Controller und Ansichten in verschiedenen Ordner aufbewahrt. Die ASP.NET Core-Runtime verwendet Namenskonventionen, um die Beziehung zwischen diesen Komponenten zu erstellen. Bei einer großen App kann es von Vorteil sein, die App in mehrere Bereiche auf hoher Funktionalitätsebene zu unterteilen, Dies gilt z.B. für eine E-Commerce-App mit mehreren Geschäftseinheiten, wie Auftragsabschluss, Abrechnung und Suche. Jede dieser Einheiten hat ihren eigenen Bereich für Ansichten, Controller, Razor Pages und Modelle.

Die Verwendung von Bereichen in einem Projekt ist erwägenswert, wenn:

  • Ihre App aus mehreren funktionalen Komponenten auf hoher Ebene besteht, die logisch getrennt sein können.
  • Sie Ihre App partitionieren möchten, damit jeder funktionale Bereich unabhängig voneinander bearbeitet werden kann.

Zeigen Sie Beispielcode an, oder laden Sie diesen herunter (Vorgehensweise zum Herunterladen). Das Downloadbeispiel stellt eine einfache App für Testbereiche zur Verfügung.

Wenn Sie Razor Pages verwenden, lesen Sie Bereiche mit Razor Pages in diesem Dokument.

Bereiche für Controller mit Ansichten

Eine typische ASP.NET Core-Web-App, die Bereiche, Controller und Ansichten verwendet, beinhaltet Folgendes:

  • Eine Bereichsordnerstruktur.

  • Controller werden mit dem Attribut [Area] versehen, um den Controller mit dem Bereich zu verknüpfen:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • Die Bereichsroute, die dem Startup hinzugefügt wurde:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "MyArea",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
    

Bereichsordnerstruktur

Stellen Sie sich eine App vor, die zwei logische Gruppen hat, Produkte und Dienste. Wenn Bereiche verwendet werden, würde die Ordnerstruktur ähnlich dem Folgenden aussehen:

  • Projektname
    • Bereiche
      • Products
        • Controller
          • HomeController.cs
          • ManageController.cs
        • Ansichten
          • Home
            • Index.cshtml
          • Verwalten
            • Index.cshtml
            • About.cshtml
      • Dienste
        • Controller
          • HomeController.cs
        • Ansichten
          • Home
            • Index.cshtml

Während das vorherige Layout typisch ist, wenn Bereiche verwendet werden, müssen nur die Ansichtsdateien diese Ordnerstruktur verwenden. Die Ansichtsermittlung sucht nach einer passenden Bereichsansichtsdatei im folgenden Ordner:

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

Zuordnen eines Controllers zu einem Bereich

Bereichscontroller werden mit dem Attribut [Area] versehen:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Docs.Samples;

namespace MVCareas.Areas.Products.Controllers
{
    [Area("Products")]
    public class ManageController : Controller
    {
        public IActionResult Index()
        {
            ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
            return View();
        }

        public IActionResult About()
        {
            ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
            return View();
        }
    }
}

Hinzufügen einer Bereichsroute

Bereichsrouten verwenden normalerweise konventionelles Routing anstatt Attributrouting. Beim herkömmlichen Routing ist die Reihenfolge wichtig. Routen mit Bereichen werden im Allgemeinen früher in der Routentabelle aufgeführt als die spezifischeren Routen ohne Bereich.

{area:...} kann als Token in Routenvorlagen verwendet werden, wenn der URL-Raum in allen Bereichen einheitlich ist:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "MyArea",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Im vorherigen Code wendet exists eine Einschränkung an: Die Route muss mit einem Bereich übereinstimmen. Die Verwendung von {area:...} mit MapControllerRoute:

  • ist die unkomplizierteste Methode, um Bereichen Routing hinzuzufügen.
  • Gleicht alle Controller mit dem Attribut [Area("Area name")] ab.

Im folgenden Code wird MapAreaControllerRoute verwendet, um zwei benannte Bereichsrouten zu erstellen:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapAreaControllerRoute(
            name: "MyAreaProducts",
            areaName: "Products",
            pattern: "Products/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapAreaControllerRoute(
            name: "MyAreaServices",
            areaName: "Services",
            pattern: "Services/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Weitere Informationen finden Sie im Artikel Routing zu Controlleraktionen in ASP.NET Core.

Im folgenden Code aus dem Beispieldownload sehen Sie die Erstellung eines Links mit dem angegebenen Bereich:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage",
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

Der Beispieldownload enthält eine Teilansicht mit Folgendem:

  • Die obigen Links
  • Ähnliche Links wie die obigen, aber ohne Angabe von area

In der Layoutdatei wird auf die partielle Ansicht verwiesen. Jede Seite in der App stellt also die erstellen Links dar. Die Links, die ohne Angabe eines Bereichs erstellt werden, sind nur gültig, wenn auf sie von einer Seite im selben Bereich und Controller verwiesen wird.

Wenn der Bereich oder der Kontroller nicht angegeben werden, hängt das Routing von den Umgebungswerten ab. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt. Oftmals hat die Verwendung der Umgebungswerte für die Beispiel-App die Generierung ungültiger Links mit Markup ohne Bereichsangabe zur Folge.

Weitere Informationen finden Sie unter Routing zu Controlleraktionen in ASP.NET Core.

Freigegebenes Layout für Bereiche unter Verwendung der _ViewStart.cshtml-Datei

Um ein allgemeines Layout für die gesamte App freizugeben, lassen Sie _ViewStart.cshtml im Stammordner der Anwendung. Weitere Informationen finden Sie unter Layout in ASP.NET Core.

Stammordner der Anwendung

Der Stammordner der Anwendung ist der Ordner, der Startup.cs in der Web-App enthält, die mit den ASP.NET Core-Vorlagen erstellt wurde.

_ViewImports.cshtml

/Views/_ViewImports.cshtml (für MVC) und /Pages/_ViewImports.cshtml (für Razor Pages) werden nicht in Ansichten in Bereichen importiert. Verwenden Sie einen der folgenden Ansätze, um Ansichtsimporte für alle Ansichten bereitzustellen:

  • Fügen Sie _ViewImports.cshtml dem Stammordner der Anwendung hinzu. Eine Datei vom Typ _ViewImports.cshtml im Stammordner der Anwendung gilt für alle Ansichten in der App.
  • Kopieren Sie die Datei _ViewImports.cshtml in den entsprechenden Ansichtsordner unter Bereichen.

Die Datei _ViewImports.cshtml enthält in der Regel Importe vom Typ Taghilfsprogramme, @using und @inject-Anweisungen. Weitere Informationen finden Sie unter Importieren gemeinsam verwendeter Anweisungen.

Ändern des Standardbereichsordners, in dem Ansichten gespeichert sind

Der folgende Code ändert den Standardbereichsordner von "Areas" in "MyAreas":

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.AreaViewLocationFormats.Clear();
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
    });

    services.AddControllersWithViews();
}

Bereiche mit Razor Pages

Für Bereiche mit Razor Pages muss ein Ordner namens Areas/<area name>/Pages im Stammverzeichnis der App vorhanden sein. Die folgende Ordnerstruktur wird mit dem Beispiel-App verwendet.

  • Projektname
    • Bereiche
      • Products
        • Seiten
          • _ViewImports
          • Info
          • Index
      • Dienste
        • Seiten
          • Verwalten
            • Info
            • Index

Im folgenden Code aus dem Beispieldownload sehen Sie die Erstellung eines Links mit dem angegebenen Bereich (z.B. asp-area="Products"):

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

Im Beispieldownload ist eine partielle Ansicht enthalten, die die vorherigen Links und dieselben Links beinhaltet, ohne dass der Bereich angegeben wird. In der Layoutdatei wird auf die partielle Ansicht verwiesen. Jede Seite in der App stellt also die erstellen Links dar. Die Links, die ohne Angabe eines Bereichs erstellt werden, sind nur gültig, wenn auf sie von einer Seite im selben Bereich verwiesen wird.

Wenn der Bereich nicht angegeben wird, hängt das Routing von den Umgebungswerten ab. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt. Oft werden ungültige Links erstellt, wenn für die Beispiel-App die Umgebungswerte verwendet werden. Betrachten Sie hierzu die aus dem folgenden Code generierten Links:

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

Für den Code oben gilt:

  • Der aus <a asp-page="/Manage/About"> generierte Link stimmt nur, wenn die letzte Anforderung für eine Seite im Services-Bereich erfolgte. Beispiel: /Services/Manage/, /Services/Manage/Index oder /Services/Manage/About.
  • Der aus <a asp-page="/About"> generierte Link stimmt nur, wenn die letzte Anforderung für eine Seite in /Home erfolgte.
  • Der Code stammt aus dem Beispieldownload.

Importieren von Namespace und Taghilfsprogrammen mit der _ViewImports-Datei

Eine Datei vom Typ _ViewImports.cshtml kann dem Ordner Pages jedes Bereichs hinzugefügt werden, um den Namespace und die Taghilfsprogramme für jede Razor-Seite im Ordner zu importieren.

Betrachten Sie den Bereich Services des Beispielcodes. Er enthält keine Datei vom Typ _ViewImports.cshtml. Das folgende Markup zeigt die Razor-Seite /Services/Manage/About:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

Im obenstehenden Markup:

  • Der vollqualifizierte Klassenname muss verwendet werden, um das Modell (@model RPareas.Areas.Services.Pages.Manage.AboutModel) anzugeben.
  • Taghilfsprogramme werden durch @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers aktiviert.

Im Beispieldownload enthält der Bereich „Products“ die folgende Datei vom Typ _ViewImports.cshtml:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Das folgende Markup zeigt die Razor-Seite /Products/About:

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

In der vorherigen Datei werden Namespace und @addTagHelper-Anweisung von der Datei Areas/Products/Pages/_ViewImports.cshtml in die Datei importiert.

Weitere Informationen finden Sie unter Verwalten des Taghilfsprogrammbereichs und Importieren gemeinsam verwendeter Anweisungen.

Gemeinsam genutztes Layout für Razor Pages-Bereiche

Um ein allgemeines Layout für die gesamte App freizugeben, verschieben Sie _ViewStart.cshtml in den Stammordner der Anwendung.

Veröffentlichen von Bereichen

Alle *.cshtml-Dateien und Dateien im wwwroot-Verzeichnis werden in der Ausgabe veröffentlicht, wenn <Project Sdk="Microsoft.NET.Sdk.Web"> in der *.csproj-Datei enthalten ist.

Hinzufügen eines MVC-Bereichs mit Visual Studio

Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Hinzufügen > Neues Gerüstelement und anschließend MVC-Bereich aus.

Bereiche sind ein Feature von ASP.NET, das für die Organisation von verwandten Funktionalitäten in eine Gruppe als separater Namespace (für Routing) und Ordnerstruktur (für Ansichten) verwendet wird. Mithilfe von Bereichen wird außerdem eine Hierarchie zu Routingzwecken erstellt, indem ein weiterer Routenparameter (area) zu controller und action oder zu einer Razor Page (page) hinzugefügt wird.

Bereiche ermöglichen es, eine ASP.NET Core-Web-App in kleinere funktionale Gruppen zu partitionieren. Jede dieser Gruppen hat dabei ihren eigenen Satz von Razor Pages, Controllern, Ansichten und Modellen. Ein Bereich ist im Grunde genommen eine Struktur in einer App. In einem ASP.NET Core-Webprojekt werden logische Komponenten wie Seiten, Modelle, Controller und Ansichten in verschiedenen Ordner aufbewahrt. Die ASP.NET Core-Runtime verwendet Namenskonventionen, um die Beziehung zwischen diesen Komponenten zu erstellen. Bei einer großen App kann es von Vorteil sein, die App in mehrere Bereiche auf hoher Funktionalitätsebene zu unterteilen, Dies gilt z.B. für eine E-Commerce-App mit mehreren Geschäftseinheiten, wie Auftragsabschluss, Abrechnung und Suche. Jede dieser Einheiten hat ihren eigenen Bereich für Ansichten, Controller, Razor Pages und Modelle.

Die Verwendung von Bereichen in einem Projekt ist erwägenswert, wenn:

  • Ihre App aus mehreren funktionalen Komponenten auf hoher Ebene besteht, die logisch getrennt sein können.
  • Sie Ihre App partitionieren möchten, damit jeder funktionale Bereich unabhängig voneinander bearbeitet werden kann.

Zeigen Sie Beispielcode an, oder laden Sie diesen herunter (Vorgehensweise zum Herunterladen). Das Downloadbeispiel stellt eine einfache App für Testbereiche zur Verfügung.

Wenn Sie Razor Pages verwenden, lesen Sie Bereiche mit Razor Pages in diesem Dokument.

Bereiche für Controller mit Ansichten

Eine typische ASP.NET Core-Web-App, die Bereiche, Controller und Ansichten verwendet, beinhaltet Folgendes:

  • Eine Bereichsordnerstruktur.

  • Controller werden mit dem Attribut [Area] versehen, um den Controller mit dem Bereich zu verknüpfen:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • Die Bereichsroute, die dem Startup hinzugefügt wurde:

    app.UseMvc(routes =>
    {
        routes.MapRoute(
          name: "MyArea",
          template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    
        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
    

Bereichsordnerstruktur

Stellen Sie sich eine App vor, die zwei logische Gruppen hat, Produkte und Dienste. Wenn Bereiche verwendet werden, würde die Ordnerstruktur ähnlich dem Folgenden aussehen:

  • Projektname
    • Bereiche
      • Products
        • Controller
          • HomeController.cs
          • ManageController.cs
        • Ansichten
          • Home
            • Index.cshtml
          • Verwalten
            • Index.cshtml
            • About.cshtml
      • Dienste
        • Controller
          • HomeController.cs
        • Ansichten
          • Home
            • Index.cshtml

Während das vorherige Layout typisch ist, wenn Bereiche verwendet werden, müssen nur die Ansichtsdateien diese Ordnerstruktur verwenden. Die Ansichtsermittlung sucht nach einer passenden Bereichsansichtsdatei im folgenden Ordner:

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

Zuordnen eines Controllers zu einem Bereich

Bereichscontroller werden mit dem Attribut [Area] versehen:

using Microsoft.AspNetCore.Mvc;

namespace MVCareas.Areas.Products.Controllers
{
    [Area("Products")]
    public class ManageController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult About()
        {
            return View();
        }
    }
}

Hinzufügen einer Bereichsroute

Bereichsrouten verwenden normalerweise konventionelles Routing anstatt Attributrouting. Beim herkömmlichen Routing ist die Reihenfolge wichtig. Routen mit Bereichen werden im Allgemeinen früher in der Routentabelle aufgeführt als die spezifischeren Routen ohne Bereich.

{area:...} kann als Token in Routenvorlagen verwendet werden, wenn der URL-Raum in allen Bereichen einheitlich ist:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
          name: "MyArea",
          template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Im vorherigen Code wendet exists eine Einschränkung an: Die Route muss mit einem Bereich übereinstimmen. {area:...} zu verwenden ist die unkomplizierteste Methode, um Bereichen Routing hinzuzufügen.

Im folgenden Code wird MapAreaRoute verwendet, um zwei benannte Bereichsrouten zu erstellen:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapAreaRoute(
            name: "MyAreaProducts",
            areaName:"Products",
            template: "Products/{controller=Home}/{action=Index}/{id?}");

        routes.MapAreaRoute(
            name: "MyAreaServices",
            areaName: "Services",
            template: "Services/{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
}

Wenn MapAreaRoute mit ASP.NET Core 2.2 verwendet werden soll, sehen Sie sich diesen GitHub-Artikel an.

Weitere Informationen finden Sie im Artikel Routing zu Controlleraktionen in ASP.NET Core.

Im folgenden Code aus dem Beispieldownload sehen Sie die Erstellung eines Links mit dem angegebenen Bereich:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage", 
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

Links, die mit dem vorherigen Code erstellt wurden, gelten überall in der App.

Im Beispieldownload ist eine partielle Ansicht enthalten, die die vorherigen Links und dieselben Links beinhaltet, ohne dass der Bereich angegeben wird. In der Layoutdatei wird auf die partielle Ansicht verwiesen. Jede Seite in der App stellt also die erstellen Links dar. Die Links, die ohne Angabe eines Bereichs erstellt werden, sind nur gültig, wenn auf sie von einer Seite im selben Bereich und Controller verwiesen wird.

Wenn der Bereich oder der Kontroller nicht angegeben werden, hängt das Routing von den Umgebungswerten ab. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt. Oft werden ungültige Links erstellt, wenn für die Beispiel-App die Umgebungswerte verwendet werden.

Weitere Informationen finden Sie unter Routing zu Controlleraktionen in ASP.NET Core.

Freigegebenes Layout für Bereiche unter Verwendung der _ViewStart.cshtml-Datei

Um ein allgemeines Layout für die gesamte App freizugeben, verschieben Sie _ViewStart.cshtml in den Stammordner der Anwendung.

_ViewImports.cshtml

An ihrem Standardspeicherort gilt die Datei /Views/_ViewImports.cshtml nicht für Bereiche. Um allgemeine Taghilfsprogramme, @using oder @inject in Ihrem Bereich zu verwenden, stellen Sie sicher, dass eine ordnungsgemäße Datei vom Typ _ViewImports.cshtmlfür Ihre Bereichsansichten gilt. Wenn Sie das gleiche Verhalten in allen Ansichten haben möchten, verschieben Sie /Views/_ViewImports.cshtml in den Anwendungsstamm.

Ändern des Standardbereichsordners, in dem Ansichten gespeichert sind

Der folgende Code ändert den Standardbereichsordner von "Areas" in "MyAreas":

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.AreaViewLocationFormats.Clear();
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
    });

    services.AddMvc();
}

Bereiche mit Razor Pages

Für Bereiche mit Razor Pages muss ein Ordner namens Areas/<area name>/Pages im Stammverzeichnis der App vorhanden sein. Die folgende Ordnerstruktur wird mit dem Beispiel-App verwendet.

  • Projektname
    • Bereiche
      • Products
        • Seiten
          • _ViewImports
          • Info
          • Index
      • Dienste
        • Seiten
          • Verwalten
            • Info
            • Index

Im folgenden Code aus dem Beispieldownload sehen Sie die Erstellung eines Links mit dem angegebenen Bereich (z.B. asp-area="Products"):

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

Links, die mit dem vorherigen Code erstellt wurden, gelten überall in der App.

Im Beispieldownload ist eine partielle Ansicht enthalten, die die vorherigen Links und dieselben Links beinhaltet, ohne dass der Bereich angegeben wird. In der Layoutdatei wird auf die partielle Ansicht verwiesen. Jede Seite in der App stellt also die erstellen Links dar. Die Links, die ohne Angabe eines Bereichs erstellt werden, sind nur gültig, wenn auf sie von einer Seite im selben Bereich verwiesen wird.

Wenn der Bereich nicht angegeben wird, hängt das Routing von den Umgebungswerten ab. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt. Oft werden ungültige Links erstellt, wenn für die Beispiel-App die Umgebungswerte verwendet werden. Betrachten Sie hierzu die aus dem folgenden Code generierten Links:

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

Für den Code oben gilt:

  • Der aus <a asp-page="/Manage/About"> generierte Link stimmt nur, wenn die letzte Anforderung für eine Seite im Services-Bereich erfolgte. Beispiel: /Services/Manage/, /Services/Manage/Index oder /Services/Manage/About.
  • Der aus <a asp-page="/About"> generierte Link stimmt nur, wenn die letzte Anforderung für eine Seite in /Home erfolgte.
  • Der Code stammt aus dem Beispieldownload.

Importieren von Namespace und Taghilfsprogrammen mit der _ViewImports-Datei

Eine Datei vom Typ _ViewImports.cshtml kann dem Ordner Pages jedes Bereichs hinzugefügt werden, um den Namespace und die Taghilfsprogramme für jede Razor-Seite im Ordner zu importieren.

Betrachten Sie den Bereich Services des Beispielcodes. Er enthält keine Datei vom Typ _ViewImports.cshtml. Das folgende Markup zeigt die Razor-Seite /Services/Manage/About:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<h2>/Services/Manage/About</h2>

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

Im obenstehenden Markup:

  • Der vollqualifizierte Domänenname muss verwendet werden, um das Modell anzugeben (@model RPareas.Areas.Services.Pages.Manage.AboutModel).
  • Taghilfsprogramme werden durch @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers aktiviert.

Im Beispieldownload enthält der Bereich „Products“ die folgende Datei vom Typ _ViewImports.cshtml:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Das folgende Markup zeigt die Razor-Seite /Products/About:

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

<h2>Products/About</h2>

<a asp-area="Services" asp-page="/Manage/About">
    Services/Manage/About
</a>

In der vorherigen Datei werden Namespace und @addTagHelper-Anweisung von der Datei Areas/Products/Pages/_ViewImports.cshtml in die Datei importiert.

Weitere Informationen finden Sie unter Verwalten des Taghilfsprogrammbereichs und Importieren gemeinsam verwendeter Anweisungen.

Gemeinsam genutztes Layout für Razor Pages-Bereiche

Um ein allgemeines Layout für die gesamte App freizugeben, verschieben Sie _ViewStart.cshtml in den Stammordner der Anwendung.

Veröffentlichen von Bereichen

Alle *.cshtml-Dateien und Dateien im wwwroot-Verzeichnis werden in der Ausgabe veröffentlicht, wenn <Project Sdk="Microsoft.NET.Sdk.Web"> in der *.csproj-Datei enthalten ist.