Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Узнайте, как использовать соглашения о маршруте страницы и поставщиках моделей приложений для управления маршрутизацией страниц, обнаружением и обработкой в Razor приложениях Pages.
Чтобы указать маршрут страницы, добавить сегменты маршрутов или добавить параметры в маршрут, используйте директиву страницы @page . Дополнительные сведения см. в разделе "Пользовательские маршруты".
Есть зарезервированные слова, которые нельзя использовать в качестве сегментов маршрутов или имен параметров. Дополнительные сведения см. в статье "Маршрутизация: зарезервированные имена маршрутизации".
Просмотр или скачивание примера кода (как скачать)
| Scenario | Пример демонстрирует |
|---|---|
|
Соглашения о модели Conventions.Add |
Добавьте шаблон маршрута и заголовок на страницы приложения. |
| Конвенции действия маршрута страницы | Добавьте шаблон маршрута на страницы в папке и на одну отдельную страницу. |
Соглашения об действии модели страницы
|
Добавьте заголовок на страницы в папку, добавьте заголовок на одну страницу и настройте фабрику фильтров для добавления заголовка на страницы приложения. |
Razor Конвенции страниц настраиваются с помощью AddRazorPages перегрузки, которая настраивает RazorPagesOptions. Ниже приведены примеры соглашений, описанные далее в этом разделе:
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( ... );
});
}
Порядок маршрутов
Маршруты указывают Order для обработки (сопоставления маршрутов).
| Порядок маршрутов | Behavior |
|---|---|
| -1 | Маршрут обрабатывается до обработки других маршрутов. |
| 0 | Порядок не указан (значение по умолчанию). Если не назначен Order (Order = null), маршрут Order по умолчанию устанавливается на 0 (ноль) для обработки. |
| 1, 2, … n | Задает порядок обработки маршрута. |
Обработка маршрутов устанавливается по стандарту:
- Маршруты обрабатываются последовательно (-1, 0, 1, 1, 2, ... n).
- Если маршруты имеют то же самое
Order, то наиболее конкретный маршрут сопоставляется сначала с менее конкретными маршрутами. - Если маршруты с одинаковым
Orderи одинаковым числом параметров соответствуют URL-адресу запроса, маршруты обрабатываются в том порядке, в котором они добавляются PageConventionCollection.
По возможности избегайте зависимости от установленного порядка обработки маршрутов. Как правило, маршрутизация выбирает правильный маршрут с сопоставлением URL-адресов. Если необходимо задать свойства маршрута Order для правильной маршрутизации запросов, схема маршрутизации приложения, вероятно, запутана для клиентов и сложна в поддержке. Стремится упростить схему маршрутизации приложения. Для примера приложения требуется явный порядок обработки маршрутов для демонстрации нескольких сценариев маршрутизации с помощью одного приложения. Однако следует попытаться избежать практики настройки маршрута Order в рабочих приложениях.
Razor Маршрутизация страниц и маршрутизация контроллера MVC используют одну и ту же реализацию. Сведения о порядке маршрута в разделах MVC доступны в разделе "Маршрутизация для действий контроллера: упорядочивание маршрутов атрибутов".
Соглашения о модели
Добавьте делегат для IPageConvention, чтобы добавить соглашения модели, применяемые к Razor Pages.
Добавление соглашения о модели маршрута на все страницы
Для создания и добавления Conventions в коллекцию экземпляров IPageRouteModelConvention, применяемых во время построения модели маршрутов страницы, используется IPageConvention.
Пример приложения содержит GlobalTemplatePageRouteModelConvention класс для добавления {globalTemplate?} шаблона маршрута ко всем страницам в приложении:
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?}"),
}
});
}
}
}
В предыдущем коде:
- Передается PageRouteModel методу Apply .
- PageRouteModel.Selectors получает количество селекторов.
- Добавлен новый объект SelectorModel , содержащий AttributeRouteModel
Razor Параметры страниц, такие как Conventions, добавляются при добавлении Razor страниц в коллекцию служб. Пример см. в примере приложения.
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();
Давайте рассмотрим класс 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?}"),
}
});
}
}
}
Для Order свойства AttributeRouteModel задано значение 1. Это гарантирует следующее поведение сопоставления маршрутов в примере приложения:
В этом разделе позже будет добавлен шаблон маршрута
TheContactPage/{text?}. МаршрутContact Pageимеет порядокnullпо умолчанию (Order = 0), поэтому он сопоставляется перед шаблоном маршрута{globalTemplate?}, который имеетOrder = 1.Шаблон
{aboutTemplate?}маршрута отображается в приведенном выше коде. Шаблон{aboutTemplate?}имеет значениеOrder2. Когда запрашивается страница About по адресу/About/RouteDataValue, "RouteDataValue" загружается вRouteData.Values["globalTemplate"](Order = 1) и не вRouteData.Values["aboutTemplate"](Order = 2) из-за установки свойстваOrder.Шаблон
{otherPagesTemplate?}маршрута показан в приведенном выше коде. Шаблон{otherPagesTemplate?}имеет значениеOrder2. Когда любая страница в папке Pages/OtherPages запрашивается с параметром маршрута:Например:
/OtherPages/Page1/xyzЗначение данных маршрута
"xyz"загружается вRouteData.Values["globalTemplate"](Order = 1).RouteData.Values["otherPagesTemplate"]с (Order = 2) не загружается из-за свойстваOrder2, имеющего более высокое значение.
По возможности не устанавливайте Orderпараметр . Если Order параметр не задан, по умолчанию используется Order = 0значение . Чтобы выбирать правильный маршрут, следует полагаться на маршрутизацию, а не на свойство Order.
Запросить страницу примера About на localhost:{port}/About/GlobalRouteValue и проверить результат.
Пример приложения использует пакет NuGet Rick.Docs.Samples.RouteInfo для отображения сведений о маршрутизации в выходных данных ведения журнала. Используя localhost:{port}/About/GlobalRouteValue, средство ведения журнала отображает запрос, Order, и использованный шаблон.
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue Order = 1 Template = About/{globalTemplate?}
Добавить соглашение модели приложения ко всем страницам
Используйте Conventions, чтобы создать и добавить IPageApplicationModelConvention в коллекцию экземпляров IPageConvention, которые применяются во время построения модели приложения страницы.
Чтобы продемонстрировать это и другие соглашения далее в разделе, пример приложения включает класс AddHeaderAttribute. Конструктор класса принимает name строку и values массив строк. Эти значения используются в методе OnResultExecuting для задания заголовка ответа. Полный класс отображается в разделе «Соглашения о действиях модели страницы» далее в этой теме.
Пример приложения использует AddHeaderAttribute класс для добавления заголовка GlobalHeader на все страницы в приложении.
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());
Запросите страницу сведений о образце на localhost:{port}/About и проверьте заголовки, чтобы просмотреть результат:
Добавьте соглашение модели обработчика ко всем страницам
Используйте Conventions для создания и добавления IPageHandlerModelConvention в коллекцию экземпляров IPageConvention, применяемых во время построения модели обработчика страниц.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Соглашения о поведении маршрутизации страницы
Поставщик модели маршрутов по умолчанию, производный от IPageRouteModelProvider, вызывает соглашения, предоставляющие точки расширяемости для настройки маршрута страницы.
Соглашение о модели маршрутов папок
Используйте AddFolderRouteModelConvention для создания и добавления IPageRouteModelConvention, которое вызывает действие на PageRouteModel для всех страниц в указанной папке.
Пример приложения использует AddFolderRouteModelConvention, чтобы добавить {otherPagesTemplate?} шаблон маршрута на страницы в папке 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?}"),
}
});
}
});
Для Order свойства AttributeRouteModel задано значение 2. Это гарантирует, что шаблон для {globalTemplate?} (заданный ранее в разделе 1) имеет приоритет для значения данных маршрута в первой позиции, если указано только одно значение маршрута. Если страница в папке Pages/OtherPages запрашивается со значением параметра маршрута (например, /OtherPages/Page1/RouteDataValue"RouteDataValue" загружается в RouteData.Values["globalTemplate"] (Order = 1) и не RouteData.Values["otherPagesTemplate"] (Order = 2) из-за задания Order свойства.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
Запросите страницу Page1 образца по адресу localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue и проверьте результат:
Конвенция модели маршрутизации страниц
Используйте AddPageRouteModelConvention, чтобы создать и добавить IPageRouteModelConvention, который выполнит действие на PageRouteModel, ассоциированном со страницей с указанным именем.
Пример приложения использует AddPageRouteModelConvention для добавления {aboutTemplate?} шаблона маршрута на страницу "О программе":
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?}"),
}
});
}
});
Для Order свойства AttributeRouteModel задано значение 2. Это гарантирует, что шаблон для {globalTemplate?} (заданный ранее в разделе 1) имеет приоритет для значения данных маршрута в первой позиции, если указано только одно значение маршрута. Если страница About запрашивается со значением параметра маршрута по /About/RouteDataValue адресу, "RouteDataValue" загружается в RouteData.Values["globalTemplate"] (Order = 1) и не RouteData.Values["aboutTemplate"] (Order = 2) из-за установки свойства Order.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
Запросите страницу localhost:{port}/About/GlobalRouteValue/AboutRouteValue "Сведения о образце" и проверьте результат:
Выходные данные средства ведения журнала отображаются:
info: SampleApp.Pages.AboutModel[0]
/About/GlobalRouteValue/AboutRouteValue Order = 2 Template = About/{globalTemplate?}/{aboutTemplate?}
Использование преобразователя параметров для настройки маршрутов страниц
См. преобразователи параметров.
Настройка маршрута страницы
Используйте AddPageRoute для настройки маршрута к странице по указанному пути. Созданные ссылки на страницу используют указанный маршрут. AddPageRoute используется AddPageRouteModelConvention для установки маршрута.
Пример приложения создает маршрут /TheContactPage для ContactRazor страницы:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
Страницу Contact также можно открыть на /Contact1 по маршруту по умолчанию.
Настраиваемый маршрут примера приложения на Contact страницу позволяет использовать необязательный text сегмент маршрута ({text?}). Страница также включает этот необязательный сегмент в директиву @page , если посетитель обращается к странице по его /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>
Обратите внимание, что URL-адрес, созданный для ссылки "Контакт" на отрисованной странице, отражает обновленный маршрут:
Посетите страницу Contact либо по её обычному маршруту, /Contact, либо по пользовательскому маршруту, /TheContactPage. Если вы предоставляете дополнительный text сегмент маршрута, на странице отображается предоставленный сегмент в кодировке HTML:
Соглашения об действии модели страницы
Поставщик модели страниц по умолчанию, реализующий соглашения через IPageApplicationModelProvider, предназначен для предоставления точек расширения для настройки моделей страниц. Эти соглашения полезны при создании и изменении сценариев обнаружения и обработки страниц.
В примерах этого раздела образец приложения использует класс AddHeaderAttribute, который применяет заголовок ответа ResultFilterAttribute:
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);
}
}
С помощью соглашений в примере показано, как применить атрибут ко всем страницам в папке и к одной странице.
Соглашение о модели приложения папок
Используйте AddFolderApplicationModelConvention для создания и добавления IPageApplicationModelConvention, который инициирует действие на PageApplicationModel экземплярах для всех страниц в указанной папке.
В примере демонстрируется использование AddFolderApplicationModelConvention путем добавления заголовка в OtherPagesHeaderстраницы в папке OtherPages приложения:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Запросите страницу Page1 из примера localhost:5000/OtherPages/Page1 и проверьте заголовки, чтобы увидеть результат.
Соглашение о модели приложения страницы
Используйте AddPageApplicationModelConvention, чтобы создать и добавить IPageApplicationModelConvention, который выполнит действие на PageApplicationModel, ассоциированном со страницей с указанным именем.
Пример демонстрирует использование AddPageApplicationModelConvention путем добавления заголовка AboutHeader на страницу "Сведения":
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Настройка фильтра
ConfigureFilter настраивает указанный фильтр для применения. Класс фильтра можно реализовать, но в примере приложения показано, как реализовать фильтр в лямбда-выражении, которое реализуется за кулисами как фабрика, которая возвращает фильтр:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Модель приложения страниц используется для проверки относительного пути к сегментам, которые ведут на страницу Page2 в папке OtherPages. Если условие проходит, добавляется заголовок. В противном случае применяется EmptyFilter.
EmptyFilter — это фильтр действий. Так как фильтры действий игнорируются Страницами Razor, предполагаемый эффект EmptyFilter отсутствует, если путь не содержит OtherPages/Page2.
Запросите страницу Page2 localhost:5000/OtherPages/Page2 примера и проверьте заголовки, чтобы просмотреть результат:
Настройка фабрики фильтров
ConfigureFilterнастраивает указанную фабрику для применения фильтров ко всем Razorстраницам.
Пример приложения предоставляет пример использования фабрики фильтров путем добавления заголовка с FilterFactoryHeaderдвумя значениями на страницы приложения:
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;
}
}
}
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Фильтры MVC и фильтр страницы (IPageFilter)
Фильтры действий MVC игнорируются Razor Страницами, поскольку Razor Страницы используют методы обработчика. Другие типы фильтров MVC доступны для использования: авторизация, исключение, ресурс и результат. Дополнительные сведения см. в разделе "Фильтры ".
Фильтр страниц (IPageFilter) — это фильтр, который применяется к Razor Страницам. Дополнительные сведения см. в разделе Методы фильтрации для Razor Pages.
Дополнительные ресурсы
Узнайте, как использовать соглашения о маршруте страницы и поставщиках моделей приложений для управления маршрутизацией страниц, обнаружением и обработкой в Razor приложениях Pages.
Если необходимо настроить маршруты для отдельных страниц, настройте маршрутизацию страниц с помощью соглашения AddPageRoute, описанного далее в этом разделе.
Чтобы указать маршрут страницы, добавить сегменты маршрутов или добавить параметры в маршрут, используйте директиву страницы @page . Дополнительные сведения см. в разделе "Пользовательские маршруты".
Есть зарезервированные слова, которые нельзя использовать в качестве сегментов маршрутов или имен параметров. Дополнительные сведения см. в статье "Маршрутизация: зарезервированные имена маршрутизации".
Просмотр или скачивание примера кода (как скачать)
| Scenario | Образец демонстрирует ... |
|---|---|
|
Соглашения о модели Conventions.Add
|
Добавьте шаблон маршрута и заголовок на страницы приложения. |
Конвенции действия маршрута страницы
|
Добавьте шаблон маршрута на страницы в папке и на одну отдельную страницу. |
Соглашения об действии модели страницы
|
Добавьте заголовок на страницы в папку, добавьте заголовок на одну страницу и настройте фабрику фильтров для добавления заголовка на страницы приложения. |
Razor Соглашения для pages настраиваются с помощью AddRazorPages перегрузки, которая конфигурирует RazorPagesOptions в Startup.ConfigureServices. Ниже приведены примеры соглашений, описанные далее в этом разделе:
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( ... );
});
}
Порядок маршрутов
Маршруты указывают Order для обработки (сопоставления маршрутов).
| Order | Behavior |
|---|---|
| -1 | Маршрут обрабатывается до обработки других маршрутов. |
| 0 | Порядок не указан (значение по умолчанию). Если не назначен Order (Order = null), маршрут Order по умолчанию устанавливается на 0 (ноль) для обработки. |
| 1, 2, … n | Задает порядок обработки маршрута. |
Обработка маршрутов устанавливается по стандарту:
- Маршруты обрабатываются последовательно (-1, 0, 1, 1, 2, ... n).
- Если маршруты имеют то же самое
Order, то наиболее конкретный маршрут сопоставляется сначала с менее конкретными маршрутами. - Если маршруты с одинаковым
Orderи одинаковым числом параметров соответствуют URL-адресу запроса, маршруты обрабатываются в том порядке, в котором они добавляются PageConventionCollection.
По возможности избегайте зависимости от установленного порядка обработки маршрутов. Как правило, маршрутизация выбирает правильный маршрут с сопоставлением URL-адресов. Если необходимо задать свойства маршрута Order для правильной маршрутизации запросов, схема маршрутизации приложения, вероятно, запутана для клиентов и сложна в поддержке. Стремится упростить схему маршрутизации приложения. Для примера приложения требуется явный порядок обработки маршрутов для демонстрации нескольких сценариев маршрутизации с помощью одного приложения. Однако следует попытаться избежать практики настройки маршрута Order в рабочих приложениях.
Razor Маршрутизация страниц и маршрутизация контроллера MVC используют одну и ту же реализацию. Сведения о порядке маршрута в разделах MVC доступны в разделе "Маршрутизация для действий контроллера: упорядочивание маршрутов атрибутов".
Соглашения о модели
Добавьте делегат для IPageConvention, чтобы добавить соглашения модели, применяемые к Razor Pages.
Добавление соглашения о модели маршрута на все страницы
Для создания и добавления Conventions в коллекцию экземпляров IPageRouteModelConvention, применяемых во время построения модели маршрутов страницы, используется IPageConvention.
Пример приложения добавляет {globalTemplate?} шаблон маршрута ко всем страницам в приложении:
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?}"),
}
});
}
}
}
Для Order свойства AttributeRouteModel задано значение 1. Это гарантирует следующее поведение сопоставления маршрутов в примере приложения:
- Шаблон маршрута
TheContactPage/{text?}добавляется позже в теме. Маршрут страницы контактов имеет порядокnullпо умолчанию (Order = 0), поэтому он соответствует перед шаблоном маршрута{globalTemplate?}. - Шаблон
{aboutTemplate?}маршрута добавляется позже в раздел. Шаблон{aboutTemplate?}имеет значениеOrder2. Когда запрашивается страница About по адресу/About/RouteDataValue, "RouteDataValue" загружается вRouteData.Values["globalTemplate"](Order = 1) и не вRouteData.Values["aboutTemplate"](Order = 2) из-за установки свойстваOrder. - Шаблон
{otherPagesTemplate?}маршрута добавляется позже в раздел. Шаблон{otherPagesTemplate?}имеет значениеOrder2. Если любая страница в папке Pages/OtherPages запрашивается с параметром маршрута (например,/OtherPages/Page1/RouteDataValue), "RouteDataValue" загружается вRouteData.Values["globalTemplate"](Order = 1), а не вRouteData.Values["otherPagesTemplate"](Order = 2) вследствие настройки свойстваOrder.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
RazorПараметры страниц, такие как добавление Conventions, добавляются, когда Razor Pages добавляется в коллекцию служб Startup.ConfigureServices. Пример см. в примере приложения.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Запросите страницу localhost:5000/About/GlobalRouteValue "Сведения о образце" и проверьте результат:
Добавить соглашение модели приложения ко всем страницам
Используйте Conventions, чтобы создать и добавить IPageApplicationModelConvention в коллекцию экземпляров IPageConvention, которые применяются во время построения модели приложения страницы.
Чтобы продемонстрировать это и другие соглашения далее в разделе, пример приложения включает класс AddHeaderAttribute. Конструктор класса принимает name строку и values массив строк. Эти значения используются в методе OnResultExecuting для задания заголовка ответа. Полный класс отображается в разделе «Соглашения о действиях модели страницы» далее в этой теме.
Пример приложения использует AddHeaderAttribute класс для добавления заголовка GlobalHeader на все страницы в приложении.
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());
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Добавьте соглашение модели обработчика ко всем страницам
Используйте Conventions для создания и добавления IPageHandlerModelConvention в коллекцию экземпляров IPageConvention, применяемых во время построения модели обработчика страниц.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Соглашения о поведении маршрутизации страницы
Поставщик модели маршрутов по умолчанию, производный от IPageRouteModelProvider, вызывает соглашения, предоставляющие точки расширяемости для настройки маршрута страницы.
Соглашение о модели маршрутов папок
Используйте AddFolderRouteModelConvention для создания и добавления IPageRouteModelConvention, которое вызывает действие на PageRouteModel для всех страниц в указанной папке.
Пример приложения использует AddFolderRouteModelConvention, чтобы добавить {otherPagesTemplate?} шаблон маршрута на страницы в папке 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?}"),
}
});
}
});
Для Order свойства AttributeRouteModel задано значение 2. Это гарантирует, что шаблон для {globalTemplate?} (заданный ранее в разделе 1) имеет приоритет для значения данных маршрута в первой позиции, если указано только одно значение маршрута. Если страница в папке Pages/OtherPages запрашивается со значением параметра маршрута (например, /OtherPages/Page1/RouteDataValue"RouteDataValue" загружается в RouteData.Values["globalTemplate"] (Order = 1) и не RouteData.Values["otherPagesTemplate"] (Order = 2) из-за задания Order свойства.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
Запросите страницу Page1 образца по адресу localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue и проверьте результат:
Конвенция модели маршрутизации страниц
Используйте AddPageRouteModelConvention, чтобы создать и добавить IPageRouteModelConvention, который выполнит действие на PageRouteModel, ассоциированном со страницей с указанным именем.
Пример приложения использует AddPageRouteModelConvention для добавления {aboutTemplate?} шаблона маршрута на страницу "О программе":
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?}"),
}
});
}
});
Для Order свойства AttributeRouteModel задано значение 2. Это гарантирует, что шаблон для {globalTemplate?} (заданный ранее в разделе 1) имеет приоритет для значения данных маршрута в первой позиции, если указано только одно значение маршрута. Если страница About запрашивается со значением параметра маршрута по /About/RouteDataValue адресу, "RouteDataValue" загружается в RouteData.Values["globalTemplate"] (Order = 1) и не RouteData.Values["aboutTemplate"] (Order = 2) из-за установки свойства Order.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
Запросите страницу localhost:5000/About/GlobalRouteValue/AboutRouteValue "Сведения о образце" и проверьте результат:
Использование преобразователя параметров для настройки маршрутов страниц
Маршруты страниц, созданные ASP.NET Core, можно настроить с помощью преобразователя параметров. Преобразователь параметров реализует IOutboundParameterTransformer и преобразует значения параметров. Например, настраиваемый преобразователь параметров SlugifyParameterTransformer изменяет значение маршрута SubscriptionManagement на subscription-management.
Соглашение PageRouteTransformerConvention о модели маршрутов страницы применяет преобразователь параметров к сегментам папок и имен файлов автоматически созданных маршрутов страниц в приложении. Например, файл Pages по адресу Razor будет переписан маршрут с /Pages/SubscriptionManagement/ViewAll.cshtml на /SubscriptionManagement/ViewAll.
PageRouteTransformerConvention преобразует только автоматически созданные сегменты маршрута страницы, поступающие из Razor папки Pages и имени файла. Он не преобразует сегменты маршрутов, добавленные с помощью директивы @page. Соглашение также не преобразует маршруты, добавленные AddPageRoute.
PageRouteTransformerConvention зарегистрирован как опция в 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();
}
}
Warning
При использовании System.Text.RegularExpressions для обработки ненадежных входных данных передайте время ожидания. Злонамеренный пользователь может предоставить входные данные для RegularExpressions, что делает возможными атаки типа "отказ в обслуживании". API платформы ASP.NET Core, использующие RegularExpressions, передают время ожидания.
Настройка маршрута страницы
Используйте AddPageRoute для настройки маршрута к странице по указанному пути. Созданные ссылки на страницу используют указанный маршрут.
AddPageRoute используется AddPageRouteModelConvention для установки маршрута.
Пример приложения создает маршрут к /TheContactPage для Contact.cshtml:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
Страницу контакты также можно открыть /Contact через маршрут по умолчанию.
Пользовательский маршрут примера приложения на страницу "Контакт" позволяет использовать необязательный text сегмент маршрута ({text?}). Страница также включает этот необязательный сегмент в директиву @page , если посетитель обращается к странице по его /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>
Обратите внимание, что URL-адрес, созданный для ссылки "Контакт" на отрисованной странице, отражает обновленный маршрут:
Посетите страницу "Контакт" либо по его обычному маршруту, /Contactлибо по пользовательскому маршруту. /TheContactPage Если вы предоставляете дополнительный text сегмент маршрута, на странице отображается предоставленный сегмент в кодировке HTML:
Соглашения об действии модели страницы
Поставщик модели страниц по умолчанию, реализующий соглашения через IPageApplicationModelProvider, предназначен для предоставления точек расширения для настройки моделей страниц. Эти соглашения полезны при создании и изменении сценариев обнаружения и обработки страниц.
В примерах этого раздела образец приложения использует класс AddHeaderAttribute, который применяет заголовок ответа ResultFilterAttribute:
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);
}
}
С помощью соглашений в примере показано, как применить атрибут ко всем страницам в папке и к одной странице.
Соглашение о модели приложения папок
Используйте AddFolderApplicationModelConvention для создания и добавления IPageApplicationModelConvention, который инициирует действие на PageApplicationModel экземплярах для всех страниц в указанной папке.
В примере демонстрируется использование AddFolderApplicationModelConvention путем добавления заголовка в OtherPagesHeaderстраницы в папке OtherPages приложения:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Запросите страницу Page1 из примера localhost:5000/OtherPages/Page1 и проверьте заголовки, чтобы увидеть результат.
Соглашение о модели приложения страницы
Используйте AddPageApplicationModelConvention, чтобы создать и добавить IPageApplicationModelConvention, который выполнит действие на PageApplicationModel, ассоциированном со страницей с указанным именем.
Пример демонстрирует использование AddPageApplicationModelConvention путем добавления заголовка AboutHeader на страницу "Сведения":
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Настройка фильтра
ConfigureFilter настраивает указанный фильтр для применения. Класс фильтра можно реализовать, но в примере приложения показано, как реализовать фильтр в лямбда-выражении, которое реализуется за кулисами как фабрика, которая возвращает фильтр:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Модель приложения страниц используется для проверки относительного пути к сегментам, которые ведут на страницу Page2 в папке OtherPages. Если условие проходит, добавляется заголовок. В противном случае применяется EmptyFilter.
EmptyFilter — это фильтр действий. Так как фильтры действий игнорируются Страницами Razor, предполагаемый эффект EmptyFilter отсутствует, если путь не содержит OtherPages/Page2.
Запросите страницу Page2 localhost:5000/OtherPages/Page2 примера и проверьте заголовки, чтобы просмотреть результат:
Настройка фабрики фильтров
ConfigureFilterнастраивает указанную фабрику для применения фильтров ко всем Razorстраницам.
Пример приложения предоставляет пример использования фабрики фильтров путем добавления заголовка с FilterFactoryHeaderдвумя значениями на страницы приложения:
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;
}
}
}
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Фильтры MVC и фильтр страницы (IPageFilter)
Фильтры действий MVC игнорируются Razor Страницами, поскольку Razor Страницы используют методы обработчика. Другие типы фильтров MVC доступны для использования: авторизация, исключение, ресурс и результат. Дополнительные сведения см. в разделе "Фильтры ".
Фильтр страниц (IPageFilter) — это фильтр, который применяется к Razor Страницам. Дополнительные сведения см. в разделе Методы фильтрации для Razor Pages.
Дополнительные ресурсы
Узнайте, как использовать соглашения о маршруте страницы и поставщиках моделей приложений для управления маршрутизацией страниц, обнаружением и обработкой в Razor приложениях Pages.
Если необходимо настроить маршруты для отдельных страниц, настройте маршрутизацию страниц с помощью соглашения AddPageRoute, описанного далее в этом разделе.
Чтобы указать маршрут страницы, добавить сегменты маршрутов или добавить параметры в маршрут, используйте директиву страницы @page . Дополнительные сведения см. в разделе "Пользовательские маршруты".
Есть зарезервированные слова, которые нельзя использовать в качестве сегментов маршрутов или имен параметров. Дополнительные сведения см. в статье "Маршрутизация: зарезервированные имена маршрутизации".
Просмотр или скачивание примера кода (как скачать)
| Scenario | Образец демонстрирует ... |
|---|---|
|
Соглашения о модели Conventions.Add
|
Добавьте шаблон маршрута и заголовок на страницы приложения. |
Конвенции действия маршрута страницы
|
Добавьте шаблон маршрута на страницы в папке и на одну отдельную страницу. |
Соглашения об действии модели страницы
|
Добавьте заголовок на страницы в папку, добавьте заголовок на одну страницу и настройте фабрику фильтров для добавления заголовка на страницы приложения. |
Razor Соглашения Pages добавляются и настраиваются с помощью AddRazorPagesOptions метода AddMvc расширения для коллекции служб в Startup классе. Ниже приведены примеры соглашений, описанные далее в этом разделе:
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( ... );
});
}
Порядок маршрутов
Маршруты указывают Order для обработки (сопоставления маршрутов).
| Order | Behavior |
|---|---|
| -1 | Маршрут обрабатывается до обработки других маршрутов. |
| 0 | Порядок не указан (значение по умолчанию). Если не назначен Order (Order = null), маршрут Order по умолчанию устанавливается на 0 (ноль) для обработки. |
| 1, 2, … n | Задает порядок обработки маршрута. |
Обработка маршрутов устанавливается по стандарту:
- Маршруты обрабатываются последовательно (-1, 0, 1, 1, 2, ... n).
- Если маршруты имеют то же самое
Order, то наиболее конкретный маршрут сопоставляется сначала с менее конкретными маршрутами. - Если маршруты с одинаковым
Orderи одинаковым числом параметров соответствуют URL-адресу запроса, маршруты обрабатываются в том порядке, в котором они добавляются PageConventionCollection.
По возможности избегайте зависимости от установленного порядка обработки маршрутов. Как правило, маршрутизация выбирает правильный маршрут с сопоставлением URL-адресов. Если необходимо задать свойства маршрута Order для правильной маршрутизации запросов, схема маршрутизации приложения, вероятно, запутана для клиентов и сложна в поддержке. Стремится упростить схему маршрутизации приложения. Для примера приложения требуется явный порядок обработки маршрутов для демонстрации нескольких сценариев маршрутизации с помощью одного приложения. Однако следует попытаться избежать практики настройки маршрута Order в рабочих приложениях.
Razor Маршрутизация страниц и маршрутизация контроллера MVC используют одну и ту же реализацию. Сведения о порядке маршрута в разделах MVC доступны в разделе "Маршрутизация для действий контроллера: упорядочивание маршрутов атрибутов".
Соглашения о модели
Добавьте делегат для IPageConvention, чтобы добавить соглашения модели, применяемые к Razor Pages.
Добавление соглашения о модели маршрута на все страницы
Для создания и добавления Conventions в коллекцию экземпляров IPageRouteModelConvention, применяемых во время построения модели маршрутов страницы, используется IPageConvention.
Пример приложения добавляет {globalTemplate?} шаблон маршрута ко всем страницам в приложении:
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?}"),
}
});
}
}
}
Для Order свойства AttributeRouteModel задано значение 1. Это гарантирует следующее поведение сопоставления маршрутов в примере приложения:
- Шаблон маршрута
TheContactPage/{text?}добавляется позже в теме. Маршрут страницы контактов имеет порядокnullпо умолчанию (Order = 0), поэтому он соответствует перед шаблоном маршрута{globalTemplate?}. - Шаблон
{aboutTemplate?}маршрута добавляется позже в раздел. Шаблон{aboutTemplate?}имеет значениеOrder2. Когда запрашивается страница About по адресу/About/RouteDataValue, "RouteDataValue" загружается вRouteData.Values["globalTemplate"](Order = 1) и не вRouteData.Values["aboutTemplate"](Order = 2) из-за установки свойстваOrder. - Шаблон
{otherPagesTemplate?}маршрута добавляется позже в раздел. Шаблон{otherPagesTemplate?}имеет значениеOrder2. Если любая страница в папке Pages/OtherPages запрашивается с параметром маршрута (например,/OtherPages/Page1/RouteDataValue), "RouteDataValue" загружается вRouteData.Values["globalTemplate"](Order = 1), а не вRouteData.Values["otherPagesTemplate"](Order = 2) вследствие настройки свойстваOrder.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
RazorПараметры страниц, например добавлениеConventions, добавляются при добавлении MVC в коллекцию служб.Startup.ConfigureServices Пример см. в примере приложения.
options.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
Запросите страницу localhost:5000/About/GlobalRouteValue "Сведения о образце" и проверьте результат:
Добавить соглашение модели приложения ко всем страницам
Используйте Conventions, чтобы создать и добавить IPageApplicationModelConvention в коллекцию экземпляров IPageConvention, которые применяются во время построения модели приложения страницы.
Чтобы продемонстрировать это и другие соглашения далее в разделе, пример приложения включает класс AddHeaderAttribute. Конструктор класса принимает name строку и values массив строк. Эти значения используются в методе OnResultExecuting для задания заголовка ответа. Полный класс отображается в разделе «Соглашения о действиях модели страницы» далее в этой теме.
Пример приложения использует AddHeaderAttribute класс для добавления заголовка GlobalHeader на все страницы в приложении.
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());
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Добавьте соглашение модели обработчика ко всем страницам
Используйте Conventions для создания и добавления IPageHandlerModelConvention в коллекцию экземпляров IPageConvention, применяемых во время построения модели обработчика страниц.
public class GlobalPageHandlerModelConvention
: IPageHandlerModelConvention
{
public void Apply(PageHandlerModel model)
{
// Access the PageHandlerModel
}
}
Startup.cs:
options.Conventions.Add(new GlobalPageHandlerModelConvention());
Соглашения о поведении маршрутизации страницы
Поставщик модели маршрутов по умолчанию, производный от IPageRouteModelProvider, вызывает соглашения, предоставляющие точки расширяемости для настройки маршрута страницы.
Соглашение о модели маршрутов папок
Используйте AddFolderRouteModelConvention для создания и добавления IPageRouteModelConvention, которое вызывает действие на PageRouteModel для всех страниц в указанной папке.
Пример приложения использует AddFolderRouteModelConvention, чтобы добавить {otherPagesTemplate?} шаблон маршрута на страницы в папке 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?}"),
}
});
}
});
Для Order свойства AttributeRouteModel задано значение 2. Это гарантирует, что шаблон для {globalTemplate?} (заданный ранее в разделе 1) имеет приоритет для значения данных маршрута в первой позиции, если указано только одно значение маршрута. Если страница в папке Pages/OtherPages запрашивается со значением параметра маршрута (например, /OtherPages/Page1/RouteDataValue"RouteDataValue" загружается в RouteData.Values["globalTemplate"] (Order = 1) и не RouteData.Values["otherPagesTemplate"] (Order = 2) из-за задания Order свойства.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
Запросите страницу Page1 образца по адресу localhost:5000/OtherPages/Page1/GlobalRouteValue/OtherPagesRouteValue и проверьте результат:
Конвенция модели маршрутизации страниц
Используйте AddPageRouteModelConvention, чтобы создать и добавить IPageRouteModelConvention, который выполнит действие на PageRouteModel, ассоциированном со страницей с указанным именем.
Пример приложения использует AddPageRouteModelConvention для добавления {aboutTemplate?} шаблона маршрута на страницу "О программе":
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?}"),
}
});
}
});
Для Order свойства AttributeRouteModel задано значение 2. Это гарантирует, что шаблон для {globalTemplate?} (заданный ранее в разделе 1) имеет приоритет для значения данных маршрута в первой позиции, если указано только одно значение маршрута. Если страница About запрашивается со значением параметра маршрута по /About/RouteDataValue адресу, "RouteDataValue" загружается в RouteData.Values["globalTemplate"] (Order = 1) и не RouteData.Values["aboutTemplate"] (Order = 2) из-за установки свойства Order.
Если это возможно, не устанавливайте Order, что приводит к Order = 0. Чтобы выбрать правильный маршрут, следует полагаться на маршрутизацию.
Запросите страницу localhost:5000/About/GlobalRouteValue/AboutRouteValue "Сведения о образце" и проверьте результат:
Настройка маршрута страницы
Используйте AddPageRoute для настройки маршрута к странице по указанному пути. Созданные ссылки на страницу используют указанный маршрут.
AddPageRoute используется AddPageRouteModelConvention для установки маршрута.
Пример приложения создает маршрут к /TheContactPage для Contact.cshtml:
options.Conventions.AddPageRoute("/Contact", "TheContactPage/{text?}");
Страницу контакты также можно открыть /Contact через маршрут по умолчанию.
Пользовательский маршрут примера приложения на страницу "Контакт" позволяет использовать необязательный text сегмент маршрута ({text?}). Страница также включает этот необязательный сегмент в директиву @page , если посетитель обращается к странице по его /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>
Обратите внимание, что URL-адрес, созданный для ссылки "Контакт" на отрисованной странице, отражает обновленный маршрут:
Посетите страницу "Контакт" либо по его обычному маршруту, /Contactлибо по пользовательскому маршруту. /TheContactPage Если вы предоставляете дополнительный text сегмент маршрута, на странице отображается предоставленный сегмент в кодировке HTML:
Соглашения об действии модели страницы
Поставщик модели страниц по умолчанию, реализующий соглашения через IPageApplicationModelProvider, предназначен для предоставления точек расширения для настройки моделей страниц. Эти соглашения полезны при создании и изменении сценариев обнаружения и обработки страниц.
В примерах этого раздела образец приложения использует класс AddHeaderAttribute, который применяет заголовок ответа ResultFilterAttribute:
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);
}
}
С помощью соглашений в примере показано, как применить атрибут ко всем страницам в папке и к одной странице.
Соглашение о модели приложения папок
Используйте AddFolderApplicationModelConvention для создания и добавления IPageApplicationModelConvention, который инициирует действие на PageApplicationModel экземплярах для всех страниц в указанной папке.
В примере демонстрируется использование AddFolderApplicationModelConvention путем добавления заголовка в OtherPagesHeaderстраницы в папке OtherPages приложения:
options.Conventions.AddFolderApplicationModelConvention("/OtherPages", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"OtherPagesHeader", new string[] { "OtherPages Header Value" }));
});
Запросите страницу Page1 из примера localhost:5000/OtherPages/Page1 и проверьте заголовки, чтобы увидеть результат.
Соглашение о модели приложения страницы
Используйте AddPageApplicationModelConvention, чтобы создать и добавить IPageApplicationModelConvention, который выполнит действие на PageApplicationModel, ассоциированном со страницей с указанным именем.
Пример демонстрирует использование AddPageApplicationModelConvention путем добавления заголовка AboutHeader на страницу "Сведения":
options.Conventions.AddPageApplicationModelConvention("/About", model =>
{
model.Filters.Add(new AddHeaderAttribute(
"AboutHeader", new string[] { "About Header Value" }));
});
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Настройка фильтра
ConfigureFilter настраивает указанный фильтр для применения. Класс фильтра можно реализовать, но в примере приложения показано, как реализовать фильтр в лямбда-выражении, которое реализуется за кулисами как фабрика, которая возвращает фильтр:
options.Conventions.ConfigureFilter(model =>
{
if (model.RelativePath.Contains("OtherPages/Page2"))
{
return new AddHeaderAttribute(
"OtherPagesPage2Header",
new string[] { "OtherPages/Page2 Header Value" });
}
return new EmptyFilter();
});
Модель приложения страниц используется для проверки относительного пути к сегментам, которые ведут на страницу Page2 в папке OtherPages. Если условие проходит, добавляется заголовок. В противном случае применяется EmptyFilter.
EmptyFilter — это фильтр действий. Так как фильтры действий игнорируются Страницами Razor, предполагаемый эффект EmptyFilter отсутствует, если путь не содержит OtherPages/Page2.
Запросите страницу Page2 localhost:5000/OtherPages/Page2 примера и проверьте заголовки, чтобы просмотреть результат:
Настройка фабрики фильтров
ConfigureFilterнастраивает указанную фабрику для применения фильтров ко всем Razorстраницам.
Пример приложения предоставляет пример использования фабрики фильтров путем добавления заголовка с FilterFactoryHeaderдвумя значениями на страницы приложения:
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;
}
}
}
Запросите страницу сведений о образце на localhost:5000/About и проверьте заголовки, чтобы просмотреть результат:
Фильтры MVC и фильтр страницы (IPageFilter)
Фильтры действий MVC игнорируются Razor Страницами, поскольку Razor Страницы используют методы обработчика. Другие типы фильтров MVC доступны для использования: авторизация, исключение, ресурс и результат. Дополнительные сведения см. в разделе "Фильтры ".
Фильтр страниц (IPageFilter) — это фильтр, который применяется к Razor Страницам. Дополнительные сведения см. в разделе Методы фильтрации для Razor Pages.