You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8如何复现3.1移除的环境路由值链接生成功能?

在ASP.NET Core 8 Razor Pages复现环境路由值功能的方案

官方移除自动继承环境路由值的功能后,确实需要通过自定义扩展来实现,最直接的方式是自定义AnchorTagHelper或扩展UrlHelper,以下是具体实现方案:

方案一:自定义AnchorTagHelper(推荐用于页面链接)

通过继承默认的AnchorTagHelper,自动从当前页面路由上下文提取目标页面需要的参数,无需手动编写asp-route-*属性。

1. 实现自定义TagHelper类

using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

[HtmlTargetElement("a", Attributes = "asp-page, asp-auto-inherit-routes")]
public class AutoInheritRouteAnchorTagHelper : AnchorTagHelper
{
    private readonly IPageContextAccessor _pageContextAccessor;

    public AutoInheritRouteAnchorTagHelper(
        IHtmlGenerator generator,
        IPageContextAccessor pageContextAccessor)
        : base(generator)
    {
        _pageContextAccessor = pageContextAccessor;
    }

    [HtmlAttributeName("asp-auto-inherit-routes")]
    public bool AutoInheritRoutes { get; set; } = true;

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (AutoInheritRoutes && !string.IsNullOrEmpty(PageName))
        {
            var currentRouteValues = _pageContextAccessor.PageContext.RouteData.Values;
            // 获取目标页面的路由模板参数
            var targetPage = _pageContextAccessor.PageContext.ActionDescriptor.EndpointMetadata
                .OfType<PageRouteMetadata>()
                .FirstOrDefault(p => p.RelativePath == $"/{PageName.Replace("~/", "").TrimStart('/')}.cshtml");
            
            if (targetPage != null)
            {
                var targetParams = targetPage.RouteTemplate.Split('/')
                    .Where(segment => segment.StartsWith("{") && segment.EndsWith("}"))
                    .Select(segment => segment.Trim('{', '}'))
                    .ToList();
                
                // 自动添加当前路由中存在、目标页面需要且未手动指定的参数
                foreach (var kvp in currentRouteValues)
                {
                    if (targetParams.Contains(kvp.Key) && !RouteValues.ContainsKey(kvp.Key))
                    {
                        RouteValues[kvp.Key] = kvp.Value;
                    }
                }
            }
        }
        
        base.Process(context, output);
    }
}

2. 注册TagHelper

在项目的_ViewImports.cshtml中添加TagHelper引用(替换YourProjectAssembly为你的项目程序集名称):

@addTagHelper *, YourProjectAssembly

3. 页面中使用

只需添加asp-auto-inherit-routes属性,即可自动携带匹配的路由参数:

@page "/org/{org}/projects/{project}"
@model Details

<a asp-page="/Translate/Index" asp-auto-inherit-routes>
    Translate
</a>

方案二:扩展UrlHelper(用于代码生成URL)

如果需要在后台或视图代码中生成URL,可以扩展UrlHelper实现自动继承路由参数:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;

public static class UrlHelperExtensions
{
    public static string PageWithInheritedRoutes(this IUrlHelper urlHelper, string pageName, object? routeValues = null)
    {
        var currentRouteValues = urlHelper.ActionContext.RouteData.Values;
        var targetPage = urlHelper.ActionContext.ActionDescriptor.EndpointMetadata
            .OfType<PageRouteMetadata>()
            .FirstOrDefault(p => p.RelativePath == $"/{pageName.Replace("~/", "").TrimStart('/')}.cshtml");
        
        var mergedRouteValues = new RouteValueDictionary(routeValues);
        
        if (targetPage != null)
        {
            var targetParams = targetPage.RouteTemplate.Split('/')
                .Where(s => s.StartsWith("{") && s.EndsWith("}"))
                .Select(s => s.Trim('{', '}'))
                .ToList();
            
            foreach (var kvp in currentRouteValues)
            {
                if (targetParams.Contains(kvp.Key) && !mergedRouteValues.ContainsKey(kvp.Key))
                {
                    mergedRouteValues[kvp.Key] = kvp.Value;
                }
            }
        }
        
        return urlHelper.Page(pageName, mergedRouteValues);
    }
}

使用方式

@inject IUrlHelper Url

<a href="@Url.PageWithInheritedRoutes("/Translate/Index")">Translate</a>

注意事项

  • 确保IPageContextAccessor已在DI容器中注册,ASP.NET Core 8默认已注册,若未注册可在Program.cs添加:builder.Services.AddSingleton<IPageContextAccessor, PageContextAccessor>();
  • 可根据需求调整自定义逻辑,比如只继承特定前缀的参数(如org、project),避免意外携带无关参数。

内容的提问来源于stack exchange,提问作者Peter Kneale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:22:43