Razor 页面自定义路由
Razor pages custom routes
我正在尝试遵循路线,所以我有 GlobalTemplatePageRouteModelConvention。
我用的是int?将 /1 与 /ListJson 处理程序区分开来的约束,但我对此并不满意,它不必要地检查每个路由的整数。
这是理想的解决方案吗?我怎样才能让它变得更好?
页数;
/Index.cshtml
/MainTestPage.cshtml
/TestDir/Index.cshtml
/TestDir/TestPage.cshtml
处理程序;
public void OnGet(int? id)
public void OnGetListJson(int? id)
路线;
"/",
"/1",
"/ListJson",
"/ListJson/1",
"/MainTestPage",
"/MainTestPage/1",
"/MainTestPage/ListJson",
"/MainTestPage/ListJson/1",
"/TestDir",
"/TestDir/1",
"/TestDir/ListJson",
"/TestDir/ListJson/1",
"/TestDir/TestPage",
"/TestDir/TestPage/1",
"/TestDir/TestPage/ListJson",
"/TestDir/TestPage/ListJson/1",
代码;
public class GlobalTemplatePageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
var list = new List<SelectorModel>();
var isIndexPage = model.ViewEnginePath.EndsWith("/Index", StringComparison.OrdinalIgnoreCase);
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
var template = selector.AttributeRouteModel.Template;
var isIndexRoute = template.EndsWith("Index", StringComparison.OrdinalIgnoreCase);
if (isIndexPage)
{
if (isIndexRoute)
{
list.Add(selector);
}
else
{
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -2,
Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{id:int?}")
}
});
selector.AttributeRouteModel.Order = -1;
selector.AttributeRouteModel.Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{handler?}/{id?}");
}
}
else
{
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -4,
Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{id:int?}")
}
});
selector.AttributeRouteModel.Order = -3;
selector.AttributeRouteModel.Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{handler?}/{id?}");
}
}
foreach (var selector in list)
model.Selectors.Remove(selector);
}
}
builder.AddRazorPagesOptions(o => {
o.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
}
最后,我更喜欢遵循路由模板约定,这样可以消除 int 约束并且不会因此而损失性能。
- 模板是全局指定的,而不是在每个页面的@page 指令中指定。
- 索引路由(/Index/1)用于未命名的处理程序、OnGet 等
- 适用于以下路线;
"/",
"/Index/1",
"/ListJson",
"/ListJson/1",
"/MainTestPage",
"/MainTestPage/Index/1",
"/MainTestPage/ListJson",
"/MainTestPage/ListJson/1",
"/TestDir",
"/TestDir/Index/1",
"/TestDir/ListJson",
"/TestDir/ListJson/1",
"/TestDir/TestPage",
"/TestDir/TestPage/Index/1",
"/TestDir/TestPage/ListJson",
"/TestDir/TestPage/ListJson/1",
- GlobalTemplatePageRouteModelConvention;
- 索引路由导致不匹配,因此将其删除。
builder.AddRazorPagesOptions(o =>
{
o.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
});
public class GlobalTemplatePageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var isIndexPage = model.ViewEnginePath.EndsWith("/Index", StringComparison.OrdinalIgnoreCase);
foreach (var selector in model.Selectors.ToList())
{
var template = selector.AttributeRouteModel.Template;
if (isIndexPage)
{
var isIndexRoute = template.EndsWith("Index", StringComparison.OrdinalIgnoreCase);
if (isIndexRoute)
{
model.Selectors.Remove(selector);
continue;
}
}
selector.AttributeRouteModel.Template =
AttributeRouteModel.CombineTemplates(template,
"{handler?}/{id?}");
}
}
}
我正在尝试遵循路线,所以我有 GlobalTemplatePageRouteModelConvention。 我用的是int?将 /1 与 /ListJson 处理程序区分开来的约束,但我对此并不满意,它不必要地检查每个路由的整数。 这是理想的解决方案吗?我怎样才能让它变得更好?
页数;
/Index.cshtml
/MainTestPage.cshtml
/TestDir/Index.cshtml
/TestDir/TestPage.cshtml
处理程序;
public void OnGet(int? id)
public void OnGetListJson(int? id)
路线;
"/",
"/1",
"/ListJson",
"/ListJson/1",
"/MainTestPage",
"/MainTestPage/1",
"/MainTestPage/ListJson",
"/MainTestPage/ListJson/1",
"/TestDir",
"/TestDir/1",
"/TestDir/ListJson",
"/TestDir/ListJson/1",
"/TestDir/TestPage",
"/TestDir/TestPage/1",
"/TestDir/TestPage/ListJson",
"/TestDir/TestPage/ListJson/1",
代码;
public class GlobalTemplatePageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
var list = new List<SelectorModel>();
var isIndexPage = model.ViewEnginePath.EndsWith("/Index", StringComparison.OrdinalIgnoreCase);
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
var template = selector.AttributeRouteModel.Template;
var isIndexRoute = template.EndsWith("Index", StringComparison.OrdinalIgnoreCase);
if (isIndexPage)
{
if (isIndexRoute)
{
list.Add(selector);
}
else
{
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -2,
Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{id:int?}")
}
});
selector.AttributeRouteModel.Order = -1;
selector.AttributeRouteModel.Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{handler?}/{id?}");
}
}
else
{
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -4,
Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{id:int?}")
}
});
selector.AttributeRouteModel.Order = -3;
selector.AttributeRouteModel.Template = AttributeRouteModel.CombineTemplates(selector.AttributeRouteModel.Template, "{handler?}/{id?}");
}
}
foreach (var selector in list)
model.Selectors.Remove(selector);
}
}
builder.AddRazorPagesOptions(o => {
o.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
}
最后,我更喜欢遵循路由模板约定,这样可以消除 int 约束并且不会因此而损失性能。
- 模板是全局指定的,而不是在每个页面的@page 指令中指定。
- 索引路由(/Index/1)用于未命名的处理程序、OnGet 等
- 适用于以下路线;
"/",
"/Index/1",
"/ListJson",
"/ListJson/1",
"/MainTestPage",
"/MainTestPage/Index/1",
"/MainTestPage/ListJson",
"/MainTestPage/ListJson/1",
"/TestDir",
"/TestDir/Index/1",
"/TestDir/ListJson",
"/TestDir/ListJson/1",
"/TestDir/TestPage",
"/TestDir/TestPage/Index/1",
"/TestDir/TestPage/ListJson",
"/TestDir/TestPage/ListJson/1",
- GlobalTemplatePageRouteModelConvention;
- 索引路由导致不匹配,因此将其删除。
builder.AddRazorPagesOptions(o =>
{
o.Conventions.Add(new GlobalTemplatePageRouteModelConvention());
});
public class GlobalTemplatePageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var isIndexPage = model.ViewEnginePath.EndsWith("/Index", StringComparison.OrdinalIgnoreCase);
foreach (var selector in model.Selectors.ToList())
{
var template = selector.AttributeRouteModel.Template;
if (isIndexPage)
{
var isIndexRoute = template.EndsWith("Index", StringComparison.OrdinalIgnoreCase);
if (isIndexRoute)
{
model.Selectors.Remove(selector);
continue;
}
}
selector.AttributeRouteModel.Template =
AttributeRouteModel.CombineTemplates(template,
"{handler?}/{id?}");
}
}
}