Razor Pages Anchor Tag Helper 不会从 href 中删除索引

Posted

技术标签:

【中文标题】Razor Pages Anchor Tag Helper 不会从 href 中删除索引【英文标题】:RazorPages AnchorTagHelper does not remove Index from href 【发布时间】:2020-02-25 15:21:01 【问题描述】:

最近我开始使用 RazorPages。 (3.1)

在我的cshtml中,当我使用时:

<a asp-page="/Index">

生成的 HTML 是:

<a href="/">

干净整洁。

当我引入自定义 PageRouteModelConvention(用于文化)和自定义 AnchorTagHelper 时,它不再以这种方式运行。

只要我的 URL 以文化 (domain.com/nl-BE/) 开头,主页的链接就会如下所示:

<a href="/nl-BE/Index">

虽然我想像以前一样在没有索引的情况下保留它

<a href="/nl-BE">

知道如何解决这个问题吗?

将我的文化添加到 url 的路由约定:

    public class CultureTemplatePageRouteModelConvention : 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("culture?", selector.AttributeRouteModel.Template),
                    
                );
            
        
    

默认的anchortaghelper被替换为:

    [HtmlTargetElement("a", Attributes = ActionAttributeName)]
    [HtmlTargetElement("a", Attributes = ControllerAttributeName)]
    [HtmlTargetElement("a", Attributes = AreaAttributeName)]
    [HtmlTargetElement("a", Attributes = PageAttributeName)]
    [HtmlTargetElement("a", Attributes = PageHandlerAttributeName)]
    [HtmlTargetElement("a", Attributes = FragmentAttributeName)]
    [HtmlTargetElement("a", Attributes = HostAttributeName)]
    [HtmlTargetElement("a", Attributes = ProtocolAttributeName)]
    [HtmlTargetElement("a", Attributes = RouteAttributeName)]
    [HtmlTargetElement("a", Attributes = RouteValuesDictionaryName)]
    [HtmlTargetElement("a", Attributes = RouteValuesPrefix + "*")]
    public class CultureAnchorTagHelper : AnchorTagHelper
    
        public CultureAnchorTagHelper(IHttpContextAccessor contextAccessor, IHtmlGenerator generator) :
            base(generator)
        
            this._contextAccessor = contextAccessor;
        

        private const string ActionAttributeName = "asp-action";
        private const string ControllerAttributeName = "asp-controller";
        private const string AreaAttributeName = "asp-area";
        private const string PageAttributeName = "asp-page";
        private const string PageHandlerAttributeName = "asp-page-handler";
        private const string FragmentAttributeName = "asp-fragment";
        private const string HostAttributeName = "asp-host";
        private const string ProtocolAttributeName = "asp-protocol";
        private const string RouteAttributeName = "asp-route";
        private const string RouteValuesDictionaryName = "asp-all-route-data";
        private const string RouteValuesPrefix = "asp-route-";
        private const string Href = "href";

        private readonly IHttpContextAccessor _contextAccessor;
        private readonly string defaultRequestCulture = "en";

        public override void Process(TagHelperContext context, TagHelperOutput output)
        
            var culture = (string)_contextAccessor.HttpContext.Request.RouteValues["culture"];

            if (culture != null && culture != defaultRequestCulture)
            
                RouteValues["culture"] = culture;
            

            base.Process(context, output);
        
    

【问题讨论】:

【参考方案1】:

如下改变:

public void ConfigureServices(IServiceCollection services)

    services.AddMvc().AddRazorPagesOptions(options =>
    
        options.Conventions.AddFolderRouteModelConvention("/", model =>
        
            foreach (var selector in model.Selectors)
            
                selector.AttributeRouteModel.Template = AttributeRouteModel.CombineTemplates("culture?", selector.AttributeRouteModel.Template);
            
        );
    );
    services.Configure<RequestLocalizationOptions>(options => 
        var supportedCultures = new CultureInfo[] 
        new CultureInfo("en"),
        new CultureInfo("fr")
        ;

        options.DefaultRequestCulture = new RequestCulture("en");
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;

        options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider()
        
            RouteDataStringKey = "culture",
            UIRouteDataStringKey = "culture",
            Options = options
        );
    );
    services.AddDbContext<Razor3_1Context>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("Razor3_1Context")));


// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    
    else
    
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    

    var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    app.UseRequestLocalization(options.Value);

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    
        endpoints.MapRazorPages();
    );

结果:

【讨论】:

以上是关于Razor Pages Anchor Tag Helper 不会从 href 中删除索引的主要内容,如果未能解决你的问题,请参考以下文章

关于 razor,.NET MVC 对 razor 的支持与 .NET razor pages 有啥区别,有啥叫做 .NET MVC razor pages 的东西吗?

Razor-Pages - HTML 标记

ASP.NET Web Pages - 添加 Razor 代码

Razor Pages 不使用它的布局

无法部署 Razor Pages 网站

Razor Pages - 一对多关系