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

.NET 8 MVC中从Uri获取RouteData的替代方案求助

.NET 8 MVC从Uri获取路由值的高效方案(迁移自.NET Framework 4.8)

原.NET Framework 4.8实现

之前在.NET Framework 4.8中,通过自定义HttpContextBase子类模拟请求,调用RouteTable.Routes.GetRouteData获取路由值:

public class GetRouteDataContext : HttpContextBase
{
    public override HttpRequestBase Request { get; }

    private GetRouteDataContext(Uri uri)
    {
        var url = uri.GetLeftPart(UriPartial.Path);
        var qs = uri.GetComponents(UriComponents.Query, UriFormat.UriEscaped);
        Request = new HttpRequestWrapper(new HttpRequest(null, url, qs));
    }

    public static RouteValueDictionary RouteValuesFromUri(Uri uri)
    {
        return RouteTable.Routes.GetRouteData(new GetRouteDataContext(uri)).Values;
    }
}

.NET 8中的适配问题

在.NET 8中,HttpContextBase、HttpRequestBase、HttpRequestWrapper以及RouteTable.Routes.GetRouteData这些旧API已被移除,无法直接复用原有逻辑。

当前实现的问题

你尝试通过EndpointDataSource手动遍历匹配路由的方式存在以下不足:

  • 手动遍历所有端点效率低下,路由数量较多时性能损耗明显
  • 使用Contains匹配路径容易误判(比如/Home/Index会错误匹配/Home/IndexTest)
  • 依赖静态HttpContext实例存在线程安全风险,服务获取方式不符合ASP.NET Core设计规范

高效替代方案

在.NET 8中,推荐使用内置的RouteMatcher完成路由匹配,它会复用应用已注册的路由规则,无需手动遍历端点。

实现步骤

  1. 确保项目已在Program.cs中配置MVC路由(默认模板已包含此配置)
  2. 创建封装路由匹配逻辑的服务类,依赖注入MatcherFactory和EndpointDataSource:
public class RouteDataResolver
{
    private readonly RouteMatcher _routeMatcher;

    public RouteDataResolver(MatcherFactory matcherFactory, EndpointDataSource endpointDataSource)
    {
        // 基于应用已注册的端点创建路由匹配器
        _routeMatcher = matcherFactory.CreateMatcher(endpointDataSource);
    }

    public RouteValueDictionary GetRouteValuesFromUri(Uri uri)
    {
        var httpContext = new DefaultHttpContext
        {
            Request =
            {
                Scheme = uri.Scheme,
                Host = new HostString(uri.Host, uri.Port),
                Path = new PathString(uri.AbsolutePath),
                QueryString = QueryString.FromUriComponent(uri)
            }
        };

        var routeContext = new RouteContext(httpContext);
        _routeMatcher.Match(routeContext);

        return routeContext.RouteData?.Values ?? new RouteValueDictionary();
    }
}
  1. 在Program.cs中注册该服务:
builder.Services.AddScoped<RouteDataResolver>();
  1. 使用示例:在需要的类中注入RouteDataResolver并调用方法:
public class SampleService
{
    private readonly RouteDataResolver _routeResolver;

    public SampleService(RouteDataResolver routeResolver)
    {
        _routeResolver = routeResolver;
    }

    public void ProcessUri(Uri uri)
    {
        var routeValues = _routeResolver.GetRouteValuesFromUri(uri);
        var controllerName = routeValues["controller"]?.ToString();
        var actionName = routeValues["action"]?.ToString();
        // 执行业务逻辑
    }
}

方案优势

  • 复用应用已有路由规则,匹配逻辑和实际请求完全一致,避免误判
  • 内置匹配器性能远高于手动遍历端点
  • 依赖注入方式符合ASP.NET Core设计规范,无线程安全风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:22:24