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:

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. La Contact Page route ha un ordine predefinito di (Order = 0), quindi corrisponde prima del {globalTemplate?} modello di null route con Order = 1.

  • Il {aboutTemplate?} modello di route viene visualizzato nel codice precedente. Al modello {aboutTemplate?} viene assegnato un Order di 2. Quando viene richiesta la pagina di informazioni in /About/RouteDataValue, "RouteDataValue" viene caricato in RouteData.Values["globalTemplate"] (Order = 1) e non in RouteData.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 un Order di 2. 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 in RouteData.Values["globalTemplate"] (Order = 1).

  • RouteData.Values["otherPagesTemplate"] con (Order = 2) non viene caricato a causa della Order 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:

The About page is requested with a route segment of GlobalRouteValue. The rendered page shows that the route data value is captured in the OnGet method of the page.

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 Ordere 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:

Response headers of the About page show that the GlobalHeader has been added.

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 , Orderche 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:

Page1 in the OtherPages folder is requested with a route segment of GlobalRouteValue and OtherPagesRouteValue. The rendered page shows that the route data values are captured in the OnGet method of the page.

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 , Orderche 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:

About page is requested with route segments for GlobalRouteValue and AboutRouteValue. The rendered page shows that the route data values are captured in the OnGet method of the page.

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 ContactRazor 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:

Sample app Contact link in the navigation bar

Inspecting the Contact link in the rendered HTML indicates that the href is set to '/TheContactPage'

Visitare la Contact pagina in corrispondenza del percorso ordinario, /Contacto 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:

Edge browser example of supplying an optional 'text' route segment of 'TextValue' in the URL. The rendered page shows the 'text' segment value.

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:

Response headers of the OtherPages/Page1 page show that the OtherPagesHeader has been added.

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:

Response headers of the About page show that the AboutHeader has been added.

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:

The OtherPagesPage2Header is added to the response for Page2.

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:

Response headers of the About page show that two FilterFactoryHeader headers have been added.

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
  • IPageRouteModelConvention
  • IPageApplicationModelConvention
  • IPageHandlerModelConvention
Aggiungere un modello e un'intestazione di route alle pagine di un'app.
Convenzioni per le azioni di route di pagina
  • AddFolderRouteModelConvention
  • AddPageRouteModelConvention
  • AddPageRoute
Aggiungere un modello di route alle pagine in una cartella e a una pagina singola.
Convenzioni per le azioni del modello di pagina
  • AddFolderApplicationModelConvention
  • AddPageApplicationModelConvention
  • ConfigureFilter (classe di filtro, espressione lambda o factory di filtro)
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 (nullOrder = 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 un Order di 2. Quando viene richiesta la pagina di informazioni in /About/RouteDataValue, "RouteDataValue" viene caricato in RouteData.Values["globalTemplate"] (Order = 1) e non in RouteData.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 un Order di 2. Quando viene richiesta una pagina nella cartella Pages/OtherPages con un 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 , Orderche 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:

The About page is requested with a route segment of GlobalRouteValue. The rendered page shows that the route data value is captured in the OnGet method of the page.

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:

Response headers of the About page show that the GlobalHeader has been added.

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 , Orderche 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:

Page1 in the OtherPages folder is requested with a route segment of GlobalRouteValue and OtherPagesRouteValue. The rendered page shows that the route data values are captured in the OnGet method of the page.

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 , Orderche 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:

About page is requested with route segments for GlobalRouteValue and AboutRouteValue. The rendered page shows that the route data values are captured in the OnGet method of the page.

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:

Sample app Contact link in the navigation bar

Inspecting the Contact link in the rendered HTML indicates that the href is set to '/TheContactPage'

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:

Edge browser example of supplying an optional 'text' route segment of 'TextValue' in the URL. The rendered page shows the 'text' segment value.

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:

Response headers of the OtherPages/Page1 page show that the OtherPagesHeader has been added.

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:

Response headers of the About page show that the AboutHeader has been added.

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:

The OtherPagesPage2Header is added to the response for Page2.

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:

Response headers of the About page show that two FilterFactoryHeader headers have been added.

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
  • IPageRouteModelConvention
  • IPageApplicationModelConvention
  • IPageHandlerModelConvention
Aggiungere un modello e un'intestazione di route alle pagine di un'app.
Convenzioni per le azioni di route di pagina
  • AddFolderRouteModelConvention
  • AddPageRouteModelConvention
  • AddPageRoute
Aggiungere un modello di route alle pagine in una cartella e a una pagina singola.
Convenzioni per le azioni del modello di pagina
  • AddFolderApplicationModelConvention
  • AddPageApplicationModelConvention
  • ConfigureFilter (classe di filtro, espressione lambda o factory di filtro)
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 (nullOrder = 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 un Order di 2. Quando viene richiesta la pagina di informazioni in /About/RouteDataValue, "RouteDataValue" viene caricato in RouteData.Values["globalTemplate"] (Order = 1) e non in RouteData.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 un Order di 2. Quando viene richiesta una pagina nella cartella Pages/OtherPages con un 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 , Orderche 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:

The About page is requested with a route segment of GlobalRouteValue. The rendered page shows that the route data value is captured in the OnGet method of the page.

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:

Response headers of the About page show that the GlobalHeader has been added.

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 , Orderche 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:

Page1 in the OtherPages folder is requested with a route segment of GlobalRouteValue and OtherPagesRouteValue. The rendered page shows that the route data values are captured in the OnGet method of the page.

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 , Orderche 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:

About page is requested with route segments for GlobalRouteValue and AboutRouteValue. The rendered page shows that the route data values are captured in the OnGet method of the page.

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:

Sample app Contact link in the navigation bar

Inspecting the Contact link in the rendered HTML indicates that the href is set to '/TheContactPage'

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:

Edge browser example of supplying an optional 'text' route segment of 'TextValue' in the URL. The rendered page shows the 'text' segment value.

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:

Response headers of the OtherPages/Page1 page show that the OtherPagesHeader has been added.

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:

Response headers of the About page show that the AboutHeader has been added.

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:

The OtherPagesPage2Header is added to the response for Page2.

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:

Response headers of the About page show that two FilterFactoryHeader headers have been added.

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