Razor Convenzioni di route e app di pagine in ASP.NET Core
Informazioni su come usare le convenzioni di routing di pagine e provider di modelli di app per controllare il routing, l'individuazione e l'elaborazione delle pagine nelle Razor app Pages.
Per specificare una route di pagina, aggiungere segmenti di route o aggiungere parametri a una route, usare la direttiva della @page
pagina. Per altre informazioni, vedere Route personalizzate.
Esistono parole riservate che non possono essere usate come segmenti di route o nomi di parametri. Per altre informazioni, vedere Routing: Nomi di routing riservati.
Visualizzare o scaricare il codice di esempio (procedura per il download)
Scenario | L'esempio illustra |
---|---|
Convenzioni del modello Conventions.Add |
Aggiungere un modello e un'intestazione di route alle pagine di un'app. |
Convenzioni per le azioni di route di pagina | Aggiungere un modello di route alle pagine in una cartella e a una pagina singola. |
Convenzioni per le azioni del modello di pagina
|
Aggiungere un'intestazione alle pagine in una cartella, aggiungere un'intestazione a una pagina singola e configurare una factory di filtro per aggiungere un'intestazione alle pagine di un'app. |
Razor Le convenzioni di pagine vengono configurate usando un AddRazorPages overload che configura RazorPagesOptions. Gli esempi di convenzione seguenti sono illustrati più avanti in questo argomento:
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( ... );
});
}
Ordine di route
Le route specificano un oggetto per l'elaborazione Order (corrispondenza della route).
Ordine di route | Comportamento |
---|---|
-1 | La route viene elaborata prima dell'elaborazione di altre route. |
0 | L'ordine non è specificato (valore predefinito). Non assegnando Order (Order = null ) per impostazione predefinita la route Order a 0 (zero) per l'elaborazione. |
1, 2, … n | Specifica l'ordine di elaborazione della route. |
L'elaborazione della route viene stabilita per convenzione:
- Le route vengono elaborate in ordine sequenziale (-1, 0, 1, 2, ... n).
- Quando le route hanno lo stesso
Order
, la route più specifica viene trovata prima seguita da route meno specifiche. - Quando le route con lo stesso e lo stesso
Order
numero di parametri corrispondono a un URL di richiesta, le route vengono elaborate nell'ordine in cui vengono aggiunte a PageConventionCollection.
Se possibile, evitare di dipendere da un ordine di elaborazione della route stabilito. In genere, il routing seleziona la route corretta con la corrispondenza dell'URL. Se devi impostare le proprietà della route Order
per instradare correttamente le richieste, lo schema di routing dell'app probabilmente crea confusione per i client e fragile da gestire. Cercare di semplificare lo schema di routing dell'app. L'app di esempio richiede un ordine di elaborazione della route esplicito per illustrare diversi scenari di routing usando una singola app. Tuttavia, è consigliabile tentare di evitare la procedura di impostazione della route Order
nelle app di produzione.
Razor Il routing delle pagine e il routing del controller MVC condividono un'implementazione. Le informazioni sull'ordine di route negli argomenti MVC sono disponibili in Routing alle azioni del controller: Ordinamento delle route degli attributi.
Convenzioni del modello
Aggiungere un delegato per IPageConvention per aggiungere convenzioni di modello applicabili alle Razor pagine.
Aggiungere una convenzione del modello di route a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageRouteModelConvention alla raccolta di istanze applicate durante la costruzione del modello di IPageConvention route di pagina.
L'app di esempio contiene la GlobalTemplatePageRouteModelConvention
classe per aggiungere un {globalTemplate?}
modello di route a tutte le pagine dell'app:
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?}"),
}
});
}
}
}
Nel codice precedente:
- L'oggetto PageRouteModel viene passato al Apply metodo .
- PageRouteModel.Selectors ottiene il conteggio dei selettori.
- Viene aggiunto un nuovo SelectorModel oggetto che contiene un AttributeRouteModel
Razor Le opzioni pagine, ad esempio l'aggiunta Conventionsdi , vengono aggiunte quando Razor pagine vengono aggiunte alla raccolta di servizi. Per un esempio completo, vedere l'app di esempio.
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();
Si consideri la GlobalTemplatePageRouteModelConvention
classe :
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?}"),
}
});
}
}
}
La proprietà Order per AttributeRouteModel è impostata su 1
. Ciò garantisce il comportamento di corrispondenza della route seguente nell'app di esempio:
Un modello di route per
TheContactPage/{text?}
viene aggiunto più avanti in questo argomento. LaContact Page
route ha un ordine predefinito di (Order = 0
), quindi corrisponde prima del{globalTemplate?}
modello dinull
route conOrder = 1
.Il
{aboutTemplate?}
modello di route viene visualizzato nel codice precedente. Al modello{aboutTemplate?}
viene assegnato unOrder
di2
. Quando viene richiesta la pagina di informazioni in/About/RouteDataValue
, "RouteDataValue" viene caricato inRouteData.Values["globalTemplate"]
(Order = 1
) e non inRouteData.Values["aboutTemplate"]
(Order = 2
) a causa dell'impostazione della proprietàOrder
.Il
{otherPagesTemplate?}
modello di route viene visualizzato nel codice precedente. Al modello{otherPagesTemplate?}
viene assegnato unOrder
di2
. Quando viene richiesta una pagina nella cartella Pages/OtherPages con un parametro di route:Ad esempio, usare
/OtherPages/Page1/xyz
Il valore
"xyz"
dei dati della route viene caricato inRouteData.Values["globalTemplate"]
(Order = 1
).RouteData.Values["otherPagesTemplate"]
con (Order = 2
) non viene caricato a causa dellaOrder
proprietà2
con un valore superiore.
Quando possibile, non impostare .Order
Se Order
non è impostato, per impostazione predefinita viene impostato su Order = 0
. Fare affidamento sul routing per selezionare la route corretta anziché la Order
proprietà .
Richiedere la pagina dell'esempio About
in localhost:{port}/About/GlobalRouteValue
e controllare il risultato:
L'app di esempio usa il pacchetto NuGet Rick.Docs.Samples.RouteInfo per visualizzare le informazioni di routing nell'output di registrazione. Usando localhost:{port}/About/GlobalRouteValue
, il logger visualizza la richiesta, l'oggetto Order
e il modello usato:
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue Order = 1 Template = About/{globalTemplate?}
Aggiungere una convenzione del modello di app a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageApplicationModelConvention alla raccolta di istanze applicate durante la costruzione del modello di IPageConvention app di pagina.
Per dimostrare questa e altre convenzioni più avanti in questo argomento, l'app di esempio include una classe AddHeaderAttribute
. Il costruttore della classe accetta una stringa name
e una matrice di stringhe values
. Questi valori vengono usati nel relativo metodo OnResultExecuting
per impostare un'intestazione di risposta. La classe completa è illustrata nella sezione Convenzioni per le azioni del modello di pagina più avanti in questo argomento.
L'app di esempio usa la classe AddHeaderAttribute
per aggiungere un'intestazione, GlobalHeader
, a tutte le pagine nell'app:
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());
Richiedere la pagina di informazioni dell'esempio in localhost:{port}/About
ed esaminare le intestazioni per visualizzare il risultato:
Aggiungere una convenzione del modello di gestore a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageHandlerModelConvention alla raccolta di istanze applicate durante la costruzione del modello del gestore di IPageConvention pagine.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Convenzioni per le azioni di route di pagina
Il provider di modelli di route predefinito che deriva da IPageRouteModelProvider richiama convenzioni progettate per fornire punti di estendibilità per la configurazione delle route di pagina.
Convenzione per il modello di route cartella
Utilizzare AddFolderRouteModelConvention per creare e aggiungere un oggetto IPageRouteModelConvention che richiama un'azione su PageRouteModel per tutte le pagine nella cartella specificata.
L'app di esempio usa AddFolderRouteModelConvention per aggiungere un modello di route {otherPagesTemplate?}
alle pagine nella cartella OtherPages:
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?}"),
}
});
}
});
La proprietà Order per AttributeRouteModel è impostata su 2
. In questo modo, il modello per {globalTemplate?}
(impostato in precedenza nell'argomento su 1
) ha la priorità per la prima posizione del valore dei dati di route quando viene specificato un singolo valore di route. Se viene richiesta una pagina nella cartella Pages/OtherPages con un valore di parametro di route ,ad esempio /OtherPages/Page1/RouteDataValue
, "RouteDataValue" viene caricato in RouteData.Values["globalTemplate"]
(Order = 1
) e non RouteData.Values["otherPagesTemplate"]
(Order = 2
) a causa dell'impostazione della Order
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Richiedere la pagina Page1 dell'esempio in localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
ed esaminare il risultato:
Convenzione per il modello di route pagina
Utilizzare AddPageRouteModelConvention per creare e aggiungere un oggetto IPageRouteModelConvention che richiama un'azione nella PageRouteModel per la pagina con il nome specificato.
L'app di esempio usa AddPageRouteModelConvention
per aggiungere un modello di route {aboutTemplate?}
alla pagina di informazioni:
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?}"),
}
});
}
});
La proprietà Order per AttributeRouteModel è impostata su 2
. In questo modo, il modello per {globalTemplate?}
(impostato in precedenza nell'argomento su 1
) ha la priorità per la prima posizione del valore dei dati di route quando viene specificato un singolo valore di route. Se la pagina Informazioni su viene richiesta con un valore del parametro di route in /About/RouteDataValue
, "RouteDataValue" viene caricata in RouteData.Values["globalTemplate"]
(Order = 1
) e non RouteData.Values["aboutTemplate"]
(Order = 2
) a causa dell'impostazione della Order
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Richiedere la pagina di informazioni dell'esempio in localhost:{port}/About/GlobalRouteValue/AboutRouteValue
ed esaminare il risultato:
L'output del logger visualizza:
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue/AboutRouteValue Order = 2 Template = About/{globalTemplate?}/{aboutTemplate?}
Usare un trasformatore di parametro per personalizzare le route di pagina
Vedere Trasformatori di parametri.
Configurare una route di pagina
Usare AddPageRoute per configurare una route a una pagina nel percorso di pagina specificato. I collegamenti generati alla pagina usano la route specificata. AddPageRoute usa AddPageRouteModelConvention per stabilire la route.
L'app di esempio crea una route a /TheContactPage
per la Contact
Razor pagina:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
È anche possibile raggiungere la Contact
pagina all'indirizzo /
Contact1' tramite la route predefinita.
La route personalizzata dell'app di esempio alla Contact
pagina consente un segmento di route facoltativo text
({text?}
). La pagina include anche tale segmento facoltativo nella relativa istruzione @page
nel caso in cui il visitatore acceda alla pagina in corrispondenza della relativa route /Contact
:
@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>
Si noti che l'URL generato per il collegamento Contatto nella pagina sottoposta a rendering riflette la route aggiornata:
Visitare la Contact
pagina in corrispondenza del percorso ordinario, /Contact
o della route personalizzata. /TheContactPage
Se si specifica un segmento di route text
aggiuntivo, la pagina visualizza il segmento codificato in formato HTML specificato dall'utente:
Convenzioni per le azioni del modello di pagina
Il provider di modelli di pagina predefinito che implementa IPageApplicationModelProvider richiama convenzioni progettate per fornire punti di estendibilità per la configurazione dei modelli di pagina. Queste convenzioni sono utili durante la compilazione e la modifica degli scenari di individuazione ed elaborazione delle pagine.
Per gli esempi in questa sezione, l'app di esempio usa una AddHeaderAttribute
classe , ovvero , ResultFilterAttributeche applica un'intestazione di risposta:
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);
}
}
Tramite le convenzioni, nell'esempio viene illustrato come applicare l'attributo a tutte le pagine in una cartella e a una singola pagina.
Convenzione per il modello di app cartella
Usare AddFolderApplicationModelConvention per creare e aggiungere un oggetto IPageApplicationModelConvention che richiama un'azione sulle PageApplicationModel istanze di per tutte le pagine nella cartella specificata.
Nell'esempio viene illustrato l'uso di AddFolderApplicationModelConvention
aggiungendo un'intestazione, OtherPagesHeader
, alle pagine all'interno della cartella OtherPages dell'app:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Richiedere la pagina Page1 dell'esempio in localhost:5000/OtherPages/Page1
ed esaminare le intestazioni per visualizzare il risultato:
Convenzione per il modello di app cartella
Utilizzare AddPageApplicationModelConvention per creare e aggiungere un oggetto IPageApplicationModelConvention che richiama un'azione nella PageApplicationModel per la pagina con il nome specificato.
Nell'esempio viene illustrato l'uso di AddPageApplicationModelConvention
aggiungendo un'intestazione, AboutHeader
, alla pagina di informazioni:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Configurare un filtro
ConfigureFilter configura il filtro specificato da applicare. È possibile implementare una classe di filtro, ma l'app di esempio illustra come implementare un filtro in un'espressione lambda, che viene implementata in background come una factory che restituisce un filtro:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Viene usato il modello di app della pagina per verificare il percorso relativo per i segmenti che portano alla pagina Page2 nella cartella OtherPages. Se la condizione viene superata, viene aggiunta un'intestazione. In caso contrario, viene applicato EmptyFilter
.
EmptyFilter
è un filtro azione. Poiché i filtri azione vengono ignorati da Razor Pages, l'oggetto EmptyFilter
non ha alcun effetto come previsto se il percorso non contiene OtherPages/Page2
.
Richiedere la pagina Page2 dell'esempio in localhost:5000/OtherPages/Page2
ed esaminare le intestazioni per visualizzare il risultato:
Configurare una factory di filtro
ConfigureFilter configura la factory specificata per applicare filtri a tutte le Razor pagine.
L'app di esempio illustra un esempio dell'uso di una factory di filtro aggiungendo un'intestazione, FilterFactoryHeader
, con due valori per le pagine dell'app:
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;
}
}
}
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Filtri MVC e il filtro di pagina (IPageFilter)
I filtri azione MVC vengono ignorati da Razor Pages, perché Razor Pages usa metodi del gestore. Sono disponibili altri tipi di filtri MVC: autorizzazione, eccezione, risorse e risultati. Per altre informazioni, vedere l'argomento Filtri.
Il filtro Pagina (IPageFilter) è un filtro che si applica alle Razor pagine. Per altre informazioni, vedere Metodi di filtro per Razor Pagine.
Risorse aggiuntive
Informazioni su come usare le convenzioni di routing di pagine e provider di modelli di app per controllare il routing, l'individuazione e l'elaborazione delle pagine nelle Razor app Pages.
Quando è necessario configurare la route di una pagina personalizzata per le singole pagine, configurare il routing alle pagine con la convenzione AddPageRoute descritta più avanti in questo argomento.
Per specificare una route di pagina, aggiungere segmenti di route o aggiungere parametri a una route, usare la direttiva della @page
pagina. Per altre informazioni, vedere Route personalizzate.
Esistono parole riservate che non possono essere usate come segmenti di route o nomi di parametri. Per altre informazioni, vedere Routing: Nomi di routing riservati.
Visualizzare o scaricare il codice di esempio (procedura per il download)
Scenario | L'esempio illustra come eseguire le seguenti operazioni: |
---|---|
Convenzioni del modello Conventions.Add
|
Aggiungere un modello e un'intestazione di route alle pagine di un'app. |
Convenzioni per le azioni di route di pagina
|
Aggiungere un modello di route alle pagine in una cartella e a una pagina singola. |
Convenzioni per le azioni del modello di pagina
|
Aggiungere un'intestazione alle pagine in una cartella, aggiungere un'intestazione a una pagina singola e configurare una factory di filtro per aggiungere un'intestazione alle pagine di un'app. |
Razor Le convenzioni di pagine vengono configurate usando un AddRazorPages overload che configura RazorPagesOptions in Startup.ConfigureServices
. Gli esempi di convenzione seguenti sono illustrati più avanti in questo argomento:
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( ... );
});
}
Ordine di route
Le route specificano un oggetto per l'elaborazione Order (corrispondenza della route).
Ordine | Comportamento |
---|---|
-1 | La route viene elaborata prima dell'elaborazione di altre route. |
0 | L'ordine non è specificato (valore predefinito). Non assegnando Order (Order = null ) per impostazione predefinita la route Order a 0 (zero) per l'elaborazione. |
1, 2, … n | Specifica l'ordine di elaborazione della route. |
L'elaborazione della route viene stabilita per convenzione:
- Le route vengono elaborate in ordine sequenziale (-1, 0, 1, 2, ... n).
- Quando le route hanno lo stesso
Order
, la route più specifica viene trovata prima seguita da route meno specifiche. - Quando le route con lo stesso e lo stesso
Order
numero di parametri corrispondono a un URL di richiesta, le route vengono elaborate nell'ordine in cui vengono aggiunte a PageConventionCollection.
Se possibile, evitare di dipendere da un ordine di elaborazione della route stabilito. In genere, il routing seleziona la route corretta con la corrispondenza dell'URL. Se devi impostare le proprietà della route Order
per instradare correttamente le richieste, lo schema di routing dell'app probabilmente crea confusione per i client e fragile da gestire. Cercare di semplificare lo schema di routing dell'app. L'app di esempio richiede un ordine di elaborazione della route esplicito per illustrare diversi scenari di routing usando una singola app. Tuttavia, è consigliabile tentare di evitare la procedura di impostazione della route Order
nelle app di produzione.
Razor Il routing delle pagine e il routing del controller MVC condividono un'implementazione. Le informazioni sull'ordine di route negli argomenti MVC sono disponibili in Routing alle azioni del controller: Ordinamento delle route degli attributi.
Convenzioni del modello
Aggiungere un delegato per IPageConvention per aggiungere convenzioni di modello applicabili alle Razor pagine.
Aggiungere una convenzione del modello di route a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageRouteModelConvention alla raccolta di istanze applicate durante la costruzione del modello di IPageConvention route di pagina.
L'app di esempio aggiunge un modello di route {globalTemplate?}
a tutte le pagine nell'app:
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?}"),
}
});
}
}
}
La proprietà Order per AttributeRouteModel è impostata su 1
. Ciò garantisce il comportamento di corrispondenza della route seguente nell'app di esempio:
- Un modello di route per
TheContactPage/{text?}
viene aggiunto più avanti nell'argomento. La route della pagina contatto ha un ordine predefinito (null
Order = 0
), quindi corrisponde prima del{globalTemplate?}
modello di route. - Un
{aboutTemplate?}
modello di route viene aggiunto più avanti nell'argomento. Al modello{aboutTemplate?}
viene assegnato unOrder
di2
. Quando viene richiesta la pagina di informazioni in/About/RouteDataValue
, "RouteDataValue" viene caricato inRouteData.Values["globalTemplate"]
(Order = 1
) e non inRouteData.Values["aboutTemplate"]
(Order = 2
) a causa dell'impostazione della proprietàOrder
. - Un
{otherPagesTemplate?}
modello di route viene aggiunto più avanti nell'argomento. Al modello{otherPagesTemplate?}
viene assegnato unOrder
di2
. Quando viene richiesta una pagina nella cartella Pages/OtherPages con un parametro di route (ad esempio,/OtherPages/Page1/RouteDataValue
), "RouteDataValue" viene caricato inRouteData.Values["globalTemplate"]
(Order = 1
) e nonRouteData.Values["otherPagesTemplate"]
(Order = 2
) a causa dell'impostazione dellaOrder
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Razor Le opzioni delle pagine, ad esempio l'aggiunta Conventionsdi , vengono aggiunte quando Razor Pages viene aggiunto alla raccolta di servizi in Startup.ConfigureServices
. Per un esempio completo, vedere l'app di esempio.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About/GlobalRouteValue
ed esaminare il risultato:
Aggiungere una convenzione del modello di app a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageApplicationModelConvention alla raccolta di istanze applicate durante la costruzione del modello di IPageConvention app di pagina.
Per dimostrare questa e altre convenzioni più avanti in questo argomento, l'app di esempio include una classe AddHeaderAttribute
. Il costruttore della classe accetta una stringa name
e una matrice di stringhe values
. Questi valori vengono usati nel relativo metodo OnResultExecuting
per impostare un'intestazione di risposta. La classe completa è illustrata nella sezione Convenzioni per le azioni del modello di pagina più avanti in questo argomento.
L'app di esempio usa la classe AddHeaderAttribute
per aggiungere un'intestazione, GlobalHeader
, a tutte le pagine nell'app:
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());
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Aggiungere una convenzione del modello di gestore a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageHandlerModelConvention alla raccolta di istanze applicate durante la costruzione del modello del gestore di IPageConvention pagine.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs
:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Convenzioni per le azioni di route di pagina
Il provider di modelli di route predefinito che deriva da IPageRouteModelProvider richiama convenzioni progettate per fornire punti di estendibilità per la configurazione delle route di pagina.
Convenzione per il modello di route cartella
Utilizzare AddFolderRouteModelConvention per creare e aggiungere un oggetto IPageRouteModelConvention che richiama un'azione su PageRouteModel per tutte le pagine nella cartella specificata.
L'app di esempio usa AddFolderRouteModelConvention per aggiungere un modello di route {otherPagesTemplate?}
alle pagine nella cartella OtherPages:
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?}"),
}
});
}
});
La proprietà Order per AttributeRouteModel è impostata su 2
. In questo modo, il modello per {globalTemplate?}
(impostato in precedenza nell'argomento su 1
) ha la priorità per la prima posizione del valore dei dati di route quando viene specificato un singolo valore di route. Se viene richiesta una pagina nella cartella Pages/OtherPages con un valore di parametro di route ,ad esempio /OtherPages/Page1/RouteDataValue
, "RouteDataValue" viene caricato in RouteData.Values["globalTemplate"]
(Order = 1
) e non RouteData.Values["otherPagesTemplate"]
(Order = 2
) a causa dell'impostazione della Order
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Richiedere la pagina Page1 dell'esempio in localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
ed esaminare il risultato:
Convenzione per il modello di route pagina
Utilizzare AddPageRouteModelConvention per creare e aggiungere un oggetto IPageRouteModelConvention che richiama un'azione nella PageRouteModel per la pagina con il nome specificato.
L'app di esempio usa AddPageRouteModelConvention
per aggiungere un modello di route {aboutTemplate?}
alla pagina di informazioni:
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?}"),
}
});
}
});
La proprietà Order per AttributeRouteModel è impostata su 2
. In questo modo, il modello per {globalTemplate?}
(impostato in precedenza nell'argomento su 1
) ha la priorità per la prima posizione del valore dei dati di route quando viene specificato un singolo valore di route. Se la pagina Informazioni su viene richiesta con un valore del parametro di route in /About/RouteDataValue
, "RouteDataValue" viene caricata in RouteData.Values["globalTemplate"]
(Order = 1
) e non RouteData.Values["aboutTemplate"]
(Order = 2
) a causa dell'impostazione della Order
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About/GlobalRouteValue/AboutRouteValue
ed esaminare il risultato:
Usare un trasformatore di parametro per personalizzare le route di pagina
Le route di pagina generate da ASP.NET Core possono essere personalizzate usando un trasformatore di parametro. Un trasformatore di parametri implementa IOutboundParameterTransformer
e trasforma il valore dei parametri. Ad esempio, un trasformatore di parametri SlugifyParameterTransformer
personalizzato cambia il valore di route SubscriptionManagement
in subscription-management
.
La convenzione del PageRouteTransformerConvention
modello di route di pagina applica un trasformatore di parametro ai segmenti di cartella e nome file di route di pagina generate automaticamente in un'app. Ad esempio, il Razor file Pages in /Pages/SubscriptionManagement/ViewAll.cshtml
avrebbe riscritto la route da /SubscriptionManagement/ViewAll
a /subscription-management/view-all
.
PageRouteTransformerConvention
trasforma solo i segmenti generati automaticamente di una route di pagina provenienti dalla cartella Pages e dal Razor nome del file. Non trasforma i segmenti di route aggiunti con la @page
direttiva . La convenzione non trasforma anche le route aggiunte da AddPageRoute.
l'oggetto PageRouteTransformerConvention
viene registrato come opzione in Startup.ConfigureServices
:
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();
}
}
Avviso
Quando si usa System.Text.RegularExpressions per elaborare l'input non attendibile, passare un timeout. Un utente malintenzionato può fornire input per RegularExpressions
causare un attacco Denial of Service. ASP.NET API del framework core che usano RegularExpressions
passano un timeout.
Configurare una route di pagina
Usare AddPageRoute per configurare una route a una pagina nel percorso di pagina specificato. I collegamenti generati alla pagina usano la route specificata. AddPageRoute
usa AddPageRouteModelConvention
per stabilire la route.
L'app di esempio crea una route a /TheContactPage
per Contact.cshtml
:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
La pagina di contatto può anche essere raggiunta in corrispondenza di /Contact
tramite la route predefinita.
La route personalizzata dell'app di esempio alla pagina di contatto consente un segmento di route text
facoltativo ({text?}
). La pagina include anche tale segmento facoltativo nella relativa istruzione @page
nel caso in cui il visitatore acceda alla pagina in corrispondenza della relativa route /Contact
:
@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>
Si noti che l'URL generato per il collegamento Contatto nella pagina sottoposta a rendering riflette la route aggiornata:
Visitare la pagina di contatto nella route normale, /Contact
, o nella route personalizzata /TheContactPage
. Se si specifica un segmento di route text
aggiuntivo, la pagina visualizza il segmento codificato in formato HTML specificato dall'utente:
Convenzioni per le azioni del modello di pagina
Il provider di modelli di pagina predefinito che implementa IPageApplicationModelProvider richiama convenzioni progettate per fornire punti di estendibilità per la configurazione dei modelli di pagina. Queste convenzioni sono utili durante la compilazione e la modifica degli scenari di individuazione ed elaborazione delle pagine.
Per gli esempi in questa sezione, l'app di esempio usa una AddHeaderAttribute
classe , ovvero , ResultFilterAttributeche applica un'intestazione di risposta:
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);
}
}
Tramite le convenzioni, nell'esempio viene illustrato come applicare l'attributo a tutte le pagine in una cartella e a una singola pagina.
Convenzione per il modello di app cartella
Usare AddFolderApplicationModelConvention per creare e aggiungere un oggetto IPageApplicationModelConvention che richiama un'azione sulle PageApplicationModel istanze di per tutte le pagine nella cartella specificata.
Nell'esempio viene illustrato l'uso di AddFolderApplicationModelConvention
aggiungendo un'intestazione, OtherPagesHeader
, alle pagine all'interno della cartella OtherPages dell'app:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Richiedere la pagina Page1 dell'esempio in localhost:5000/OtherPages/Page1
ed esaminare le intestazioni per visualizzare il risultato:
Convenzione per il modello di app cartella
Utilizzare AddPageApplicationModelConvention per creare e aggiungere un oggetto IPageApplicationModelConvention che richiama un'azione nella PageApplicationModel per la pagina con il nome specificato.
Nell'esempio viene illustrato l'uso di AddPageApplicationModelConvention
aggiungendo un'intestazione, AboutHeader
, alla pagina di informazioni:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Configurare un filtro
ConfigureFilter configura il filtro specificato da applicare. È possibile implementare una classe di filtro, ma l'app di esempio illustra come implementare un filtro in un'espressione lambda, che viene implementata in background come una factory che restituisce un filtro:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Viene usato il modello di app della pagina per verificare il percorso relativo per i segmenti che portano alla pagina Page2 nella cartella OtherPages. Se la condizione viene superata, viene aggiunta un'intestazione. In caso contrario, viene applicato EmptyFilter
.
EmptyFilter
è un filtro azione. Poiché i filtri azione vengono ignorati da Razor Pages, l'oggetto EmptyFilter
non ha alcun effetto come previsto se il percorso non contiene OtherPages/Page2
.
Richiedere la pagina Page2 dell'esempio in localhost:5000/OtherPages/Page2
ed esaminare le intestazioni per visualizzare il risultato:
Configurare una factory di filtro
ConfigureFilter configura la factory specificata per applicare filtri a tutte le Razor pagine.
L'app di esempio illustra un esempio dell'uso di una factory di filtro aggiungendo un'intestazione, FilterFactoryHeader
, con due valori per le pagine dell'app:
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;
}
}
}
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Filtri MVC e il filtro di pagina (IPageFilter)
I filtri azione MVC vengono ignorati da Razor Pages, perché Razor Pages usa metodi del gestore. Sono disponibili altri tipi di filtri MVC: autorizzazione, eccezione, risorse e risultati. Per altre informazioni, vedere l'argomento Filtri.
Il filtro Pagina (IPageFilter) è un filtro che si applica alle Razor pagine. Per altre informazioni, vedere Metodi di filtro per Razor Pagine.
Risorse aggiuntive
Informazioni su come usare le convenzioni di routing di pagine e provider di modelli di app per controllare il routing, l'individuazione e l'elaborazione delle pagine nelle Razor app Pages.
Quando è necessario configurare la route di una pagina personalizzata per le singole pagine, configurare il routing alle pagine con la convenzione AddPageRoute descritta più avanti in questo argomento.
Per specificare una route di pagina, aggiungere segmenti di route o aggiungere parametri a una route, usare la direttiva della @page
pagina. Per altre informazioni, vedere Route personalizzate.
Esistono parole riservate che non possono essere usate come segmenti di route o nomi di parametri. Per altre informazioni, vedere Routing: Nomi di routing riservati.
Visualizzare o scaricare il codice di esempio (procedura per il download)
Scenario | L'esempio illustra come eseguire le seguenti operazioni: |
---|---|
Convenzioni del modello Conventions.Add
|
Aggiungere un modello e un'intestazione di route alle pagine di un'app. |
Convenzioni per le azioni di route di pagina
|
Aggiungere un modello di route alle pagine in una cartella e a una pagina singola. |
Convenzioni per le azioni del modello di pagina
|
Aggiungere un'intestazione alle pagine in una cartella, aggiungere un'intestazione a una pagina singola e configurare una factory di filtro per aggiungere un'intestazione alle pagine di un'app. |
Razor Le convenzioni pages vengono aggiunte e configurate usando il AddRazorPagesOptions metodo di estensione su AddMvc nella raccolta di servizi nella Startup
classe . Gli esempi di convenzione seguenti sono illustrati più avanti in questo argomento:
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( ... );
});
}
Ordine di route
Le route specificano un oggetto per l'elaborazione Order (corrispondenza della route).
Ordine | Comportamento |
---|---|
-1 | La route viene elaborata prima dell'elaborazione di altre route. |
0 | L'ordine non è specificato (valore predefinito). Non assegnando Order (Order = null ) per impostazione predefinita la route Order a 0 (zero) per l'elaborazione. |
1, 2, … n | Specifica l'ordine di elaborazione della route. |
L'elaborazione della route viene stabilita per convenzione:
- Le route vengono elaborate in ordine sequenziale (-1, 0, 1, 2, ... n).
- Quando le route hanno lo stesso
Order
, la route più specifica viene trovata prima seguita da route meno specifiche. - Quando le route con lo stesso e lo stesso
Order
numero di parametri corrispondono a un URL di richiesta, le route vengono elaborate nell'ordine in cui vengono aggiunte a PageConventionCollection.
Se possibile, evitare di dipendere da un ordine di elaborazione della route stabilito. In genere, il routing seleziona la route corretta con la corrispondenza dell'URL. Se devi impostare le proprietà della route Order
per instradare correttamente le richieste, lo schema di routing dell'app probabilmente crea confusione per i client e fragile da gestire. Cercare di semplificare lo schema di routing dell'app. L'app di esempio richiede un ordine di elaborazione della route esplicito per illustrare diversi scenari di routing usando una singola app. Tuttavia, è consigliabile tentare di evitare la procedura di impostazione della route Order
nelle app di produzione.
Razor Il routing delle pagine e il routing del controller MVC condividono un'implementazione. Le informazioni sull'ordine di route negli argomenti MVC sono disponibili in Routing alle azioni del controller: Ordinamento delle route degli attributi.
Convenzioni del modello
Aggiungere un delegato per IPageConvention per aggiungere convenzioni di modello applicabili alle Razor pagine.
Aggiungere una convenzione del modello di route a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageRouteModelConvention alla raccolta di istanze applicate durante la costruzione del modello di IPageConvention route di pagina.
L'app di esempio aggiunge un modello di route {globalTemplate?}
a tutte le pagine nell'app:
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?}"),
}
});
}
}
}
La proprietà Order per AttributeRouteModel è impostata su 1
. Ciò garantisce il comportamento di corrispondenza della route seguente nell'app di esempio:
- Un modello di route per
TheContactPage/{text?}
viene aggiunto più avanti nell'argomento. La route della pagina contatto ha un ordine predefinito (null
Order = 0
), quindi corrisponde prima del{globalTemplate?}
modello di route. - Un
{aboutTemplate?}
modello di route viene aggiunto più avanti nell'argomento. Al modello{aboutTemplate?}
viene assegnato unOrder
di2
. Quando viene richiesta la pagina di informazioni in/About/RouteDataValue
, "RouteDataValue" viene caricato inRouteData.Values["globalTemplate"]
(Order = 1
) e non inRouteData.Values["aboutTemplate"]
(Order = 2
) a causa dell'impostazione della proprietàOrder
. - Un
{otherPagesTemplate?}
modello di route viene aggiunto più avanti nell'argomento. Al modello{otherPagesTemplate?}
viene assegnato unOrder
di2
. Quando viene richiesta una pagina nella cartella Pages/OtherPages con un parametro di route (ad esempio,/OtherPages/Page1/RouteDataValue
), "RouteDataValue" viene caricato inRouteData.Values["globalTemplate"]
(Order = 1
) e nonRouteData.Values["otherPagesTemplate"]
(Order = 2
) a causa dell'impostazione dellaOrder
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Razor Le opzioni delle pagine, ad esempio l'aggiunta Conventionsdi , vengono aggiunte quando MVC viene aggiunto alla raccolta di servizi in Startup.ConfigureServices
. Per un esempio completo, vedere l'app di esempio.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About/GlobalRouteValue
ed esaminare il risultato:
Aggiungere una convenzione del modello di app a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageApplicationModelConvention alla raccolta di istanze applicate durante la costruzione del modello di IPageConvention app di pagina.
Per dimostrare questa e altre convenzioni più avanti in questo argomento, l'app di esempio include una classe AddHeaderAttribute
. Il costruttore della classe accetta una stringa name
e una matrice di stringhe values
. Questi valori vengono usati nel relativo metodo OnResultExecuting
per impostare un'intestazione di risposta. La classe completa è illustrata nella sezione Convenzioni per le azioni del modello di pagina più avanti in questo argomento.
L'app di esempio usa la classe AddHeaderAttribute
per aggiungere un'intestazione, GlobalHeader
, a tutte le pagine nell'app:
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());
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Aggiungere una convenzione del modello di gestore a tutte le pagine
Usare Conventions per creare e aggiungere un oggetto IPageHandlerModelConvention alla raccolta di istanze applicate durante la costruzione del modello del gestore di IPageConvention pagine.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs
:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Convenzioni per le azioni di route di pagina
Il provider di modelli di route predefinito che deriva da IPageRouteModelProvider richiama convenzioni progettate per fornire punti di estendibilità per la configurazione delle route di pagina.
Convenzione per il modello di route cartella
Utilizzare AddFolderRouteModelConvention per creare e aggiungere un oggetto IPageRouteModelConvention che richiama un'azione su PageRouteModel per tutte le pagine nella cartella specificata.
L'app di esempio usa AddFolderRouteModelConvention per aggiungere un modello di route {otherPagesTemplate?}
alle pagine nella cartella OtherPages:
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?}"),
}
});
}
});
La proprietà Order per AttributeRouteModel è impostata su 2
. In questo modo, il modello per {globalTemplate?}
(impostato in precedenza nell'argomento su 1
) ha la priorità per la prima posizione del valore dei dati di route quando viene specificato un singolo valore di route. Se viene richiesta una pagina nella cartella Pages/OtherPages con un valore di parametro di route ,ad esempio /OtherPages/Page1/RouteDataValue
, "RouteDataValue" viene caricato in RouteData.Values["globalTemplate"]
(Order = 1
) e non RouteData.Values["otherPagesTemplate"]
(Order = 2
) a causa dell'impostazione della Order
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Richiedere la pagina Page1 dell'esempio in localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
ed esaminare il risultato:
Convenzione per il modello di route pagina
Utilizzare AddPageRouteModelConvention per creare e aggiungere un oggetto IPageRouteModelConvention che richiama un'azione nella PageRouteModel per la pagina con il nome specificato.
L'app di esempio usa AddPageRouteModelConvention
per aggiungere un modello di route {aboutTemplate?}
alla pagina di informazioni:
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?}"),
}
});
}
});
La proprietà Order per AttributeRouteModel è impostata su 2
. In questo modo, il modello per {globalTemplate?}
(impostato in precedenza nell'argomento su 1
) ha la priorità per la prima posizione del valore dei dati di route quando viene specificato un singolo valore di route. Se la pagina Informazioni su viene richiesta con un valore del parametro di route in /About/RouteDataValue
, "RouteDataValue" viene caricata in RouteData.Values["globalTemplate"]
(Order = 1
) e non RouteData.Values["aboutTemplate"]
(Order = 2
) a causa dell'impostazione della Order
proprietà .
Laddove possibile, non impostare , Order
che restituisce Order = 0
. Fare affidamento sul routing per selezionare la route corretta.
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About/GlobalRouteValue/AboutRouteValue
ed esaminare il risultato:
Configurare una route di pagina
Usare AddPageRoute per configurare una route a una pagina nel percorso di pagina specificato. I collegamenti generati alla pagina usano la route specificata. AddPageRoute
usa AddPageRouteModelConvention
per stabilire la route.
L'app di esempio crea una route a /TheContactPage
per Contact.cshtml
:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
La pagina di contatto può anche essere raggiunta in corrispondenza di /Contact
tramite la route predefinita.
La route personalizzata dell'app di esempio alla pagina di contatto consente un segmento di route text
facoltativo ({text?}
). La pagina include anche tale segmento facoltativo nella relativa istruzione @page
nel caso in cui il visitatore acceda alla pagina in corrispondenza della relativa route /Contact
:
@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>
Si noti che l'URL generato per il collegamento Contatto nella pagina sottoposta a rendering riflette la route aggiornata:
Visitare la pagina di contatto nella route normale, /Contact
, o nella route personalizzata /TheContactPage
. Se si specifica un segmento di route text
aggiuntivo, la pagina visualizza il segmento codificato in formato HTML specificato dall'utente:
Convenzioni per le azioni del modello di pagina
Il provider di modelli di pagina predefinito che implementa IPageApplicationModelProvider richiama convenzioni progettate per fornire punti di estendibilità per la configurazione dei modelli di pagina. Queste convenzioni sono utili durante la compilazione e la modifica degli scenari di individuazione ed elaborazione delle pagine.
Per gli esempi in questa sezione, l'app di esempio usa una AddHeaderAttribute
classe , ovvero , ResultFilterAttributeche applica un'intestazione di risposta:
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);
}
}
Tramite le convenzioni, nell'esempio viene illustrato come applicare l'attributo a tutte le pagine in una cartella e a una singola pagina.
Convenzione per il modello di app cartella
Usare AddFolderApplicationModelConvention per creare e aggiungere un oggetto IPageApplicationModelConvention che richiama un'azione sulle PageApplicationModel istanze di per tutte le pagine nella cartella specificata.
Nell'esempio viene illustrato l'uso di AddFolderApplicationModelConvention
aggiungendo un'intestazione, OtherPagesHeader
, alle pagine all'interno della cartella OtherPages dell'app:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Richiedere la pagina Page1 dell'esempio in localhost:5000/OtherPages/Page1
ed esaminare le intestazioni per visualizzare il risultato:
Convenzione per il modello di app cartella
Utilizzare AddPageApplicationModelConvention per creare e aggiungere un oggetto IPageApplicationModelConvention che richiama un'azione nella PageApplicationModel per la pagina con il nome specificato.
Nell'esempio viene illustrato l'uso di AddPageApplicationModelConvention
aggiungendo un'intestazione, AboutHeader
, alla pagina di informazioni:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Configurare un filtro
ConfigureFilter configura il filtro specificato da applicare. È possibile implementare una classe di filtro, ma l'app di esempio illustra come implementare un filtro in un'espressione lambda, che viene implementata in background come una factory che restituisce un filtro:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Viene usato il modello di app della pagina per verificare il percorso relativo per i segmenti che portano alla pagina Page2 nella cartella OtherPages. Se la condizione viene superata, viene aggiunta un'intestazione. In caso contrario, viene applicato EmptyFilter
.
EmptyFilter
è un filtro azione. Poiché i filtri azione vengono ignorati da Razor Pages, l'oggetto EmptyFilter
non ha alcun effetto come previsto se il percorso non contiene OtherPages/Page2
.
Richiedere la pagina Page2 dell'esempio in localhost:5000/OtherPages/Page2
ed esaminare le intestazioni per visualizzare il risultato:
Configurare una factory di filtro
ConfigureFilter configura la factory specificata per applicare filtri a tutte le Razor pagine.
L'app di esempio illustra un esempio dell'uso di una factory di filtro aggiungendo un'intestazione, FilterFactoryHeader
, con due valori per le pagine dell'app:
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;
}
}
}
Richiedere la pagina di informazioni dell'esempio in localhost:5000/About
ed esaminare le intestazioni per visualizzare il risultato:
Filtri MVC e il filtro di pagina (IPageFilter)
I filtri azione MVC vengono ignorati da Razor Pages, perché Razor Pages usa metodi del gestore. Sono disponibili altri tipi di filtri MVC: autorizzazione, eccezione, risorse e risultati. Per altre informazioni, vedere l'argomento Filtri.
Il filtro Pagina (IPageFilter) è un filtro che si applica alle Razor pagine. Per altre informazioni, vedere Metodi di filtro per Razor Pagine.