Razor Pages: Routen- und App-Konventionen in ASP.NET Core
Erfahren Sie, wie Sie in Apps für Razor Pages mithilfe von Konventionen für Seitenrouten und App-Modellanbieter das Seitenrouting, die Ermittlung und die Verarbeitung steuern können.
Um eine Seitenroute anzugeben oder einer Route Segmente oder Parameter hinzuzufügen, verwenden Sie die Anweisung @page
der Seite. Weitere Informationen finden Sie unter Benutzerdefinierte Routen.
Es gibt reservierte Wörter, die nicht als Routensegmente oder Parameternamen verwendet werden können. Weitere Informationen finden Sie unter Routing: Reservierte Routingnamen.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Szenario | Dieses Beispiel veranschaulicht Folgendes |
---|---|
Model conventions (Modellkonventionen) Conventions.Add |
Das Hinzufügen einer Routenvorlage und eines Headers zu den Seiten einer App |
Konventionen für Seitenroutenaktionen | Das Hinzufügen einer Routenvorlage zu Seiten in einem Ordner und zu einer Einzelseite |
Konventionen für Seitenmodellaktionen
|
Das Hinzufügen eines Headers zu Seiten in einem Ordner, das Hinzufügen eines Headers zu einer einzelnen Seite und das Konfigurieren einer Filter-Factoy zum Hinzufügen eines Headers zu den Seiten einer App. |
Razor Pages-Konventionen werden mithilfe einer AddRazorPages-Überladung konfiguriert, die RazorPagesOptions konfiguriert. Die folgenden Beispiele der Konvention werden später in diesem Thema erläutert:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(options =>
{
options.Conventions.Add( ... );
options.Conventions.AddFolderRouteModelConvention(
"/OtherPages", model => { ... });
options.Conventions.AddPageRouteModelConvention(
"/About", model => { ... });
options.Conventions.AddPageRoute(
"/Contact", "TheContactPage/{text?}");
options.Conventions.AddFolderApplicationModelConvention(
"/OtherPages", model => { ... });
options.Conventions.AddPageApplicationModelConvention(
"/About", model => { ... });
options.Conventions.ConfigureFilter(model => { ... });
options.Conventions.ConfigureFilter( ... );
});
}
Routenreihenfolge
Routen geben eine Order für die Verarbeitung an (Routenabgleich).
Routenreihenfolge | Verhalten |
---|---|
-1 | Die Route wird vor anderen Routen verarbeitet. |
0 | Die Reihenfolge wurde nicht angegeben (Standardwert). Wenn Sie Order (Order = null ) nicht zuweisen, wird für die Verarbeitung der Route Order standardmäßig auf 0 (null) gesetzt. |
1, 2, … n | Gibt die Verarbeitungsreihenfolge für die Route an. |
Die Routenverarbeitung wird gemäß der Konvention eingerichtet:
- Routen werden in sequenzieller Reihenfolge verarbeitet (-1, 0, 1, 2, ... n).
- Wenn Routen dieselbe
Order
aufweisen, wird zuerst die spezifischste Route abgeglichen, danach folgen die weniger spezifischen Routen. - Wenn Routen mit derselben
Order
und derselben Anzahl Parameter mit einer Anforderungs-URL übereinstimmen, werden Routen in der Reihenfolge verarbeitet, in der sie der PageConventionCollection hinzugefügt wurden.
Vermeiden Sie nach Möglichkeit die Abhängigkeit von einer festgelegten Verarbeitungsreihenfolge für Routen. Im Allgemeinen wird beim Routing die richtige Route mittels URL-Zuordnung ausgewählt. Wenn Sie zum ordnungsgemäßen Weiterleiten von Anforderungen für die Route Order
-Eigenschaften festlegen müssen, ist das Routingschema der App für Clients wahrscheinlich irreführend und in Bezug auf die Verwaltung störanfälliger. Versuchen Sie daher, das Routingschema der App zu vereinfachen. Bei der Beispiel-App ist eine explizite Verarbeitungsreihenfolge für Routen erforderlich, um mit einer einzigen App verschiedene Routingszenarios veranschaulichen zu können. In Produktions-Apps sollten Sie jedoch nach Möglichkeit eine Festlegung von Order
für Routen vermeiden.
Razor Pages-Routing und MVC Controller-Routing verwenden eine gemeinsame Implementierung. Informationen zur Reihenfolge von Routen in den MVC-Themen finden Sie unter Routing zu Controlleraktionen: Ordnen der Attributrouten.
Modellkonventionen
Fügen Sie einen Delegaten für IPageConvention hinzu, um Modellkonventionen hinzuzufügen, die auf Razor Pages anwendbar sind.
Hinzufügen einer Routenmodellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageRouteModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenroutenmodellen eingesetzt werden.
Die Beispielanwendung beinhaltet GlobalTemplatePageRouteModelConvention
-Klasse, um eine {globalTemplate?}
-Routenvorlage zu allen Seiten der App hinzuzufügen:
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace SampleApp.Conventions;
public class GlobalTemplatePageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 1,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel!.Template,
"{globalTemplate?}"),
}
});
}
}
}
Für den Code oben gilt:
- Die PageRouteModel wird an die Apply Methode übergeben.
- Der Befehl PageRouteModel.Selectors ruft die Anzahl der Selektoren ab.
- Es wird ein neue SelectorModel hinzugefügt, der eine AttributeRouteModel enthält
Razor Pages-Optionen wie das Hinzufügen von Conventions werden hinzugefügt, wenn Razor Pages zur Dienstsammlung hinzugefügt wird. In der Beispiel-App finden Sie ein Beispiel hierfür.
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.EntityFrameworkCore;
using SampleApp.Conventions;
using SampleApp.Data;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseInMemoryDatabase("InMemoryDb"));
builder.Services.AddRazorPages(options =>
{
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
options.Conventions.AddFolderRouteModelConvention("/OtherPages", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel!.Template,
"{otherPagesTemplate?}"),
}
});
}
});
options.Conventions.AddPageRouteModelConvention("/About", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel!.Template,
"{aboutTemplate?}"),
}
});
}
});
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Betrachten Sie die GlobalTemplatePageRouteModelConvention
Klasse:
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace SampleApp.Conventions;
public class GlobalTemplatePageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 1,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel!.Template,
"{globalTemplate?}"),
}
});
}
}
}
Die Eigenschaft Order ist für das AttributeRouteModel auf 1
festgelegt. Dadurch wird das folgende Routenabgleichsverhalten in der Beispiel-App sichergestellt:
Eine Routenvorlage für
TheContactPage/{text?}
wird später in diesem Thema hinzugefügt. Die Standardreihenfolge derContact Page
Route lautetnull
(Order = 0
). Somit wird sie vor der Routenvorlage{globalTemplate?}
abgeglichen, welcheOrder = 1
hat.Die
{aboutTemplate?}
Routenvorlage wurde im vorausgehenden Code gezeigt. Die Vorlage{aboutTemplate?}
erhält denOrder
von2
. Wenn die Seite „Info“ unter/About/RouteDataValue
angefordert wird, wird „RouteDataValue“ in die VorlageRouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht inRouteData.Values["aboutTemplate"]
(Order = 2
), da die EigenschaftOrder
auf null festgelegt wurde.Die
{otherPagesTemplate?}
Routenvorlage wurde im vorausgehenden Code gezeigt. Die Vorlage{otherPagesTemplate?}
erhält denOrder
von2
. Wenn eine beliebige Seite im Pages/OtherPages Ordner mit einem Routenparameter angefordert wird:Zum Beispiel,
/OtherPages/Page1/xyz
Der Routendatenwert
"xyz"
wird inRouteData.Values["globalTemplate"]
(Order = 1
) geladen.RouteData.Values["otherPagesTemplate"]
mit (Order = 2
) wird nicht geladen, weil dieOrder
Eigenschaft2
einen höheren Wert hat.
Wenn möglich, legen Sie die Order
nicht fest. Wenn Order
nicht festgelegt ist, dann ist es standardmäßig Order = 0
. Verlassen Sie sich auf das Routing anstelle der Order
Eigenschaft, um die richtige Route zu wählen.
Fordern Sie die About
Seite der Beispielanwendung unter localhost:{port}/About/GlobalRouteValue
an, und prüfen Sie das Ergebnis:
Die Beispiel-App verwendet das Rick.Docs.Samples.RouteInfo NuGet-Paket, um Routinginformationen in der Protokollierungsausgabe anzuzeigen. Mithilfe von localhost:{port}/About/GlobalRouteValue
zeigt die Protokollierung die Anforderung, die Order
, und die verwendete Vorlage an:
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue Order = 1 Template = About/{globalTemplate?}
Hinzufügen einer App-Modellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageApplicationModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenanwendungsmodellen eingesetzt werden.
Die Beispielanwendung enthält eine AddHeaderAttribute
-Klasse, damit das Verwenden dieser und anderer Konventionen weiter unten in diesem Thema gezeigt werden kann. Der Klassenkonstruktor akzeptiert eine name
-Zeichenfolge und ein values
-Zeichenfolgenarray. Diese Werte werden in seiner OnResultExecuting
-Methode verwendet, um einen Antwortheader einzurichten. Die Klasse wird im Abschnitt Seitenmodellaktionskonventionen weiter unten in diesem Artikel erläutert.
Die Beispielanwendung verwendet die Klasse AddHeaderAttribute
, um den Header GlobalHeader
zu allen Seiten der Anwendung hinzuzufügen:
public class GlobalHeaderPageApplicationModelConvention
: IPageApplicationModelConvention
{
public void Apply(PageApplicationModel model)
{
model.Filters.Add(new AddHeaderAttribute(
"GlobalHeader", new string[] { "Global Header Value" }));
}
}
Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseInMemoryDatabase("InMemoryDb"));
builder.Services.AddRazorPages(options =>
{
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
options.Conventions.Add(new GlobalHeaderPageApplicationModelConvention());
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:{port}/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Hinzufügen einer Handlermodellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageHandlerModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenhandlermodellen eingesetzt werden.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Konventionen für Seitenroutenaktionen
Der Standardanbieter für Routenmodelle, der von IPageRouteModelProvider abgeleitet wird, ruft Konventionen auf, die entwickelt wurden, um Erweiterungspunkte zum Konfigurieren von Seitenrouten bereitzustellen.
Ordnerroutenmodellkonvention
Verwenden Sie AddFolderRouteModelConvention zum Erstellen und Hinzuzufügen einer IPageRouteModelConvention, die eine Aktion für PageRouteModel für alle Seiten im angegebenen Ordner aufruft.
Die Beispielanwendung verwendet AddFolderRouteModelConvention, um eine {otherPagesTemplate?}
-Routenvorlage zu den Seiten im Ordner OtherPages hinzuzufügen:
options.Conventions.AddFolderRouteModelConvention("/OtherPages", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel!.Template,
"{otherPagesTemplate?}"),
}
});
}
});
Die Eigenschaft Order ist für das AttributeRouteModel auf 2
festgelegt. Dadurch wird sichergestellt, dass die Vorlage für {globalTemplate?}
, die weiter oben in diesem Thema für 1
festgelegt wurde, in Bezug auf die erste Position für einen Routendatenwert vorgezogen wird, wenn nur ein einziger Routenwert angegeben wurde. Wenn eine Seite im Ordner Pages/OtherPages mit einem Routenparameterwert (z. B. /OtherPages/Page1/RouteDataValue
) angefordert wird, wird „RouteDataValue“ in die Vorlage RouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht in RouteData.Values["otherPagesTemplate"]
(Order = 2
), da die Eigenschaft Order
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Fordern Sie die Seite „Seite1“ der Beispielanwendung unter localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
an, und prüfen Sie das Ergebnis:
Seitenroutenmodellkonvention
Verwenden Sie AddPageRouteModelConvention zum Erstellen und Hinzuzufügen einer IPageRouteModelConvention, die eine Aktion für das PageRouteModel für die Seite mit dem angegebenen Namen aufruft.
Die Beispielanwendung verwendet AddPageRouteModelConvention
, um eine {aboutTemplate?}
-Routenvorlage zu der Seite „Info“ hinzuzufügen:
options.Conventions.AddPageRouteModelConvention("/About", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel!.Template,
"{aboutTemplate?}"),
}
});
}
});
Die Eigenschaft Order ist für das AttributeRouteModel auf 2
festgelegt. Dadurch wird sichergestellt, dass die Vorlage für {globalTemplate?}
, die weiter oben in diesem Thema für 1
festgelegt wurde, in Bezug auf die erste Position für einen Routendatenwert vorgezogen wird, wenn nur ein einziger Routenwert angegeben wurde. Wenn die Seite „Info“ mit einem Routenparameterwert unter /About/RouteDataValue
angefordert wird, wird „RouteDataValue“ in die Vorlage RouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht in RouteData.Values["aboutTemplate"]
(Order = 2
), da die Eigenschaft Order
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:{port}/About/GlobalRouteValue/AboutRouteValue
an, und prüfen Sie das Ergebnis:
Die Protokollierungsausgabe zeigt Folgendes an:
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue/AboutRouteValue Order = 2 Template = About/{globalTemplate?}/{aboutTemplate?}
Verwenden eines Parametertransformators zum Anpassen von Seitenrouten
Siehe Parametertransformatoren.
Konfigurieren einer Seitenroute
Konfigurieren Sie mithilfe von AddPageRoute eine Route zu einer Seite am angegebenen Seitenpfad. Generierte Links, die auf die Seite verweisen, verwenden die spezifizierte Route. AddPageRoute verwendet die AddPageRouteModelConvention zum Aufbauen der Route.
Die Beispielanwendung erstellt eine Route zur /TheContactPage
für die Contact
Razor Seite:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
Die Contact
Seite kann auch unter /
Contact1` über ihre Standardroute erreicht werden.
Die benutzerdefinierte Route der Beispielanwendung, die zur Contact
Seite führt, ermöglicht das Verwenden eines optionalen text
-Routensegments ({text?}
). Die Seite enthält dieses optionale Segment auch in ihrer @page
-Anweisung, für den Fall, dass der Besucher über die /Contact
-Route auf die Seite zugreift:
@page "{text?}"
@model ContactModel
@{
ViewData["Title"] = "Contact";
}
<h1>@ViewData["Title"]</h1>
<h2>@Model.Message</h2>
<address>
One Microsoft Way<br>
Redmond, WA 98052-6399<br>
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
<address>
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br>
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
</address>
<p>@Model.RouteDataTextTemplateValue</p>
Beachten Sie, dass die URL, die für den Link Kontakt in der gerenderten Seite generiert wurde, die aktualisierte Route widerspiegelt:
Sie können die Contact
Seite entweder über deren übliche Route, /Contact
, oder über die benutzerdefinierte Route, /TheContactPage
, besuchen. Wenn Sie ein zusätzliches text
-Routensegment bereitstellen, wird dieses HTML-codierte Segment auf der Seite angezeigt:
Konventionen für Seitenmodellaktionen
Der Standardanbieter für Seitenmodelle, der IPageApplicationModelProvider implementiert, ruft Konventionen auf, die entwickelt wurden, um Erweiterungspunkte zum Konfigurieren von Seitenmodellen bereitzustellen. Diese Konventionen sind beim Erstellen und Ändern von Seitenermittlungs- und Verarbeitungsszenarios hilfreich.
In den Beispielen in diesem Abschnitt verwendet die Beispielanwendung eine AddHeaderAttribute
-Klasse, also ein ResultFilterAttribute, das einen Antwortheader verwendet:
public class AddHeaderAttribute : ResultFilterAttribute
{
private readonly string _name;
private readonly string[] _values;
public AddHeaderAttribute(string name, string[] values)
{
_name = name;
_values = values;
}
public override void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(_name, _values);
base.OnResultExecuting(context);
}
}
Das Beispiel veranschaulicht mithilfe von Konventionen, wie das Attribut auf alle Seiten in einem Ordner und auf eine Einzelseite angewendet werden kann.
Ordner-App-Modellkonvention
Verwenden Sie AddFolderApplicationModelConvention zum Erstellen und Hinzuzufügen einer IPageApplicationModelConvention, die eine Aktion für PageApplicationModel-Instanzen für alle Seiten im angegebenen Ordner aufruft.
Im Beispiel wird die Verwendung der AddFolderApplicationModelConvention
durch Hinzufügen eines Headers, OtherPagesHeader
, zu den Seiten im Ordner OtherPages der Anwendung veranschaulicht:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Fordern Sie die Seite „Seite1“ der Beispielanwendung unter localhost:5000/OtherPages/Page1
an, und prüfen Sie die Header, um das Ergebnis zu sehen:
Seiten-App-Modellkonvention
Verwenden Sie AddPageApplicationModelConvention zum Erstellen und Hinzuzufügen einer IPageApplicationModelConvention, die eine Aktion für das PageApplicationModel für die Seite mit dem angegebenen Namen aufruft.
Im Beispiel wird das Verwenden von AddPageApplicationModelConvention
durch Hinzufügen eines Headers, AboutHeader
, auf der Seite „Info“ veranschaulicht:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Konfigurieren eines Filters
Der angegebene Filter, der angewendet werden soll, wird mit ConfigureFilter konfiguriert. Sie können Filterklassen selbst implementieren. In der Beispielanwendung wird jedoch gezeigt, wie Sie einen Filter in einen Lambdaausdruck implementieren. Dieser wird dann im Hintergrund als Zuordnungsinstanz implementiert, die einen Filter zurückgibt:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Das Seiten-App-Modell wird verwendet, um den relativen Pfad für Segmente zu überprüfen, die zur Seite „Seite2“ im Ordner OtherPages führen. Wenn die Bedingung erfüllt ist, wird ein Header hinzugefügt. Wenn dies nicht der Fall ist, wird der EmptyFilter
angewendet.
EmptyFilter
ist ein Aktionsfilter. Wenn der Pfad OtherPages/Page2
nicht enthält, hat der EmptyFilter
, wie vorgesehen, keine Auswirkung, da Aktionsfilter von Razor Pages ignoriert werden.
Fordern Sie die Seite „Seite2“ der Beispielanwendung unter localhost:5000/OtherPages/Page2
an, und prüfen Sie die Header, um das Ergebnis zu sehen:
Konfigurieren einer Filterzuordnungsinstanz
Mit ConfigureFilter wird die angegebene Zuordnungsinstanz so konfiguriert, dass sie Filter auf alle Razor Pages anwendet.
Die Beispielanwendung bietet Ihnen die Möglichkeit des beispielhaften Verwendens einer Filterzuordnungsinstanz durch Hinzufügen des Headers FilterFactoryHeader
zu den Seiten der Anwendung, der zwei Werte besitzt:
options.Conventions.ConfigureFilter(new AddHeaderWithFactory());
AddHeaderWithFactory.cs
:
public class AddHeaderWithFactory : IFilterFactory
{
// Implement IFilterFactory
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return new AddHeaderFilter();
}
private class AddHeaderFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(
"FilterFactoryHeader",
new string[]
{
"Filter Factory Header Value 1",
"Filter Factory Header Value 2"
});
}
public void OnResultExecuted(ResultExecutedContext context)
{
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Die MVC-Filter und der Seitenfilter (IPageFilter)
MVC-Aktionsfilter werden von Razor Pages ignoriert, da Razor Pages Handlermethoden verwenden. Darüber hinaus stehen die folgenden MVC-Filtertypen zur Verfügung: Autorisierung, Ausnahme, Ressource und Ergebnis. Weitere Informationen finden Sie im Thema Filter.
Der Seitenfilter (IPageFilter) ist ein Filter, der auf Razor Pages anwendbar ist. Weitere Informationen finden Sie unter Filtermethoden für Razor Pages.
Zusätzliche Ressourcen
Erfahren Sie, wie Sie in Apps für Razor Pages mithilfe von Konventionen für Seitenrouten und App-Modellanbieter das Seitenrouting, die Ermittlung und die Verarbeitung steuern können.
Wenn Sie für einzelne Seiten benutzerdefinierte Seitenrouten konfigurieren müssen, sollten Sie das Routing zu den Seiten mithilfe der AddPageRoute-Konvention konfigurieren, die weiter unten in diesem Artikel beschrieben wird.
Um eine Seitenroute anzugeben oder einer Route Segmente oder Parameter hinzuzufügen, verwenden Sie die Anweisung @page
der Seite. Weitere Informationen finden Sie unter Benutzerdefinierte Routen.
Es gibt reservierte Wörter, die nicht als Routensegmente oder Parameternamen verwendet werden können. Weitere Informationen finden Sie unter Routing: Reservierte Routingnamen.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Szenario | Dieses Beispiel veranschaulicht Folgendes: |
---|---|
Model conventions (Modellkonventionen) Conventions.Add
|
Das Hinzufügen einer Routenvorlage und eines Headers zu den Seiten einer App |
Konventionen für Seitenroutenaktionen
|
Das Hinzufügen einer Routenvorlage zu Seiten in einem Ordner und zu einer Einzelseite |
Konventionen für Seitenmodellaktionen
|
Das Hinzufügen eines Headers zu Seiten in einem Ordner, das Hinzufügen eines Headers zu einer einzelnen Seite und das Konfigurieren einer Filter-Factoy zum Hinzufügen eines Headers zu den Seiten einer App. |
Razor Pages-Konventionen werden mithilfe einer AddRazorPages-Überladung konfiguriert, die RazorPagesOptions in Startup.ConfigureServices
konfiguriert. Die folgenden Beispiele der Konvention werden später in diesem Thema erläutert:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.Add( ... );
options.Conventions.AddFolderRouteModelConvention(
"/OtherPages", model => { ... });
options.Conventions.AddPageRouteModelConvention(
"/About", model => { ... });
options.Conventions.AddPageRoute(
"/Contact", "TheContactPage/{text?}");
options.Conventions.AddFolderApplicationModelConvention(
"/OtherPages", model => { ... });
options.Conventions.AddPageApplicationModelConvention(
"/About", model => { ... });
options.Conventions.ConfigureFilter(model => { ... });
options.Conventions.ConfigureFilter( ... );
});
}
Routenreihenfolge
Routen geben eine Order für die Verarbeitung an (Routenabgleich).
Auftrag | Verhalten |
---|---|
-1 | Die Route wird vor anderen Routen verarbeitet. |
0 | Die Reihenfolge wurde nicht angegeben (Standardwert). Wenn Sie Order (Order = null ) nicht zuweisen, wird für die Verarbeitung der Route Order standardmäßig auf 0 (null) gesetzt. |
1, 2, … n | Gibt die Verarbeitungsreihenfolge für die Route an. |
Die Routenverarbeitung wird gemäß der Konvention eingerichtet:
- Routen werden in sequenzieller Reihenfolge verarbeitet (-1, 0, 1, 2, ... n).
- Wenn Routen dieselbe
Order
aufweisen, wird zuerst die spezifischste Route abgeglichen, danach folgen die weniger spezifischen Routen. - Wenn Routen mit derselben
Order
und derselben Anzahl Parameter mit einer Anforderungs-URL übereinstimmen, werden Routen in der Reihenfolge verarbeitet, in der sie der PageConventionCollection hinzugefügt wurden.
Vermeiden Sie nach Möglichkeit die Abhängigkeit von einer festgelegten Verarbeitungsreihenfolge für Routen. Im Allgemeinen wird beim Routing die richtige Route mittels URL-Zuordnung ausgewählt. Wenn Sie zum ordnungsgemäßen Weiterleiten von Anforderungen für die Route Order
-Eigenschaften festlegen müssen, ist das Routingschema der App für Clients wahrscheinlich irreführend und in Bezug auf die Verwaltung störanfälliger. Versuchen Sie daher, das Routingschema der App zu vereinfachen. Bei der Beispiel-App ist eine explizite Verarbeitungsreihenfolge für Routen erforderlich, um mit einer einzigen App verschiedene Routingszenarios veranschaulichen zu können. In Produktions-Apps sollten Sie jedoch nach Möglichkeit eine Festlegung von Order
für Routen vermeiden.
Razor Pages-Routing und MVC Controller-Routing verwenden eine gemeinsame Implementierung. Informationen zur Reihenfolge von Routen in den MVC-Themen finden Sie unter Routing zu Controlleraktionen: Ordnen der Attributrouten.
Modellkonventionen
Fügen Sie einen Delegaten für IPageConvention hinzu, um Modellkonventionen hinzuzufügen, die auf Razor Pages anwendbar sind.
Hinzufügen einer Routenmodellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageRouteModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenroutenmodellen eingesetzt werden.
Die Beispielanwendung fügt dann zu allen Seiten der App eine {globalTemplate?}
-Routenvorlage hinzu:
public class GlobalTemplatePageRouteModelConvention
: IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 1,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel.Template,
"{globalTemplate?}"),
}
});
}
}
}
Die Eigenschaft Order ist für das AttributeRouteModel auf 1
festgelegt. Dadurch wird das folgende Routenabgleichsverhalten in der Beispiel-App sichergestellt:
- Eine Routenvorlage für
TheContactPage/{text?}
wird später in diesem Thema hinzugefügt. Die Standardreihenfolge der Route für die Kontaktseite lautetnull
(Order = 0
). Somit wird sie vor der Routenvorlage{globalTemplate?}
abgeglichen. - Eine Routenvorlage für
{aboutTemplate?}
wird später in diesem Thema hinzugefügt. Die Vorlage{aboutTemplate?}
erhält denOrder
von2
. Wenn die Seite „Info“ unter/About/RouteDataValue
angefordert wird, wird „RouteDataValue“ in die VorlageRouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht inRouteData.Values["aboutTemplate"]
(Order = 2
), da die EigenschaftOrder
auf null festgelegt wurde. - Eine Routenvorlage für
{otherPagesTemplate?}
wird später in diesem Thema hinzugefügt. Die Vorlage{otherPagesTemplate?}
erhält denOrder
von2
. Wenn eine Seite im Ordner Pages/OtherPages mit einem Routenparameter (z. B./OtherPages/Page1/RouteDataValue
) angefordert wird, wird „RouteDataValue“ in die VorlageRouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht inRouteData.Values["otherPagesTemplate"]
(Order = 2
), da die EigenschaftOrder
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Razor Pages-Optionen wie das Hinzufügen von Conventions werden hinzugefügt, wenn Razor Pages zur Dienstsammlung in Startup.ConfigureServices
hinzugefügt wird. In der Beispiel-App finden Sie ein Beispiel hierfür.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About/GlobalRouteValue
an, und prüfen Sie das Ergebnis:
Hinzufügen einer App-Modellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageApplicationModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenanwendungsmodellen eingesetzt werden.
Die Beispielanwendung enthält eine AddHeaderAttribute
-Klasse, damit das Verwenden dieser und anderer Konventionen weiter unten in diesem Thema gezeigt werden kann. Der Klassenkonstruktor akzeptiert eine name
-Zeichenfolge und ein values
-Zeichenfolgenarray. Diese Werte werden in seiner OnResultExecuting
-Methode verwendet, um einen Antwortheader einzurichten. Die Klasse wird im Abschnitt Seitenmodellaktionskonventionen weiter unten in diesem Artikel erläutert.
Die Beispielanwendung verwendet die Klasse AddHeaderAttribute
, um den Header GlobalHeader
zu allen Seiten der Anwendung hinzuzufügen:
public class GlobalHeaderPageApplicationModelConvention
: IPageApplicationModelConvention
{
public void Apply(PageApplicationModel model)
{
model.Filters.Add(new AddHeaderAttribute(
"GlobalHeader", new string[] { "Global Header Value" }));
}
}
Startup.cs
:
options.Conventions.Add(new GlobalHeaderPageApplicationModelConvention());
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Hinzufügen einer Handlermodellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageHandlerModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenhandlermodellen eingesetzt werden.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs
:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Konventionen für Seitenroutenaktionen
Der Standardanbieter für Routenmodelle, der von IPageRouteModelProvider abgeleitet wird, ruft Konventionen auf, die entwickelt wurden, um Erweiterungspunkte zum Konfigurieren von Seitenrouten bereitzustellen.
Ordnerroutenmodellkonvention
Verwenden Sie AddFolderRouteModelConvention zum Erstellen und Hinzuzufügen einer IPageRouteModelConvention, die eine Aktion für PageRouteModel für alle Seiten im angegebenen Ordner aufruft.
Die Beispielanwendung verwendet AddFolderRouteModelConvention, um eine {otherPagesTemplate?}
-Routenvorlage zu den Seiten im Ordner OtherPages hinzuzufügen:
options.Conventions.AddFolderRouteModelConvention("/OtherPages", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel.Template,
"{otherPagesTemplate?}"),
}
});
}
});
Die Eigenschaft Order ist für das AttributeRouteModel auf 2
festgelegt. Dadurch wird sichergestellt, dass die Vorlage für {globalTemplate?}
, die weiter oben in diesem Thema für 1
festgelegt wurde, in Bezug auf die erste Position für einen Routendatenwert vorgezogen wird, wenn nur ein einziger Routenwert angegeben wurde. Wenn eine Seite im Ordner Pages/OtherPages mit einem Routenparameterwert (z. B. /OtherPages/Page1/RouteDataValue
) angefordert wird, wird „RouteDataValue“ in die Vorlage RouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht in RouteData.Values["otherPagesTemplate"]
(Order = 2
), da die Eigenschaft Order
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Fordern Sie die Seite „Seite1“ der Beispielanwendung unter localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
an, und prüfen Sie das Ergebnis:
Seitenroutenmodellkonvention
Verwenden Sie AddPageRouteModelConvention zum Erstellen und Hinzuzufügen einer IPageRouteModelConvention, die eine Aktion für das PageRouteModel für die Seite mit dem angegebenen Namen aufruft.
Die Beispielanwendung verwendet AddPageRouteModelConvention
, um eine {aboutTemplate?}
-Routenvorlage zu der Seite „Info“ hinzuzufügen:
options.Conventions.AddPageRouteModelConvention("/About", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel.Template,
"{aboutTemplate?}"),
}
});
}
});
Die Eigenschaft Order ist für das AttributeRouteModel auf 2
festgelegt. Dadurch wird sichergestellt, dass die Vorlage für {globalTemplate?}
, die weiter oben in diesem Thema für 1
festgelegt wurde, in Bezug auf die erste Position für einen Routendatenwert vorgezogen wird, wenn nur ein einziger Routenwert angegeben wurde. Wenn die Seite „Info“ mit einem Routenparameterwert unter /About/RouteDataValue
angefordert wird, wird „RouteDataValue“ in die Vorlage RouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht in RouteData.Values["aboutTemplate"]
(Order = 2
), da die Eigenschaft Order
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About/GlobalRouteValue/AboutRouteValue
an, und prüfen Sie das Ergebnis:
Verwenden eines Parametertransformators zum Anpassen von Seitenrouten
Von ASP.NET Core generierte Seitenrouten können mit einem Parametertransformator angepasst werden. Ein Parametertransformator implementiert IOutboundParameterTransformer
und wandelt den Wert der Parameter um. Beispielsweise ändert ein benutzerdefinierter SlugifyParameterTransformer
-Parametertransformator den Routenwert SubscriptionManagement
in subscription-management
.
Mit der Seitenroutenmodellkonvention PageRouteTransformerConvention
wird ein Parametertransformator auf die Ordner- und Dateinamenssegmente von automatisch generierten Seitenrouten in einer App angewendet. Für die Seitendatei Razor unter /Pages/SubscriptionManagement/ViewAll.cshtml
wird die Route beispielsweise von /SubscriptionManagement/ViewAll
in /subscription-management/view-all
umgeschrieben.
Mit PageRouteTransformerConvention
werden nur die automatisch generierten Segmente einer Seitenroute transformiert, die aus dem Ordner- und Dateinamen von Razor Pages stammen. Mit der @page
-Anweisung hinzugefügte Routensegmente werden nicht transformiert. Auch durch AddPageRoute hinzugefügte Routen werden mit dieser Konvention nicht transformiert.
Die PageRouteTransformerConvention
wird als Option in Startup.ConfigureServices
registriert:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.Add(
new PageRouteTransformerConvention(
new SlugifyParameterTransformer()));
});
}
public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
public string TransformOutbound(object value)
{
if (value == null) { return null; }
return Regex.Replace(value.ToString(),
"([a-z])([A-Z])",
"$1-$2",
RegexOptions.CultureInvariant,
TimeSpan.FromMilliseconds(100)).ToLowerInvariant();
}
}
Warnung
Übergeben Sie ein Timeout, wenn Sie System.Text.RegularExpressions zum Verarbeiten nicht vertrauenswürdiger Eingaben verwenden. Ein böswilliger Benutzer kann Eingaben für RegularExpressions
angeben, um einen Denial-of-Service-Angriff durchzuführen. ASP.NET Core-Framework-APIs, die RegularExpressions
verwenden, übergeben ein Timeout.
Konfigurieren einer Seitenroute
Konfigurieren Sie mithilfe von AddPageRoute eine Route zu einer Seite am angegebenen Seitenpfad. Generierte Links, die auf die Seite verweisen, verwenden die von Ihnen angegebene Route. AddPageRoute
verwendet die AddPageRouteModelConvention
zum Aufbauen der Route.
Die Beispielanwendung erstellt für Contact.cshtml
eine Route zur Seite /TheContactPage
:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
Die Seite „Kontakt“ kann auch unter /Contact
über ihre Standardroute erreicht werden.
Die benutzerdefinierte Route der Beispielanwendung, die zur Seite „Kontakt“ führt, ermöglicht das Verwenden eines optionalen text
-Routensegments ({text?}
). Die Seite enthält dieses optionale Segment auch in ihrer @page
-Anweisung, für den Fall, dass der Besucher über die /Contact
-Route auf die Seite zugreift:
@page "{text?}"
@model ContactModel
@{
ViewData["Title"] = "Contact";
}
<h1>@ViewData["Title"]</h1>
<h2>@Model.Message</h2>
<address>
One Microsoft Way<br>
Redmond, WA 98052-6399<br>
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
<address>
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br>
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
</address>
<p>@Model.RouteDataTextTemplateValue</p>
Beachten Sie, dass die URL, die für den Link Kontakt in der gerenderten Seite generiert wurde, die aktualisierte Route widerspiegelt:
Sie können die Kontaktseite entweder über deren übliche Route, /Contact
, oder über die benutzerdefinierte Route, /TheContactPage
, besuchen. Wenn Sie ein zusätzliches text
-Routensegment bereitstellen, wird dieses HTML-codierte Segment auf der Seite angezeigt:
Konventionen für Seitenmodellaktionen
Der Standardanbieter für Seitenmodelle, der IPageApplicationModelProvider implementiert, ruft Konventionen auf, die entwickelt wurden, um Erweiterungspunkte zum Konfigurieren von Seitenmodellen bereitzustellen. Diese Konventionen sind beim Erstellen und Ändern von Seitenermittlungs- und Verarbeitungsszenarios hilfreich.
In den Beispielen in diesem Abschnitt verwendet die Beispielanwendung eine AddHeaderAttribute
-Klasse, also ein ResultFilterAttribute, das einen Antwortheader verwendet:
public class AddHeaderAttribute : ResultFilterAttribute
{
private readonly string _name;
private readonly string[] _values;
public AddHeaderAttribute(string name, string[] values)
{
_name = name;
_values = values;
}
public override void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(_name, _values);
base.OnResultExecuting(context);
}
}
Das Beispiel veranschaulicht mithilfe von Konventionen, wie das Attribut auf alle Seiten in einem Ordner und auf eine Einzelseite angewendet werden kann.
Ordner-App-Modellkonvention
Verwenden Sie AddFolderApplicationModelConvention zum Erstellen und Hinzuzufügen einer IPageApplicationModelConvention, die eine Aktion für PageApplicationModel-Instanzen für alle Seiten im angegebenen Ordner aufruft.
Im Beispiel wird die Verwendung der AddFolderApplicationModelConvention
durch Hinzufügen eines Headers, OtherPagesHeader
, zu den Seiten im Ordner OtherPages der Anwendung veranschaulicht:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Fordern Sie die Seite „Seite1“ der Beispielanwendung unter localhost:5000/OtherPages/Page1
an, und prüfen Sie die Header, um das Ergebnis zu sehen:
Seiten-App-Modellkonvention
Verwenden Sie AddPageApplicationModelConvention zum Erstellen und Hinzuzufügen einer IPageApplicationModelConvention, die eine Aktion für das PageApplicationModel für die Seite mit dem angegebenen Namen aufruft.
Im Beispiel wird das Verwenden von AddPageApplicationModelConvention
durch Hinzufügen eines Headers, AboutHeader
, auf der Seite „Info“ veranschaulicht:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Konfigurieren eines Filters
Der angegebene Filter, der angewendet werden soll, wird mit ConfigureFilter konfiguriert. Sie können Filterklassen selbst implementieren. In der Beispielanwendung wird jedoch gezeigt, wie Sie einen Filter in einen Lambdaausdruck implementieren. Dieser wird dann im Hintergrund als Zuordnungsinstanz implementiert, die einen Filter zurückgibt:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Das Seiten-App-Modell wird verwendet, um den relativen Pfad für Segmente zu überprüfen, die zur Seite „Seite2“ im Ordner OtherPages führen. Wenn die Bedingung erfüllt ist, wird ein Header hinzugefügt. Wenn dies nicht der Fall ist, wird der EmptyFilter
angewendet.
EmptyFilter
ist ein Aktionsfilter. Wenn der Pfad OtherPages/Page2
nicht enthält, hat der EmptyFilter
, wie vorgesehen, keine Auswirkung, da Aktionsfilter von Razor Pages ignoriert werden.
Fordern Sie die Seite „Seite2“ der Beispielanwendung unter localhost:5000/OtherPages/Page2
an, und prüfen Sie die Header, um das Ergebnis zu sehen:
Konfigurieren einer Filterzuordnungsinstanz
Mit ConfigureFilter wird die angegebene Zuordnungsinstanz so konfiguriert, dass sie Filter auf alle Razor Pages anwendet.
Die Beispielanwendung bietet Ihnen die Möglichkeit des beispielhaften Verwendens einer Filterzuordnungsinstanz durch Hinzufügen des Headers FilterFactoryHeader
zu den Seiten der Anwendung, der zwei Werte besitzt:
options.Conventions.ConfigureFilter(new AddHeaderWithFactory());
AddHeaderWithFactory.cs
:
public class AddHeaderWithFactory : IFilterFactory
{
// Implement IFilterFactory
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return new AddHeaderFilter();
}
private class AddHeaderFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(
"FilterFactoryHeader",
new string[]
{
"Filter Factory Header Value 1",
"Filter Factory Header Value 2"
});
}
public void OnResultExecuted(ResultExecutedContext context)
{
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Die MVC-Filter und der Seitenfilter (IPageFilter)
MVC-Aktionsfilter werden von Razor Pages ignoriert, da Razor Pages Handlermethoden verwenden. Darüber hinaus stehen die folgenden MVC-Filtertypen zur Verfügung: Autorisierung, Ausnahme, Ressource und Ergebnis. Weitere Informationen finden Sie im Thema Filter.
Der Seitenfilter (IPageFilter) ist ein Filter, der auf Razor Pages anwendbar ist. Weitere Informationen finden Sie unter Filtermethoden für Razor Pages.
Zusätzliche Ressourcen
Erfahren Sie, wie Sie in Apps für Razor Pages mithilfe von Konventionen für Seitenrouten und App-Modellanbieter das Seitenrouting, die Ermittlung und die Verarbeitung steuern können.
Wenn Sie für einzelne Seiten benutzerdefinierte Seitenrouten konfigurieren müssen, sollten Sie das Routing zu den Seiten mithilfe der AddPageRoute-Konvention konfigurieren, die weiter unten in diesem Artikel beschrieben wird.
Um eine Seitenroute anzugeben oder einer Route Segmente oder Parameter hinzuzufügen, verwenden Sie die Anweisung @page
der Seite. Weitere Informationen finden Sie unter Benutzerdefinierte Routen.
Es gibt reservierte Wörter, die nicht als Routensegmente oder Parameternamen verwendet werden können. Weitere Informationen finden Sie unter Routing: Reservierte Routingnamen.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Szenario | Dieses Beispiel veranschaulicht Folgendes: |
---|---|
Model conventions (Modellkonventionen) Conventions.Add
|
Das Hinzufügen einer Routenvorlage und eines Headers zu den Seiten einer App |
Konventionen für Seitenroutenaktionen
|
Das Hinzufügen einer Routenvorlage zu Seiten in einem Ordner und zu einer Einzelseite |
Konventionen für Seitenmodellaktionen
|
Das Hinzufügen eines Headers zu Seiten in einem Ordner, das Hinzufügen eines Headers zu einer einzelnen Seite und das Konfigurieren einer Filter-Factoy zum Hinzufügen eines Headers zu den Seiten einer App. |
Konventionen für Razor Pages werden AddMvc mithilfe der Erweiterungsmethode AddRazorPagesOptions unter der Dienstklasse in der Klasse Startup
hinzugefügt. Die folgenden Beispiele der Konvention werden später in diesem Thema erläutert:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.Add( ... );
options.Conventions.AddFolderRouteModelConvention(
"/OtherPages", model => { ... });
options.Conventions.AddPageRouteModelConvention(
"/About", model => { ... });
options.Conventions.AddPageRoute(
"/Contact", "TheContactPage/{text?}");
options.Conventions.AddFolderApplicationModelConvention(
"/OtherPages", model => { ... });
options.Conventions.AddPageApplicationModelConvention(
"/About", model => { ... });
options.Conventions.ConfigureFilter(model => { ... });
options.Conventions.ConfigureFilter( ... );
});
}
Routenreihenfolge
Routen geben eine Order für die Verarbeitung an (Routenabgleich).
Auftrag | Verhalten |
---|---|
-1 | Die Route wird vor anderen Routen verarbeitet. |
0 | Die Reihenfolge wurde nicht angegeben (Standardwert). Wenn Sie Order (Order = null ) nicht zuweisen, wird für die Verarbeitung der Route Order standardmäßig auf 0 (null) gesetzt. |
1, 2, … n | Gibt die Verarbeitungsreihenfolge für die Route an. |
Die Routenverarbeitung wird gemäß der Konvention eingerichtet:
- Routen werden in sequenzieller Reihenfolge verarbeitet (-1, 0, 1, 2, ... n).
- Wenn Routen dieselbe
Order
aufweisen, wird zuerst die spezifischste Route abgeglichen, danach folgen die weniger spezifischen Routen. - Wenn Routen mit derselben
Order
und derselben Anzahl Parameter mit einer Anforderungs-URL übereinstimmen, werden Routen in der Reihenfolge verarbeitet, in der sie der PageConventionCollection hinzugefügt wurden.
Vermeiden Sie nach Möglichkeit die Abhängigkeit von einer festgelegten Verarbeitungsreihenfolge für Routen. Im Allgemeinen wird beim Routing die richtige Route mittels URL-Zuordnung ausgewählt. Wenn Sie zum ordnungsgemäßen Weiterleiten von Anforderungen für die Route Order
-Eigenschaften festlegen müssen, ist das Routingschema der App für Clients wahrscheinlich irreführend und in Bezug auf die Verwaltung störanfälliger. Versuchen Sie daher, das Routingschema der App zu vereinfachen. Bei der Beispiel-App ist eine explizite Verarbeitungsreihenfolge für Routen erforderlich, um mit einer einzigen App verschiedene Routingszenarios veranschaulichen zu können. In Produktions-Apps sollten Sie jedoch nach Möglichkeit eine Festlegung von Order
für Routen vermeiden.
Razor Pages-Routing und MVC Controller-Routing verwenden eine gemeinsame Implementierung. Informationen zur Reihenfolge von Routen in den MVC-Themen finden Sie unter Routing zu Controlleraktionen: Ordnen der Attributrouten.
Modellkonventionen
Fügen Sie einen Delegaten für IPageConvention hinzu, um Modellkonventionen hinzuzufügen, die auf Razor Pages anwendbar sind.
Hinzufügen einer Routenmodellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageRouteModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenroutenmodellen eingesetzt werden.
Die Beispielanwendung fügt dann zu allen Seiten der App eine {globalTemplate?}
-Routenvorlage hinzu:
public class GlobalTemplatePageRouteModelConvention
: IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 1,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel.Template,
"{globalTemplate?}"),
}
});
}
}
}
Die Eigenschaft Order ist für das AttributeRouteModel auf 1
festgelegt. Dadurch wird das folgende Routenabgleichsverhalten in der Beispiel-App sichergestellt:
- Eine Routenvorlage für
TheContactPage/{text?}
wird später in diesem Thema hinzugefügt. Die Standardreihenfolge der Route für die Kontaktseite lautetnull
(Order = 0
). Somit wird sie vor der Routenvorlage{globalTemplate?}
abgeglichen. - Eine Routenvorlage für
{aboutTemplate?}
wird später in diesem Thema hinzugefügt. Die Vorlage{aboutTemplate?}
erhält denOrder
von2
. Wenn die Seite „Info“ unter/About/RouteDataValue
angefordert wird, wird „RouteDataValue“ in die VorlageRouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht inRouteData.Values["aboutTemplate"]
(Order = 2
), da die EigenschaftOrder
auf null festgelegt wurde. - Eine Routenvorlage für
{otherPagesTemplate?}
wird später in diesem Thema hinzugefügt. Die Vorlage{otherPagesTemplate?}
erhält denOrder
von2
. Wenn eine Seite im Ordner Pages/OtherPages mit einem Routenparameter (z. B./OtherPages/Page1/RouteDataValue
) angefordert wird, wird „RouteDataValue“ in die VorlageRouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht inRouteData.Values["otherPagesTemplate"]
(Order = 2
), da die EigenschaftOrder
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Optionen für Razor Pages, z. B. das Hinzufügen von Conventions, werden hinzugefügt, wenn MVC der Dienstauflistung in Startup.ConfigureServices
hinzugefügt wird. In der Beispiel-App finden Sie ein Beispiel hierfür.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About/GlobalRouteValue
an, und prüfen Sie das Ergebnis:
Hinzufügen einer App-Modellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageApplicationModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenanwendungsmodellen eingesetzt werden.
Die Beispielanwendung enthält eine AddHeaderAttribute
-Klasse, damit das Verwenden dieser und anderer Konventionen weiter unten in diesem Thema gezeigt werden kann. Der Klassenkonstruktor akzeptiert eine name
-Zeichenfolge und ein values
-Zeichenfolgenarray. Diese Werte werden in seiner OnResultExecuting
-Methode verwendet, um einen Antwortheader einzurichten. Die Klasse wird im Abschnitt Seitenmodellaktionskonventionen weiter unten in diesem Artikel erläutert.
Die Beispielanwendung verwendet die Klasse AddHeaderAttribute
, um den Header GlobalHeader
zu allen Seiten der Anwendung hinzuzufügen:
public class GlobalHeaderPageApplicationModelConvention
: IPageApplicationModelConvention
{
public void Apply(PageApplicationModel model)
{
model.Filters.Add(new AddHeaderAttribute(
"GlobalHeader", new string[] { "Global Header Value" }));
}
}
Startup.cs
:
options.Conventions.Add(new GlobalHeaderPageApplicationModelConvention());
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Hinzufügen einer Handlermodellkonvention zu allen Seiten
Verwenden Sie Conventions zum Erstellen und Hinzufügen einer IPageHandlerModelConvention zur Auflistung der Instanzen von IPageConvention, die während der Erstellung von Seitenhandlermodellen eingesetzt werden.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs
:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Konventionen für Seitenroutenaktionen
Der Standardanbieter für Routenmodelle, der von IPageRouteModelProvider abgeleitet wird, ruft Konventionen auf, die entwickelt wurden, um Erweiterungspunkte zum Konfigurieren von Seitenrouten bereitzustellen.
Ordnerroutenmodellkonvention
Verwenden Sie AddFolderRouteModelConvention zum Erstellen und Hinzuzufügen einer IPageRouteModelConvention, die eine Aktion für PageRouteModel für alle Seiten im angegebenen Ordner aufruft.
Die Beispielanwendung verwendet AddFolderRouteModelConvention, um eine {otherPagesTemplate?}
-Routenvorlage zu den Seiten im Ordner OtherPages hinzuzufügen:
options.Conventions.AddFolderRouteModelConvention("/OtherPages", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel.Template,
"{otherPagesTemplate?}"),
}
});
}
});
Die Eigenschaft Order ist für das AttributeRouteModel auf 2
festgelegt. Dadurch wird sichergestellt, dass die Vorlage für {globalTemplate?}
, die weiter oben in diesem Thema für 1
festgelegt wurde, in Bezug auf die erste Position für einen Routendatenwert vorgezogen wird, wenn nur ein einziger Routenwert angegeben wurde. Wenn eine Seite im Ordner Pages/OtherPages mit einem Routenparameterwert (z. B. /OtherPages/Page1/RouteDataValue
) angefordert wird, wird „RouteDataValue“ in die Vorlage RouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht in RouteData.Values["otherPagesTemplate"]
(Order = 2
), da die Eigenschaft Order
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Fordern Sie die Seite „Seite1“ der Beispielanwendung unter localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
an, und prüfen Sie das Ergebnis:
Seitenroutenmodellkonvention
Verwenden Sie AddPageRouteModelConvention zum Erstellen und Hinzuzufügen einer IPageRouteModelConvention, die eine Aktion für das PageRouteModel für die Seite mit dem angegebenen Namen aufruft.
Die Beispielanwendung verwendet AddPageRouteModelConvention
, um eine {aboutTemplate?}
-Routenvorlage zu der Seite „Info“ hinzuzufügen:
options.Conventions.AddPageRouteModelConvention("/About", model =>
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = 2,
Template = AttributeRouteModel.CombineTemplates(
selector.AttributeRouteModel.Template,
"{aboutTemplate?}"),
}
});
}
});
Die Eigenschaft Order ist für das AttributeRouteModel auf 2
festgelegt. Dadurch wird sichergestellt, dass die Vorlage für {globalTemplate?}
, die weiter oben in diesem Thema für 1
festgelegt wurde, in Bezug auf die erste Position für einen Routendatenwert vorgezogen wird, wenn nur ein einziger Routenwert angegeben wurde. Wenn die Seite „Info“ mit einem Routenparameterwert unter /About/RouteDataValue
angefordert wird, wird „RouteDataValue“ in die Vorlage RouteData.Values["globalTemplate"]
geladen (Order = 1
) und nicht in RouteData.Values["aboutTemplate"]
(Order = 2
), da die Eigenschaft Order
auf null festgelegt wurde.
Legen Sie die Order
möglichst nicht fest, sodass Order = 0
gilt. Verlassen Sie sich bei der Auswahl der richtigen Route auf die Routenplanung.
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About/GlobalRouteValue/AboutRouteValue
an, und prüfen Sie das Ergebnis:
Konfigurieren einer Seitenroute
Konfigurieren Sie mithilfe von AddPageRoute eine Route zu einer Seite am angegebenen Seitenpfad. Generierte Links, die auf die Seite verweisen, verwenden die von Ihnen angegebene Route. AddPageRoute
verwendet die AddPageRouteModelConvention
zum Aufbauen der Route.
Die Beispielanwendung erstellt für Contact.cshtml
eine Route zur Seite /TheContactPage
:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
Die Seite „Kontakt“ kann auch unter /Contact
über ihre Standardroute erreicht werden.
Die benutzerdefinierte Route der Beispielanwendung, die zur Seite „Kontakt“ führt, ermöglicht das Verwenden eines optionalen text
-Routensegments ({text?}
). Die Seite enthält dieses optionale Segment auch in ihrer @page
-Anweisung, für den Fall, dass der Besucher über die /Contact
-Route auf die Seite zugreift:
@page "{text?}"
@model ContactModel
@{
ViewData["Title"] = "Contact";
}
<h1>@ViewData["Title"]</h1>
<h2>@Model.Message</h2>
<address>
One Microsoft Way<br>
Redmond, WA 98052-6399<br>
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
<address>
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br>
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
</address>
<p>@Model.RouteDataTextTemplateValue</p>
Beachten Sie, dass die URL, die für den Link Kontakt in der gerenderten Seite generiert wurde, die aktualisierte Route widerspiegelt:
Sie können die Kontaktseite entweder über deren übliche Route, /Contact
, oder über die benutzerdefinierte Route, /TheContactPage
, besuchen. Wenn Sie ein zusätzliches text
-Routensegment bereitstellen, wird dieses HTML-codierte Segment auf der Seite angezeigt:
Konventionen für Seitenmodellaktionen
Der Standardanbieter für Seitenmodelle, der IPageApplicationModelProvider implementiert, ruft Konventionen auf, die entwickelt wurden, um Erweiterungspunkte zum Konfigurieren von Seitenmodellen bereitzustellen. Diese Konventionen sind beim Erstellen und Ändern von Seitenermittlungs- und Verarbeitungsszenarios hilfreich.
In den Beispielen in diesem Abschnitt verwendet die Beispielanwendung eine AddHeaderAttribute
-Klasse, also ein ResultFilterAttribute, das einen Antwortheader verwendet:
public class AddHeaderAttribute : ResultFilterAttribute
{
private readonly string _name;
private readonly string[] _values;
public AddHeaderAttribute(string name, string[] values)
{
_name = name;
_values = values;
}
public override void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(_name, _values);
base.OnResultExecuting(context);
}
}
Das Beispiel veranschaulicht mithilfe von Konventionen, wie das Attribut auf alle Seiten in einem Ordner und auf eine Einzelseite angewendet werden kann.
Ordner-App-Modellkonvention
Verwenden Sie AddFolderApplicationModelConvention zum Erstellen und Hinzuzufügen einer IPageApplicationModelConvention, die eine Aktion für PageApplicationModel-Instanzen für alle Seiten im angegebenen Ordner aufruft.
Im Beispiel wird die Verwendung der AddFolderApplicationModelConvention
durch Hinzufügen eines Headers, OtherPagesHeader
, zu den Seiten im Ordner OtherPages der Anwendung veranschaulicht:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Fordern Sie die Seite „Seite1“ der Beispielanwendung unter localhost:5000/OtherPages/Page1
an, und prüfen Sie die Header, um das Ergebnis zu sehen:
Seiten-App-Modellkonvention
Verwenden Sie AddPageApplicationModelConvention zum Erstellen und Hinzuzufügen einer IPageApplicationModelConvention, die eine Aktion für das PageApplicationModel für die Seite mit dem angegebenen Namen aufruft.
Im Beispiel wird das Verwenden von AddPageApplicationModelConvention
durch Hinzufügen eines Headers, AboutHeader
, auf der Seite „Info“ veranschaulicht:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Konfigurieren eines Filters
Der angegebene Filter, der angewendet werden soll, wird mit ConfigureFilter konfiguriert. Sie können Filterklassen selbst implementieren. In der Beispielanwendung wird jedoch gezeigt, wie Sie einen Filter in einen Lambdaausdruck implementieren. Dieser wird dann im Hintergrund als Zuordnungsinstanz implementiert, die einen Filter zurückgibt:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Das Seiten-App-Modell wird verwendet, um den relativen Pfad für Segmente zu überprüfen, die zur Seite „Seite2“ im Ordner OtherPages führen. Wenn die Bedingung erfüllt ist, wird ein Header hinzugefügt. Wenn dies nicht der Fall ist, wird der EmptyFilter
angewendet.
EmptyFilter
ist ein Aktionsfilter. Wenn der Pfad OtherPages/Page2
nicht enthält, hat der EmptyFilter
, wie vorgesehen, keine Auswirkung, da Aktionsfilter von Razor Pages ignoriert werden.
Fordern Sie die Seite „Seite2“ der Beispielanwendung unter localhost:5000/OtherPages/Page2
an, und prüfen Sie die Header, um das Ergebnis zu sehen:
Konfigurieren einer Filterzuordnungsinstanz
Mit ConfigureFilter wird die angegebene Zuordnungsinstanz so konfiguriert, dass sie Filter auf alle Razor Pages anwendet.
Die Beispielanwendung bietet Ihnen die Möglichkeit des beispielhaften Verwendens einer Filterzuordnungsinstanz durch Hinzufügen des Headers FilterFactoryHeader
zu den Seiten der Anwendung, der zwei Werte besitzt:
options.Conventions.ConfigureFilter(new AddHeaderWithFactory());
AddHeaderWithFactory.cs
:
public class AddHeaderWithFactory : IFilterFactory
{
// Implement IFilterFactory
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return new AddHeaderFilter();
}
private class AddHeaderFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(
"FilterFactoryHeader",
new string[]
{
"Filter Factory Header Value 1",
"Filter Factory Header Value 2"
});
}
public void OnResultExecuted(ResultExecutedContext context)
{
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Fordern Sie die Seite „Info“ der Beispielanwendung unter localhost:5000/About
an, und überprüfen Sie die Header, um das Ergebnis zu sehen:
Die MVC-Filter und der Seitenfilter (IPageFilter)
MVC-Aktionsfilter werden von Razor Pages ignoriert, da Razor Pages Handlermethoden verwenden. Darüber hinaus stehen die folgenden MVC-Filtertypen zur Verfügung: Autorisierung, Ausnahme, Ressource und Ergebnis. Weitere Informationen finden Sie im Thema Filter.
Der Seitenfilter (IPageFilter) ist ein Filter, der auf Razor Pages anwendbar ist. Weitere Informationen finden Sie unter Filtermethoden für Razor Pages.