概述
IPageRouteModelConvention接口用于自定義PageRouteModel,這個對象在Microsoft.AspNetCore.Mvc.ApplicationModels命名空間中,
代表着Razor Page路由設定,換句話說我們可以通過實作該接口覆寫預設的實作。
該接口需要實作一個成員void Apply(PageRouteModel model)。通過這個方法,我們可以通路有關目前路由設定的中繼資料,并根據需要對其内容進行修改。
下面示例,将解決提供一個僞靜态的解決方案,是以我們可以通過index.html about.html....去通路我們的頁面,也就是說我們可以從Index-Index.html的支援
public class HtmlExtensionPageRouteModelConvention : IPageRouteModelConvention
{
private readonly ILogger _logger;
public HtmlExtensionPageRouteModelConvention(ILogger logger)
{
_logger = logger;
}
public void Apply(PageRouteModel model)
{
var log = new StringBuilder();
log.AppendLine("====================================================");
log.AppendLine($"Count:{model.Selectors.Count} ViewEnginePath:{model.ViewEnginePath} RelativePath:{model.RelativePath}");
var selectorsCount = model.Selectors.Count;
for (var i = 0; i < selectorsCount; ++i)
{
var attributeRouteModel = model.Selectors[i].AttributeRouteModel;
//添加之前
log.AppendLine($"Template:{attributeRouteModel.Template}");
if (string.IsNullOrEmpty(attributeRouteModel.Template))
{
continue;
}
//該規則是否禁止連結的生成,預設為生成(支援TagHelpers) asp-page="/Index"
attributeRouteModel.SuppressLinkGeneration = true;
//添加新的路由模闆
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
//Order 路由比對順序
//SuppressLinkGeneration = true,
Template = $"{attributeRouteModel.Template}.html",
}
});
}
//添加完後
log.AppendLine($"Count:{model.Selectors.Count} ");
foreach (var item in model.Selectors)
{
log.AppendLine($"Template:{item.AttributeRouteModel.Template} ");
}
_logger.LogInformation(log.ToString());
}
}
在啟動時,為所有可導航的Razor頁面建構PageRouteModel。Apply方法接收這個對象,并通路于PageRouteModel相關聯的SelectorModel對象集合。它們包含頁面路由和任何限制的資訊,在每個頁面的selector集合中通常有一個SelectorModel,但可以有任意數量,預設頁面為Index.cshtml通常有兩個選擇器,一個包含一個路由模闆,由相對檔案路徑和"Index"組成,另一個模闆中有一個空字元串,檔案名通常放在那裡(這使它成為檔案夾的預設檔案)。在這個例子中的Index.cshtml原始模闆生成的(Index),将變成一個Index.html
我們需要将attributeRouteModel.SuppressLinkGeneration設定為true,禁止對連結的生成,預設值為false(支援TagHelpers如:asp-page="/Index"),
如下圖所示滑鼠箭頭放到Home上面,在下面可以顯示出來為我們生成的路徑,這個路由則是根據我們設定的規則而生成出來的.

當我們在Selectors.Add方法内中的
new AttributeRouteModel
對象中将
SuppressLinkGeneration
設定為true,這樣的話我們是将路由規則設定禁止了,看下圖可以看出,
當我們把所有的規則都設定為禁止生成後,我們當滑鼠剪頭再次放到Home上面時已經不會為我們再生成新的連結了
添加約定
自定義約定要在Startup中的void ConfigureServices(IServiceCollection services)方法下中的 services.AddRazorPages()方法下追加RazorPagesOptions方法并添加約定的集合:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddRazorPages().AddRazorPagesOptions(options =>
{
//options.Conventions.AddPageRoute("/Index", "Index.html");
options.Conventions.Add(new HtmlExtensionPageRouteModelConvention(_loggerFactory.CreateLogger<HtmlExtensionPageRouteModelConvention>()));
});
}
通過如上代碼,我們便在.NET中實作了僞靜态,對URL路由比對規則的附加操作.
https://github.com/hueifeng/BlogSample/tree/master/src/PageRouteModelConventionURLRewrite