Bereiche in ASP.NET Core

Von Dhananjay Kumar und Rick Anderson

Bereiche sind ein ASP.NET Feature, das verwendet wird, um verwandte Funktionen in einer Gruppe als separates zu organisieren:

  • Namespace für Routing.
  • Ordnerstruktur für Ansichten und Razor Seiten.

Mithilfe von Bereichen wird eine Hierarchie für den Zweck des Routings erstellt, indem sie einen anderen Routenparameter, areazu controller und action einer Razor Seite pagehinzufügen.

Bereiche bieten eine Möglichkeit, eine ASP.NET Core Web-App in kleinere funktionsbezogene Gruppen zu partitionieren, die jeweils eine eigene Gruppe von Razor Seiten, Controllern, Ansichten und Modellen aufweisen. 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 mit hoher Funktionalität aufzuteilen. Dies gilt z.B. für eine E-Commerce-App mit mehreren Geschäftseinheiten, wie Auftragsabschluss, Abrechnung und Suche. Jede dieser Einheiten verfügt über einen eigenen Bereich, der Ansichten, Controller, Razor Seiten und Modelle enthält.

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 Seiten verwenden Razor , lesen Sie Bereiche mit Razor Seiten 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 wurde hinzugefügt zu Program.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
      • Produkte
        • Controller
          • HomeController.cs
          • ManageController.cs
        • Sichten
          • Home
            • Index.cshtml
          • Verwalten
            • Index.cshtml
            • About.cshtml
      • Dienste
        • Controller
          • HomeController.cs
        • Sichten
          • 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 [Area] Attribut festgelegt:

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

Flächenrouten verwenden in der Regel herkömmliches Routing anstelle des Attributroutings. 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. Verwenden {area:...} mit MapControllerRoute:

  • Ist der am wenigsten komplizierte Mechanismus zum Hinzufügen von Routing zu Bereichen.
  • Entspricht allen Controllern mit dem [Area("Area name")] Attribut.

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 , die Folgendes enthält:

  • Die vorherigen Links.
  • Links ähnlich wie oben, außer area es ist nicht angegeben.

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. In vielen Fällen für die Beispiel-App generiert die Verwendung der Umgebungswerte falsche Verknüpfungen mit dem Markup, das den Bereich nicht angibt.

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 gemeinsames Layout für die gesamte App freizugeben, behalten Sie den _ViewStart.cshtml im Anwendungsstammordner bei. Weitere Informationen finden Sie unter Layout in ASP.NET Core

Anwendungsstammordner

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

_ViewImports.cshtml

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

  • Fügen Sie dem Anwendungsstammordner_ViewImports.cshtml hinzu. Ein _ViewImports.cshtml im Anwendungsstammordner gilt für alle Ansichten in der App.
  • Kopieren Sie die Datei _ViewImports.cshtml in den entsprechenden Ansichtsordner unter Bereichen. Eine mit einzelnen Benutzerkonten erstellte Seiten-App verfügt beispielsweise Razor in den folgenden Ordnern über eine datei "_ViewImports.cshtml ":
    • /Areas/Identity/Pages/_ViewImports.cshtml
    • /Pages/_ViewImports.cshtml

Die Datei _ViewImports.cshtml enthält in der Regel Tag-Hilfshilfen-Importe , @usingund @inject Anweisungen. Weitere Informationen finden Sie unter Importieren freigegebener Direktiven.

Ä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 Seiten

Bereiche mit Razor Seiten erfordern einen Areas/<area name>/Pages Ordner im Stammverzeichnis der App. Die folgende Ordnerstruktur wird mit dem Beispiel-App verwendet.

  • Projektname
    • Bereiche
      • Produkte
        • 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 _ViewImports.cshtml-Datei kann jedem Bereichsseitenordner hinzugefügt werden, um den Namespace und die Taghilfen auf 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 /Services/Manage/AboutRazor Page:

@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 zum Angeben des Modells (@model RPareas.Areas.Services.Pages.Manage.AboutModel) verwendet werden.
  • Taghilfen werden durch aktiviert @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

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 /Products/AboutRazor Page:

@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.

Freigegebenes Layout für Razor Seitenbereiche

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 von MVC-Bereich mit Visual Studio

Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Neues Gerüstelement hinzufügen>" und dann "MVC-Bereich" aus.

Zusätzliche Ressourcen

Bereiche sind ein ASP.NET Feature, das zum Organisieren verwandter Funktionen in eine Gruppe als separates verwendet wird:

  • Namespace für Routing.
  • Ordnerstruktur für Ansichten und Razor Seiten.

Mithilfe von Bereichen wird eine Hierarchie zum Zweck des Routings erstellt, indem sie einen anderen Routenparameter hinzufügen, areazu controller und action eine Razor Seite pagehinzufügen.

Bereiche bieten eine Möglichkeit, eine ASP.NET Core Web-App in kleinere funktionsbezogene Gruppen zu partitionieren, die jeweils einen eigenen Satz von Razor Seiten, Controllern, Ansichten und Modellen enthalten. 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 mit hoher Funktionalität aufzuteilen. Dies gilt z.B. für eine E-Commerce-App mit mehreren Geschäftseinheiten, wie Auftragsabschluss, Abrechnung und Suche. Jede dieser Einheiten verfügt über einen eigenen Bereich, um Ansichten, Controller, Razor Seiten und Modelle zu enthalten.

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 Seiten verwenden Razor , lesen Sie Bereiche mit Razor Seiten 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
      • Produkte
        • Controller
          • HomeController.cs
          • ManageController.cs
        • Sichten
          • Home
            • Index.cshtml
          • Verwalten
            • Index.cshtml
            • About.cshtml
      • Dienste
        • Controller
          • HomeController.cs
        • Sichten
          • 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] festgelegt:

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 in der Regel herkömmliche Routing anstelle von 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. Verwenden {area:...} mit MapControllerRoute:

  • Ist der am wenigsten komplizierte Mechanismus zum Hinzufügen von Routing zu Bereichen.
  • Entspricht allen Controllern mit dem [Area("Area name")] Attribut.

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 , die Folgendes enthält:

  • Die vorhergehenden Links.
  • Links ähnlich wie die vorhergehende Ausnahme area ist nicht angegeben.

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. In vielen Fällen für die Beispiel-App generiert die Verwendung der Umgebungswerte falsche Links mit dem Markup, das den Bereich nicht angibt.

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 gemeinsames Layout für die gesamte App freizugeben, behalten Sie den _ViewStart.cshtmlStammordner der Anwendung auf. Weitere Informationen finden Sie unter Layout in ASP.NET Core

Anwendungsstammordner

Der Stammordner der Anwendung ist der OrdnerStartup.cs, der in der Web-App mit den ASP.NET Core Vorlagen erstellt wurde.

_ViewImports.cshtml

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

  • Fügen Sie dem Anwendungsstammordner hinzu_ViewImports.cshtml. Ein _ViewImports.cshtml Anwendungsstammordner gilt für alle Ansichten in der App.
  • Kopieren Sie die _ViewImports.cshtml Datei in den entsprechenden Ansichtsordner unter Bereichen.

Die Datei enthält in der _ViewImports.cshtml Regel Tag-Hilfshilfen importe, @usingund @inject Anweisungen. Weitere Informationen finden Sie unter Importieren freigegebener Richtlinien.

Ä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 Seiten

Bereiche mit Razor Seiten erfordern einen Areas/<area name>/Pages Ordner im Stamm der App. Die folgende Ordnerstruktur wird mit dem Beispiel-App verwendet.

  • Projektname
    • Bereiche
      • Produkte
        • 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 _ViewImports.cshtml Datei kann jedem Bereichsseitenordner hinzugefügt werden, um den Namespace und die Taghilfen auf jede Razor Seite im Ordner zu importieren.

Berücksichtigen Sie den Bereich "Dienste " im Beispielcode, der keine Datei enthält _ViewImports.cshtml . Das folgende Markup zeigt die /Services/Manage/AboutRazor Page:

@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 zum Angeben des Modells (@model RPareas.Areas.Services.Pages.Manage.AboutModel) verwendet werden.
  • Taghilfen werden durch aktiviert @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Im Beispieldownload enthält der Bereich "Produkte" die folgende _ViewImports.cshtml Datei:

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

Das folgende Markup zeigt die /Products/AboutRazor Page:

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

In der vorherigen Datei wird der Namespace und @addTagHelper die Direktive durch die Datei in die Areas/Products/Pages/_ViewImports.cshtml Datei importiert.

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

Freigegebenes Layout für Razor Seitenbereiche

Um ein gemeinsames Layout für die gesamte App zu teilen, verschieben Sie den _ViewStart.cshtml 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 von MVC-Bereich mit Visual Studio

Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Neues Gerüstelement hinzufügen>" und dann "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 eine Hierarchie zum Zweck des Routings erstellt, indem sie einen anderen Routenparameter hinzufügen, areazu controller und action eine Razor Seite pagehinzufügen.

Bereiche bieten eine Möglichkeit, eine ASP.NET Core Web-App in kleinere funktionsbezogene Gruppen zu partitionieren, die jeweils einen eigenen Satz von Razor Seiten, Controllern, Ansichten und Modellen enthalten. 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 mit hoher Funktionalität aufzuteilen. Dies gilt z.B. für eine E-Commerce-App mit mehreren Geschäftseinheiten, wie Auftragsabschluss, Abrechnung und Suche. Jede dieser Einheiten verfügt über einen eigenen Bereich, um Ansichten, Controller, Razor Seiten und Modelle zu enthalten.

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 Seiten verwenden Razor , lesen Sie Bereiche mit Razor Seiten 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
      • Produkte
        • Controller
          • HomeController.cs
          • ManageController.cs
        • Sichten
          • Home
            • Index.cshtml
          • Verwalten
            • Index.cshtml
            • About.cshtml
      • Dienste
        • Controller
          • HomeController.cs
        • Sichten
          • 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 [Area] -Attribut angegeben:

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

Wenn Sie ein gemeinsames Layout für die gesamte App freigeben möchten, verschieben Sie den _ViewStart.cshtml Ordner in den Stammordner der Anwendung.

_ViewImports.cshtml

In seinem Standardstandort /Views/_ViewImports.cshtml gilt es nicht für Bereiche. Um allgemeine Taghilfen oder in Ihrem Bereich zu verwenden, stellen Sie sicher, @using@inject dass eine richtige _ViewImports.cshtml Datei für Ihre Bereichsansichten gilt. Wenn Sie das gleiche Verhalten in allen Ansichten wünschen, wechseln Sie /Views/_ViewImports.cshtml zum 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 Seiten

Bereiche mit Razor Seiten erfordern einen Areas/<area name>/Pages Ordner im Stammverzeichnis der App. Die folgende Ordnerstruktur wird mit dem Beispiel-App verwendet.

  • Projektname
    • Bereiche
      • Produkte
        • 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 _ViewImports.cshtml Datei kann jedem Bereichsseitenordner hinzugefügt werden, um den Namespace und die Taghilfen in jede Razor Seite im Ordner zu importieren.

Betrachten Sie den Bereich "Dienste " des Beispielcodes, der keine Datei enthält _ViewImports.cshtml . Das folgende Markup zeigt die Seite "/Dienste/Verwalten/InformationenRazor ":

@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).
  • Taghilfen werden durch aktiviert @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Im Beispieldownload enthält der Bereich "Produkte" die folgende _ViewImports.cshtml Datei:

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

Das folgende Markup zeigt die /Products/AboutRazor Page:

@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 wird der Namespace und @addTagHelper die Direktive von der Datei in die Areas/Products/Pages/_ViewImports.cshtml Datei importiert.

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

Freigegebenes Layout für Razor Seitenbereiche

Wenn Sie ein gemeinsames Layout für die gesamte App freigeben möchten, verschieben Sie den _ViewStart.cshtml Ordner 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.