Convenções de rota e aplicativo do Razor Pages no ASP.NET Core
Saiba como usar a página convenções do provedor de modelo de rota e aplicativo para controlar o roteamento, a descoberta e o processamento de páginas nos aplicativos Razor Pages.
Para especificar uma rota de página, adicionar segmentos de rota ou adicionar parâmetros a uma rota, use a diretiva @page
da página. Para obter mais informações, confira Rotas personalizadas.
Há palavras reservadas que não podem ser usadas como segmentos de rota ou nomes de parâmetros. Para obter mais informações, confira Roteamento: nomes de roteamento reservados.
Exibir ou baixar código de exemplo (como baixar)
Cenário | O exemplo demonstra |
---|---|
Convenções de modelo Conventions.Add |
Adicione um cabeçalho e um modelo de rota às páginas de um aplicativo. |
Convenções de ação da rota de página | Adicione um modelo de rota às páginas em uma pasta e a uma única página. |
Convenções de ação do modelo de página
|
Adicione um cabeçalho às páginas em uma pasta, adicione um cabeçalho a uma única página e configure um alocador de filtro para adicionar um cabeçalho às páginas de um aplicativo. |
As convenções do Razor Pages são configuradas usando uma sobrecarga AddRazorPages que configura RazorPagesOptions. Os exemplos de convenção a seguir estão descritos mais adiante neste tópico:
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( ... );
});
}
Ordem de rota
As rotas especificam um Order para processamento (correspondência de rotas).
Ordem de rota | Comportamento |
---|---|
-1 | A rota é processada antes que outras rotas sejam processadas. |
0 | A ordem não é especificada (valor padrão). A não atribuição Order (Order = null ) define a rota Order como 0 (zero) por padrão para processamento. |
1, 2, … n | Especifica a ordem de processamento de rota. |
O processamento de rotas é estabelecido por convenção:
- As rotas são processadas em ordem sequencial (-1, 0, 1, 2, ... n).
- Quando as rotas têm o mesmo
Order
, a rota mais específica é correspondida primeiro, seguida por rotas menos específicas. - Quando as rotas com o mesmo
Order
e o mesmo número de parâmetros correspondem a uma URL de solicitação, as rotas são processadas na ordem em que são adicionadas a PageConventionCollection.
Se possível, evite depender de uma ordem de processamento de rota estabelecida. Em geral, o roteamento seleciona a rota correta com correspondência de URL. Se você precisar definir propriedades Order
de rota para rotear solicitações corretamente, o esquema de roteamento do aplicativo provavelmente será confuso para os clientes e de frágil manutenção. Procure simplificar o esquema de roteamento do aplicativo. O aplicativo de exemplo requer uma ordem de processamento de rota explícita para demonstrar vários cenários de roteamento usando um único aplicativo. No entanto, você deve tentar evitar a prática de definir a rota Order
em aplicativos de produção.
O roteamento do Razor Pages e o roteamento de controlador do MVC compartilham uma implementação. As informações sobre a ordem de rota nos tópicos do MVC estão disponíveis em Roteamento para ações do controlador: ordenando as rotas de atributo.
Convenções de modelo
Adicione um representante para IPageConvention a fim de adicionar convenções de modelo que se aplicam ao Razor Pages.
Adicionar uma convenção de modelo de rota a todas as páginas
Use Conventions para criar e adicionar um IPageRouteModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo de rota de página.
O aplicativo de exemplo contém a classe GlobalTemplatePageRouteModelConvention
para adicionar um modelo de rota {globalTemplate?}
a todas as páginas do aplicativo:
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?}"),
}
});
}
}
}
No código anterior:
- O PageRouteModel é passado para o método Apply.
- O PageRouteModel.Selectors obtém a contagem de seletores.
- Um novo SelectorModel é adicionado, que contém um AttributeRouteModel
As opções do Razor Pages, como adicionar Conventions, são adicionadas quando o Razor Pages é adicionado à coleção de serviços. Para obter um exemplo, confira o aplicativo de exemplo.
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();
Considere a classe GlobalTemplatePageRouteModelConvention
:
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?}"),
}
});
}
}
}
A propriedade Order do AttributeRouteModel é definida como 1
. Isso garante o seguinte comportamento de correspondência de rotas no aplicativo de exemplo:
Um modelo de rota para
TheContactPage/{text?}
é adicionado posteriormente nesse tópico. A rotaContact Page
tem uma ordem padrão denull
(Order = 0
), portanto, corresponde antes do modelo de rota{globalTemplate?}
, que temOrder = 1
.O modelo de rota
{aboutTemplate?}
é mostrado no código anterior. O modelo{aboutTemplate?}
recebe umaOrder
de2
. Quando a página About é solicitada no/About/RouteDataValue
, "RouteDataValue" é carregado noRouteData.Values["globalTemplate"]
(Order = 1
) e nãoRouteData.Values["aboutTemplate"]
(Order = 2
) devido à configuração da propriedadeOrder
.O modelo de rota
{otherPagesTemplate?}
é mostrado no código anterior. O modelo{otherPagesTemplate?}
recebe umaOrder
de2
. Quando qualquer página na pasta Pages/OtherPages é solicitada com um parâmetro de rota:Por exemplo,
/OtherPages/Page1/xyz
O valor dos dados de rota
"xyz"
é carregado emRouteData.Values["globalTemplate"]
(Order = 1
).RouteData.Values["otherPagesTemplate"]
com (Order = 2
) não é carregado devido à propriedadeOrder
2
ter um valor mais alto.
Quando possível, não defina Order
. Quando Order
não está definida, o padrão será Order = 0
. Conte com o roteamento para selecionar a rota correta em vez da propriedade Order
.
Solicite a página About
do exemplo em localhost:{port}/About/GlobalRouteValue
e inspecione o resultado:
O aplicativo de exemplo usa o pacote NuGet Rick.Docs.Samples.RouteInfo para exibir informações de roteamento na saída de registro em log. Utilizando localhost:{port}/About/GlobalRouteValue
, o agente exibe a solicitação, o Order
e o modelo usados:
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue Order = 1 Template = About/{globalTemplate?}
Adicionar uma convenção de modelo de aplicativo a todas as páginas
Use Conventions para criar e adicionar um IPageApplicationModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo de aplicativo de página.
Para demonstrar isso e outras convenções mais adiante no tópico, o aplicativo de exemplo inclui uma classe AddHeaderAttribute
. O construtor de classe aceita uma cadeia de caracteres name
e uma matriz de cadeia de caracteres values
. Esses valores são usados em seu método OnResultExecuting
para definir um cabeçalho de resposta. A classe completa é mostrada na seção Convenções de ação do modelo de página mais adiante no tópico.
O aplicativo de exemplo usa a classe AddHeaderAttribute
para adicionar um cabeçalho, GlobalHeader
, a todas as páginas no aplicativo:
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());
Solicite a página About da amostra em localhost:{port}/About
e inspecione os cabeçalhos para exibir o resultado:
Adicionar uma convenção de modelo de manipulador a todas as páginas
Use Conventions para criar e adicionar um IPageHandlerModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo do manipulador de página.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Convenções de ação da rota de página
O provedor de modelo de rota padrão derivado de IPageRouteModelProvider invoca convenções que foram projetadas para fornecer pontos de extensibilidade para configuração de rotas de página.
Convenção de modelo de rota de pasta
Use AddFolderRouteModelConvention para criar e adicionar um IPageRouteModelConvention que invoca uma ação no PageRouteModel para todas as páginas na pasta especificada.
O aplicativo de exemplo usa AddFolderRouteModelConvention para adicionar um modelo de rota {otherPagesTemplate?}
às páginas da pasta 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?}"),
}
});
}
});
A propriedade Order do AttributeRouteModel é definida como 2
. Isso garante que o modelo para {globalTemplate?}
(definido anteriormente no tópico como 1
) tenha prioridade para a primeira posição de valor de dados de rota quando um único valor de rota é fornecido. Se uma página na pasta Pages/OtherPages for solicitada com um valor de parâmetro de rota (por exemplo, /OtherPages/Page1/RouteDataValue
), "RouteDataValue" será carregado em RouteData.Values["globalTemplate"]
(Order = 1
) e não RouteData.Values["otherPagesTemplate"]
(Order = 2
) devido à configuração da propriedade Order
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
Solicite a página Page1 da amostra em localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
e inspecione o resultado:
Convenção de modelo de rota de página
Use AddPageRouteModelConvention para criar e adicionar um IPageRouteModelConvention que invoca uma ação no PageRouteModel para a página no nome especificado.
O aplicativo de exemplo usa AddPageRouteModelConvention
para adicionar um modelo de rota {aboutTemplate?}
à página About:
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?}"),
}
});
}
});
A propriedade Order do AttributeRouteModel é definida como 2
. Isso garante que o modelo para {globalTemplate?}
(definido anteriormente no tópico como 1
) tenha prioridade para a primeira posição de valor de dados de rota quando um único valor de rota é fornecido. Se a página About for solicitada com um valor de parâmetro de rota no /About/RouteDataValue
, "RouteDataValue" será carregado no RouteData.Values["globalTemplate"]
(Order = 1
) e não RouteData.Values["aboutTemplate"]
(Order = 2
) devido à configuração da propriedade Order
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
Solicite a página About da amostra em localhost:{port}/About/GlobalRouteValue/AboutRouteValue
e inspecione o resultado:
A saída do agente mostra:
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue/AboutRouteValue Order = 2 Template = About/{globalTemplate?}/{aboutTemplate?}
Usar um transformador de parâmetro para personalizar rotas de página
Confira Transformadores de parâmetro.
Configurar uma rota de página
Use AddPageRoute para configurar uma rota para uma página no caminho de página especificado. Os links gerados para a página usam a rota especificada. AddPageRoute usa AddPageRouteModelConvention para estabelecer a rota.
O aplicativo de exemplo cria uma rota para /TheContactPage
para o Contact
Razor Pages:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
A página Contact
também pode ser acessada em /
Contact1` via rota padrão.
A rota personalizada do aplicativo de exemplo para a página Contact
permite um segmento de rota text
opcional ({text?}
). A página também inclui esse segmento opcional em sua diretiva @page
, caso o visitante acesse a página em sua rota /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>
Observe que a URL gerada para o link Contato na página renderizada reflete a rota atualizada:
Visite a página Contact
na rota ordinária /Contact
ou na rota personalizada /TheContactPage
. Se você fornecer um segmento de rota text
adicional, a página mostrará o segmento codificado em HTML fornecido:
Convenções de ação do modelo de página
O provedor de modelo de página padrão que implementa IPageApplicationModelProvider invoca convenções que foram projetadas para fornecer pontos de extensibilidade para configuração de modelos de página. Essas convenções são úteis ao criar e modificar cenários de descoberta e processamento de página.
Para os exemplos desta seção, o aplicativo de exemplo usa uma classe AddHeaderAttribute
, que é um ResultFilterAttribute, aplicável a um cabeçalho de resposta:
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);
}
}
Usando convenções, a amostra explica como aplicar o atributo a todas as páginas de uma pasta e a uma única página.
Convenção de modelo de aplicativo de pasta
Use AddFolderApplicationModelConvention para criar e adicionar um IPageApplicationModelConvention que invoca uma ação em instâncias PageApplicationModel para todas as páginas na pasta especificada.
A amostra explica o uso de AddFolderApplicationModelConvention
adicionando um cabeçalho, OtherPagesHeader
, às páginas dentro da pasta OtherPages do aplicativo:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Solicite a página Page1 da amostra em localhost:5000/OtherPages/Page1
e inspecione os cabeçalhos para exibir o resultado:
Convenção de modelo de aplicativo de página
Use AddPageApplicationModelConvention para criar e adicionar um IPageApplicationModelConvention que invoca uma ação no PageApplicationModel para a página no nome especificado.
A amostra explica o uso de AddPageApplicationModelConvention
adicionando um cabeçalho, AboutHeader
, à página About:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Configurar um filtro
ConfigureFilter configura o filtro especificado a ser aplicado. É possível implementar uma classe de filtro, mas o aplicativo de exemplo mostra como implementar um filtro em uma expressão lambda, que é implementado em segundo plano como um alocador que retorna um filtro:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
O modelo de aplicativo de página é usado para verificar o caminho relativo para segmentos que levam à página Page2 na pasta OtherPages. Se a condição é aprovada, um cabeçalho é adicionado. Caso contrário, o EmptyFilter
é aplicado.
EmptyFilter
é um filtro de Ação. Como os filtros de ação são ignorados por páginas Razor , o EmptyFilter
não terá o efeito pretendido se o caminho não contiver OtherPages/Page2
.
Solicite a página Page2 da amostra em localhost:5000/OtherPages/Page2
e inspecione os cabeçalhos para exibir o resultado:
Configurar um alocador de filtro
ConfigureFilter configura o alocador especificado para aplicar filtros a todas as Páginas Razor.
O aplicativo de exemplo fornece um exemplo de como usar um alocador de filtro adicionando um cabeçalho, FilterFactoryHeader
, com dois valores para as páginas do aplicativo:
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;
}
}
}
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Filtros MVC e o filtro de Página (IPageFilter)
Os filtros de Ação MVC são ignorados pelas Páginas Razor, pois as páginas Razor usam métodos de manipulador. Outros tipos de filtros MVC estão disponíveis para uso: Autorização, Exceção, Recurso e Resultado. Para obter mais informações, consulte o tópico Filtros.
O filtro de Página (IPageFilter) é um filtro que se aplica às Páginas do Razor. Para obter mais informações, confira Métodos de filtragem para Páginas do Razor.
Recursos adicionais
Saiba como usar a página convenções do provedor de modelo de rota e aplicativo para controlar o roteamento, a descoberta e o processamento de páginas nos aplicativos Razor Pages.
Quando precisar configurar rotas de página personalizadas para páginas individuais, configure o roteamento para páginas com a convenção AddPageRoute descrita mais adiante neste tópico.
Para especificar uma rota de página, adicionar segmentos de rota ou adicionar parâmetros a uma rota, use a diretiva @page
da página. Para obter mais informações, confira Rotas personalizadas.
Há palavras reservadas que não podem ser usadas como segmentos de rota ou nomes de parâmetros. Para obter mais informações, confira Roteamento: nomes de roteamento reservados.
Exibir ou baixar código de exemplo (como baixar)
Cenário | A amostra explica... |
---|---|
Convenções de modelo Conventions.Add
|
Adicione um cabeçalho e um modelo de rota às páginas de um aplicativo. |
Convenções de ação da rota de página
|
Adicione um modelo de rota às páginas em uma pasta e a uma única página. |
Convenções de ação do modelo de página
|
Adicione um cabeçalho às páginas em uma pasta, adicione um cabeçalho a uma única página e configure um alocador de filtro para adicionar um cabeçalho às páginas de um aplicativo. |
As convenções de páginas do Razor são configuradas usando uma sobrecarga AddRazorPages que configura RazorPagesOptions em Startup.ConfigureServices
. Os exemplos de convenção a seguir estão descritos mais adiante neste tópico:
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( ... );
});
}
Ordem de rota
As rotas especificam um Order para processamento (correspondência de rotas).
Order | Comportamento |
---|---|
-1 | A rota é processada antes que outras rotas sejam processadas. |
0 | A ordem não é especificada (valor padrão). A não atribuição Order (Order = null ) define a rota Order como 0 (zero) por padrão para processamento. |
1, 2, … n | Especifica a ordem de processamento de rota. |
O processamento de rotas é estabelecido por convenção:
- As rotas são processadas em ordem sequencial (-1, 0, 1, 2, ... n).
- Quando as rotas têm o mesmo
Order
, a rota mais específica é correspondida primeiro, seguida por rotas menos específicas. - Quando as rotas com o mesmo
Order
e o mesmo número de parâmetros correspondem a uma URL de solicitação, as rotas são processadas na ordem em que são adicionadas a PageConventionCollection.
Se possível, evite depender de uma ordem de processamento de rota estabelecida. Em geral, o roteamento seleciona a rota correta com correspondência de URL. Se você precisar definir propriedades Order
de rota para rotear solicitações corretamente, o esquema de roteamento do aplicativo provavelmente será confuso para os clientes e de frágil manutenção. Procure simplificar o esquema de roteamento do aplicativo. O aplicativo de exemplo requer uma ordem de processamento de rota explícita para demonstrar vários cenários de roteamento usando um único aplicativo. No entanto, você deve tentar evitar a prática de definir a rota Order
em aplicativos de produção.
O roteamento do Razor Pages e o roteamento de controlador do MVC compartilham uma implementação. As informações sobre a ordem de rota nos tópicos do MVC estão disponíveis em Roteamento para ações do controlador: ordenando as rotas de atributo.
Convenções de modelo
Adicione um representante para IPageConvention a fim de adicionar convenções de modelo que se aplicam ao Razor Pages.
Adicionar uma convenção de modelo de rota a todas as páginas
Use Conventions para criar e adicionar um IPageRouteModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo de rota de página.
O aplicativo de exemplo adiciona um modelo de rota {globalTemplate?}
a todas as páginas no aplicativo:
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?}"),
}
});
}
}
}
A propriedade Order do AttributeRouteModel é definida como 1
. Isso garante o seguinte comportamento de correspondência de rotas no aplicativo de exemplo:
- Um modelo de rota para
TheContactPage/{text?}
é adicionado posteriormente no tópico. A rota Página de Contato tem uma ordem padrão denull
(Order = 0
), portanto, corresponde antes do modelo de rota{globalTemplate?}
. - Um modelo de rota
{aboutTemplate?}
é adicionado posteriormente no tópico. O modelo{aboutTemplate?}
recebe umaOrder
de2
. Quando a página About é solicitada no/About/RouteDataValue
, "RouteDataValue" é carregado noRouteData.Values["globalTemplate"]
(Order = 1
) e nãoRouteData.Values["aboutTemplate"]
(Order = 2
) devido à configuração da propriedadeOrder
. - Um modelo de rota
{otherPagesTemplate?}
é adicionado posteriormente no tópico. O modelo{otherPagesTemplate?}
recebe umaOrder
de2
. Quando qualquer página na pasta Pages/OtherPages é solicitada com um parâmetro de rota (por exemplo,/OtherPages/Page1/RouteDataValue
), "RouteDataValue" é carregado emRouteData.Values["globalTemplate"]
(Order = 1
) e nãoRouteData.Values["otherPagesTemplate"]
(Order = 2
) devido à configuração da propriedadeOrder
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
As opções do Razor Pages, como adicionar Conventions, são adicionadas quando o Razor Pages é adicionado à coleção de serviços no Startup.ConfigureServices
. Para obter um exemplo, confira o aplicativo de exemplo.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Solicite a página About da amostra em localhost:5000/About/GlobalRouteValue
e inspecione o resultado:
Adicionar uma convenção de modelo de aplicativo a todas as páginas
Use Conventions para criar e adicionar um IPageApplicationModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo de aplicativo de página.
Para demonstrar isso e outras convenções mais adiante no tópico, o aplicativo de exemplo inclui uma classe AddHeaderAttribute
. O construtor de classe aceita uma cadeia de caracteres name
e uma matriz de cadeia de caracteres values
. Esses valores são usados em seu método OnResultExecuting
para definir um cabeçalho de resposta. A classe completa é mostrada na seção Convenções de ação do modelo de página mais adiante no tópico.
O aplicativo de exemplo usa a classe AddHeaderAttribute
para adicionar um cabeçalho, GlobalHeader
, a todas as páginas no aplicativo:
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());
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Adicionar uma convenção de modelo de manipulador a todas as páginas
Use Conventions para criar e adicionar um IPageHandlerModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo do manipulador de página.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs
:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Convenções de ação da rota de página
O provedor de modelo de rota padrão derivado de IPageRouteModelProvider invoca convenções que foram projetadas para fornecer pontos de extensibilidade para configuração de rotas de página.
Convenção de modelo de rota de pasta
Use AddFolderRouteModelConvention para criar e adicionar um IPageRouteModelConvention que invoca uma ação no PageRouteModel para todas as páginas na pasta especificada.
O aplicativo de exemplo usa AddFolderRouteModelConvention para adicionar um modelo de rota {otherPagesTemplate?}
às páginas da pasta 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?}"),
}
});
}
});
A propriedade Order do AttributeRouteModel é definida como 2
. Isso garante que o modelo para {globalTemplate?}
(definido anteriormente no tópico como 1
) tenha prioridade para a primeira posição de valor de dados de rota quando um único valor de rota é fornecido. Se uma página na pasta Pages/OtherPages for solicitada com um valor de parâmetro de rota (por exemplo, /OtherPages/Page1/RouteDataValue
), "RouteDataValue" será carregado em RouteData.Values["globalTemplate"]
(Order = 1
) e não RouteData.Values["otherPagesTemplate"]
(Order = 2
) devido à configuração da propriedade Order
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
Solicite a página Page1 da amostra em localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
e inspecione o resultado:
Convenção de modelo de rota de página
Use AddPageRouteModelConvention para criar e adicionar um IPageRouteModelConvention que invoca uma ação no PageRouteModel para a página no nome especificado.
O aplicativo de exemplo usa AddPageRouteModelConvention
para adicionar um modelo de rota {aboutTemplate?}
à página About:
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?}"),
}
});
}
});
A propriedade Order do AttributeRouteModel é definida como 2
. Isso garante que o modelo para {globalTemplate?}
(definido anteriormente no tópico como 1
) tenha prioridade para a primeira posição de valor de dados de rota quando um único valor de rota é fornecido. Se a página About for solicitada com um valor de parâmetro de rota no /About/RouteDataValue
, "RouteDataValue" será carregado no RouteData.Values["globalTemplate"]
(Order = 1
) e não RouteData.Values["aboutTemplate"]
(Order = 2
) devido à configuração da propriedade Order
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
Solicite a página About da amostra em localhost:5000/About/GlobalRouteValue/AboutRouteValue
e inspecione o resultado:
Usar um transformador de parâmetro para personalizar rotas de página
As rotas de página geradas pelo ASP.NET Core podem ser personalizadas usando um transformador de parâmetro. Um transformador de parâmetro implementa IOutboundParameterTransformer
e transforma o valor dos parâmetros. Por exemplo, um transformador de parâmetro SlugifyParameterTransformer
personalizado muda o valor de rota SubscriptionManagement
para subscription-management
.
A convenção de modelo de rota de página PageRouteTransformerConvention
aplica um transformador de parâmetro aos segmentos de nome de arquivo e pasta de rotas de página geradas automaticamente em um aplicativo. Por exemplo, o arquivo de Páginas do Razor em /Pages/SubscriptionManagement/ViewAll.cshtml
teria sua rota reescrita de /SubscriptionManagement/ViewAll
para /subscription-management/view-all
.
PageRouteTransformerConvention
transforma apenas os segmentos gerados automaticamente de uma rota de página proveniente do nome de arquivo e pasta das Páginas do Razor. Ele não transforma segmentos de rota adicionados com a diretiva @page
. A convenção também não transforma rotas adicionadas por AddPageRoute.
O PageRouteTransformerConvention
está registrado como uma opção em 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();
}
}
Aviso
Ao usar System.Text.RegularExpressions para processar entradas não confiáveis, passe um tempo limite. Um usuário mal-intencionado pode fornecer entrada para RegularExpressions
, causando um ataque de negação de serviço. APIs ASP.NET Core Framework que usam RegularExpressions
passam um tempo limite.
Configurar uma rota de página
Use AddPageRoute para configurar uma rota para uma página no caminho de página especificado. Os links gerados para a página usam a rota especificada. AddPageRoute
usa AddPageRouteModelConvention
para estabelecer a rota.
O aplicativo de exemplo cria uma rota para /TheContactPage
para Contact.cshtml
:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
A página Contact também pode ser acessada em /Contact
por meio de sua rota padrão.
A rota personalizada do aplicativo de exemplo para a página Contact permite um segmento de rota text
opcional ({text?}
). A página também inclui esse segmento opcional em sua diretiva @page
, caso o visitante acesse a página em sua rota /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>
Observe que a URL gerada para o link Contato na página renderizada reflete a rota atualizada:
Visite a página Contact em sua rota comum, /Contact
, ou na rota personalizada, /TheContactPage
. Se você fornecer um segmento de rota text
adicional, a página mostrará o segmento codificado em HTML fornecido:
Convenções de ação do modelo de página
O provedor de modelo de página padrão que implementa IPageApplicationModelProvider invoca convenções que foram projetadas para fornecer pontos de extensibilidade para configuração de modelos de página. Essas convenções são úteis ao criar e modificar cenários de descoberta e processamento de página.
Para os exemplos desta seção, o aplicativo de exemplo usa uma classe AddHeaderAttribute
, que é um ResultFilterAttribute, aplicável a um cabeçalho de resposta:
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);
}
}
Usando convenções, a amostra explica como aplicar o atributo a todas as páginas de uma pasta e a uma única página.
Convenção de modelo de aplicativo de pasta
Use AddFolderApplicationModelConvention para criar e adicionar um IPageApplicationModelConvention que invoca uma ação em instâncias PageApplicationModel para todas as páginas na pasta especificada.
A amostra explica o uso de AddFolderApplicationModelConvention
adicionando um cabeçalho, OtherPagesHeader
, às páginas dentro da pasta OtherPages do aplicativo:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Solicite a página Page1 da amostra em localhost:5000/OtherPages/Page1
e inspecione os cabeçalhos para exibir o resultado:
Convenção de modelo de aplicativo de página
Use AddPageApplicationModelConvention para criar e adicionar um IPageApplicationModelConvention que invoca uma ação no PageApplicationModel para a página no nome especificado.
A amostra explica o uso de AddPageApplicationModelConvention
adicionando um cabeçalho, AboutHeader
, à página About:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Configurar um filtro
ConfigureFilter configura o filtro especificado a ser aplicado. É possível implementar uma classe de filtro, mas o aplicativo de exemplo mostra como implementar um filtro em uma expressão lambda, que é implementado em segundo plano como um alocador que retorna um filtro:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
O modelo de aplicativo de página é usado para verificar o caminho relativo para segmentos que levam à página Page2 na pasta OtherPages. Se a condição é aprovada, um cabeçalho é adicionado. Caso contrário, o EmptyFilter
é aplicado.
EmptyFilter
é um filtro de Ação. Como os filtros de ação são ignorados por páginas Razor , o EmptyFilter
não terá o efeito pretendido se o caminho não contiver OtherPages/Page2
.
Solicite a página Page2 da amostra em localhost:5000/OtherPages/Page2
e inspecione os cabeçalhos para exibir o resultado:
Configurar um alocador de filtro
ConfigureFilter configura o alocador especificado para aplicar filtros a todas as Páginas Razor.
O aplicativo de exemplo fornece um exemplo de como usar um alocador de filtro adicionando um cabeçalho, FilterFactoryHeader
, com dois valores para as páginas do aplicativo:
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;
}
}
}
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Filtros MVC e o filtro de Página (IPageFilter)
Os filtros de Ação MVC são ignorados pelas Páginas Razor, pois as páginas Razor usam métodos de manipulador. Outros tipos de filtros MVC estão disponíveis para uso: Autorização, Exceção, Recurso e Resultado. Para obter mais informações, consulte o tópico Filtros.
O filtro de Página (IPageFilter) é um filtro que se aplica às Páginas do Razor. Para obter mais informações, confira Métodos de filtragem para Páginas do Razor.
Recursos adicionais
Saiba como usar a página convenções do provedor de modelo de rota e aplicativo para controlar o roteamento, a descoberta e o processamento de páginas nos aplicativos Razor Pages.
Quando precisar configurar rotas de página personalizadas para páginas individuais, configure o roteamento para páginas com a convenção AddPageRoute descrita mais adiante neste tópico.
Para especificar uma rota de página, adicionar segmentos de rota ou adicionar parâmetros a uma rota, use a diretiva @page
da página. Para obter mais informações, confira Rotas personalizadas.
Há palavras reservadas que não podem ser usadas como segmentos de rota ou nomes de parâmetros. Para obter mais informações, confira Roteamento: nomes de roteamento reservados.
Exibir ou baixar código de exemplo (como baixar)
Cenário | A amostra explica... |
---|---|
Convenções de modelo Conventions.Add
|
Adicione um cabeçalho e um modelo de rota às páginas de um aplicativo. |
Convenções de ação da rota de página
|
Adicione um modelo de rota às páginas em uma pasta e a uma única página. |
Convenções de ação do modelo de página
|
Adicione um cabeçalho às páginas em uma pasta, adicione um cabeçalho a uma única página e configure um alocador de filtro para adicionar um cabeçalho às páginas de um aplicativo. |
As convenções do Razor Pages são adicionadas e configuradas usando o método de extensão AddRazorPagesOptions para AddMvc na coleção de serviços na classe Startup
. Os exemplos de convenção a seguir estão descritos mais adiante neste tópico:
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( ... );
});
}
Ordem de rota
As rotas especificam um Order para processamento (correspondência de rotas).
Order | Comportamento |
---|---|
-1 | A rota é processada antes que outras rotas sejam processadas. |
0 | A ordem não é especificada (valor padrão). A não atribuição Order (Order = null ) define a rota Order como 0 (zero) por padrão para processamento. |
1, 2, … n | Especifica a ordem de processamento de rota. |
O processamento de rotas é estabelecido por convenção:
- As rotas são processadas em ordem sequencial (-1, 0, 1, 2, ... n).
- Quando as rotas têm o mesmo
Order
, a rota mais específica é correspondida primeiro, seguida por rotas menos específicas. - Quando as rotas com o mesmo
Order
e o mesmo número de parâmetros correspondem a uma URL de solicitação, as rotas são processadas na ordem em que são adicionadas a PageConventionCollection.
Se possível, evite depender de uma ordem de processamento de rota estabelecida. Em geral, o roteamento seleciona a rota correta com correspondência de URL. Se você precisar definir propriedades Order
de rota para rotear solicitações corretamente, o esquema de roteamento do aplicativo provavelmente será confuso para os clientes e de frágil manutenção. Procure simplificar o esquema de roteamento do aplicativo. O aplicativo de exemplo requer uma ordem de processamento de rota explícita para demonstrar vários cenários de roteamento usando um único aplicativo. No entanto, você deve tentar evitar a prática de definir a rota Order
em aplicativos de produção.
O roteamento do Razor Pages e o roteamento de controlador do MVC compartilham uma implementação. As informações sobre a ordem de rota nos tópicos do MVC estão disponíveis em Roteamento para ações do controlador: ordenando as rotas de atributo.
Convenções de modelo
Adicione um representante para IPageConvention a fim de adicionar convenções de modelo que se aplicam ao Razor Pages.
Adicionar uma convenção de modelo de rota a todas as páginas
Use Conventions para criar e adicionar um IPageRouteModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo de rota de página.
O aplicativo de exemplo adiciona um modelo de rota {globalTemplate?}
a todas as páginas no aplicativo:
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?}"),
}
});
}
}
}
A propriedade Order do AttributeRouteModel é definida como 1
. Isso garante o seguinte comportamento de correspondência de rotas no aplicativo de exemplo:
- Um modelo de rota para
TheContactPage/{text?}
é adicionado posteriormente no tópico. A rota Página de Contato tem uma ordem padrão denull
(Order = 0
), portanto, corresponde antes do modelo de rota{globalTemplate?}
. - Um modelo de rota
{aboutTemplate?}
é adicionado posteriormente no tópico. O modelo{aboutTemplate?}
recebe umaOrder
de2
. Quando a página About é solicitada no/About/RouteDataValue
, "RouteDataValue" é carregado noRouteData.Values["globalTemplate"]
(Order = 1
) e nãoRouteData.Values["aboutTemplate"]
(Order = 2
) devido à configuração da propriedadeOrder
. - Um modelo de rota
{otherPagesTemplate?}
é adicionado posteriormente no tópico. O modelo{otherPagesTemplate?}
recebe umaOrder
de2
. Quando qualquer página na pasta Pages/OtherPages é solicitada com um parâmetro de rota (por exemplo,/OtherPages/Page1/RouteDataValue
), "RouteDataValue" é carregado emRouteData.Values["globalTemplate"]
(Order = 1
) e nãoRouteData.Values["otherPagesTemplate"]
(Order = 2
) devido à configuração da propriedadeOrder
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
As opções das Páginas do Razor, como adicionar Conventions, são adicionadas quando o MVC é adicionado à coleção de serviços em Startup.ConfigureServices
. Para obter um exemplo, confira o aplicativo de exemplo.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Solicite a página About da amostra em localhost:5000/About/GlobalRouteValue
e inspecione o resultado:
Adicionar uma convenção de modelo de aplicativo a todas as páginas
Use Conventions para criar e adicionar um IPageApplicationModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo de aplicativo de página.
Para demonstrar isso e outras convenções mais adiante no tópico, o aplicativo de exemplo inclui uma classe AddHeaderAttribute
. O construtor de classe aceita uma cadeia de caracteres name
e uma matriz de cadeia de caracteres values
. Esses valores são usados em seu método OnResultExecuting
para definir um cabeçalho de resposta. A classe completa é mostrada na seção Convenções de ação do modelo de página mais adiante no tópico.
O aplicativo de exemplo usa a classe AddHeaderAttribute
para adicionar um cabeçalho, GlobalHeader
, a todas as páginas no aplicativo:
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());
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Adicionar uma convenção de modelo de manipulador a todas as páginas
Use Conventions para criar e adicionar um IPageHandlerModelConvention à coleção de instâncias IPageConvention que são aplicadas durante a construção do modelo do manipulador de página.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs
:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Convenções de ação da rota de página
O provedor de modelo de rota padrão derivado de IPageRouteModelProvider invoca convenções que foram projetadas para fornecer pontos de extensibilidade para configuração de rotas de página.
Convenção de modelo de rota de pasta
Use AddFolderRouteModelConvention para criar e adicionar um IPageRouteModelConvention que invoca uma ação no PageRouteModel para todas as páginas na pasta especificada.
O aplicativo de exemplo usa AddFolderRouteModelConvention para adicionar um modelo de rota {otherPagesTemplate?}
às páginas da pasta 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?}"),
}
});
}
});
A propriedade Order do AttributeRouteModel é definida como 2
. Isso garante que o modelo para {globalTemplate?}
(definido anteriormente no tópico como 1
) tenha prioridade para a primeira posição de valor de dados de rota quando um único valor de rota é fornecido. Se uma página na pasta Pages/OtherPages for solicitada com um valor de parâmetro de rota (por exemplo, /OtherPages/Page1/RouteDataValue
), "RouteDataValue" será carregado em RouteData.Values["globalTemplate"]
(Order = 1
) e não RouteData.Values["otherPagesTemplate"]
(Order = 2
) devido à configuração da propriedade Order
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
Solicite a página Page1 da amostra em localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue
e inspecione o resultado:
Convenção de modelo de rota de página
Use AddPageRouteModelConvention para criar e adicionar um IPageRouteModelConvention que invoca uma ação no PageRouteModel para a página no nome especificado.
O aplicativo de exemplo usa AddPageRouteModelConvention
para adicionar um modelo de rota {aboutTemplate?}
à página About:
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?}"),
}
});
}
});
A propriedade Order do AttributeRouteModel é definida como 2
. Isso garante que o modelo para {globalTemplate?}
(definido anteriormente no tópico como 1
) tenha prioridade para a primeira posição de valor de dados de rota quando um único valor de rota é fornecido. Se a página About for solicitada com um valor de parâmetro de rota no /About/RouteDataValue
, "RouteDataValue" será carregado no RouteData.Values["globalTemplate"]
(Order = 1
) e não RouteData.Values["aboutTemplate"]
(Order = 2
) devido à configuração da propriedade Order
.
Sempre que possível, não defina o Order
, que resulta em Order = 0
. Conte com o roteamento para selecionar a rota correta.
Solicite a página About da amostra em localhost:5000/About/GlobalRouteValue/AboutRouteValue
e inspecione o resultado:
Configurar uma rota de página
Use AddPageRoute para configurar uma rota para uma página no caminho de página especificado. Os links gerados para a página usam a rota especificada. AddPageRoute
usa AddPageRouteModelConvention
para estabelecer a rota.
O aplicativo de exemplo cria uma rota para /TheContactPage
para Contact.cshtml
:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
A página Contact também pode ser acessada em /Contact
por meio de sua rota padrão.
A rota personalizada do aplicativo de exemplo para a página Contact permite um segmento de rota text
opcional ({text?}
). A página também inclui esse segmento opcional em sua diretiva @page
, caso o visitante acesse a página em sua rota /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>
Observe que a URL gerada para o link Contato na página renderizada reflete a rota atualizada:
Visite a página Contact em sua rota comum, /Contact
, ou na rota personalizada, /TheContactPage
. Se você fornecer um segmento de rota text
adicional, a página mostrará o segmento codificado em HTML fornecido:
Convenções de ação do modelo de página
O provedor de modelo de página padrão que implementa IPageApplicationModelProvider invoca convenções que foram projetadas para fornecer pontos de extensibilidade para configuração de modelos de página. Essas convenções são úteis ao criar e modificar cenários de descoberta e processamento de página.
Para os exemplos desta seção, o aplicativo de exemplo usa uma classe AddHeaderAttribute
, que é um ResultFilterAttribute, aplicável a um cabeçalho de resposta:
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);
}
}
Usando convenções, a amostra explica como aplicar o atributo a todas as páginas de uma pasta e a uma única página.
Convenção de modelo de aplicativo de pasta
Use AddFolderApplicationModelConvention para criar e adicionar um IPageApplicationModelConvention que invoca uma ação em instâncias PageApplicationModel para todas as páginas na pasta especificada.
A amostra explica o uso de AddFolderApplicationModelConvention
adicionando um cabeçalho, OtherPagesHeader
, às páginas dentro da pasta OtherPages do aplicativo:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Solicite a página Page1 da amostra em localhost:5000/OtherPages/Page1
e inspecione os cabeçalhos para exibir o resultado:
Convenção de modelo de aplicativo de página
Use AddPageApplicationModelConvention para criar e adicionar um IPageApplicationModelConvention que invoca uma ação no PageApplicationModel para a página no nome especificado.
A amostra explica o uso de AddPageApplicationModelConvention
adicionando um cabeçalho, AboutHeader
, à página About:
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Configurar um filtro
ConfigureFilter configura o filtro especificado a ser aplicado. É possível implementar uma classe de filtro, mas o aplicativo de exemplo mostra como implementar um filtro em uma expressão lambda, que é implementado em segundo plano como um alocador que retorna um filtro:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
O modelo de aplicativo de página é usado para verificar o caminho relativo para segmentos que levam à página Page2 na pasta OtherPages. Se a condição é aprovada, um cabeçalho é adicionado. Caso contrário, o EmptyFilter
é aplicado.
EmptyFilter
é um filtro de Ação. Como os filtros de ação são ignorados por páginas Razor , o EmptyFilter
não terá o efeito pretendido se o caminho não contiver OtherPages/Page2
.
Solicite a página Page2 da amostra em localhost:5000/OtherPages/Page2
e inspecione os cabeçalhos para exibir o resultado:
Configurar um alocador de filtro
ConfigureFilter configura o alocador especificado para aplicar filtros a todas as Páginas Razor.
O aplicativo de exemplo fornece um exemplo de como usar um alocador de filtro adicionando um cabeçalho, FilterFactoryHeader
, com dois valores para as páginas do aplicativo:
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;
}
}
}
Solicite a página About da amostra em localhost:5000/About
e inspecione os cabeçalhos para exibir o resultado:
Filtros MVC e o filtro de Página (IPageFilter)
Os filtros de Ação MVC são ignorados pelas Páginas Razor, pois as páginas Razor usam métodos de manipulador. Outros tipos de filtros MVC estão disponíveis para uso: Autorização, Exceção, Recurso e Resultado. Para obter mais informações, consulte o tópico Filtros.
O filtro de Página (IPageFilter) é um filtro que se aplica às Páginas do Razor. Para obter mais informações, confira Métodos de filtragem para Páginas do Razor.