【问题标题】:Use MVC Router to determine if route exists使用 MVC Router 判断路由是否存在
【发布时间】:2017-05-19 16:20:34
【问题描述】:

是否可以使用 ASP.NET Core MVC 路由器来确定是否可以成功重定向到特定位置?

我想注入 MVC 路由器并询问它,如果我想使用的路由是否存在,但我正在努力寻找要注入的正确类并且在 MVCRouter 中没有看到任何使用方法.

我也可以覆盖默认路由器并使用必要的方法对其进行扩展。

【问题讨论】:

    标签: asp.net-core-mvc


    【解决方案1】:

    一种方法是将IActionSelector 注入到您的组件中。

    该组件负责控制器动作选择,并且可以告诉您是否存在具有给定参数的路由(即使存在模棱两可的匹配)。

    public class HomeController : Controller
    {
        private readonly IActionSelector _actionSelector;
    
        public HomeController(IActionSelector actionSelector)
        {
            _actionSelector = actionSelector;
        }
    
        public IActionResult Index()
        {
            var routeData = new RouteData();
            routeData.Values["action"] = "DoesNotExist";
            routeData.Values["controller"] = "Home";
            var routeContext = new RouteContext(HttpContext)
            {
                RouteData = routeData
            };
            IReadOnlyList<ActionDescriptor> candidates = _actionSelector.SelectCandidates(routeContext);
            if (candidates == null || candidates.Count == 0)
            {
                //No actions matched
            }
            else
            {
                try
                {
                    var actionDescriptor = _actionSelector.SelectBestCandidate(routeContext, candidates);
                    if(actionDescriptor == null)
                    {
                        //No action matched
                    }
                    //Action matched
                }
                catch (AmbiguousActionException)
                {
                    //More than 1 action matched
                }
            }
            return View();
        }
    }
    

    这基本上就是MvcRouteHandler 所做的。首先找到所有可能的候选人,然后将其过滤到最佳候选人。如果它发现多个异常,它可能会抛出一个异常,你可能想要也可能不想处理。

    我想如果你可以通过扩展一个组件来改变行为以某种方式更容易做到这一点,但是MvcRouteHandler 并不是那么容易扩展。如果没有操作匹配,它当前只记录一条消息,这不会影响返回值。而且我们不能真正改变那里的签名。

    【讨论】:

    • 这真的很接近我想要的。本质上,我想看看,如果派生位置存在,是否有 404。所以我必须使用中间件,我目前不知道如何从任意 Url 构造 RouteContext。不过,我感谢您为帮助我所做的努力。
    • 幸运的是,这实际上是 ASP.NET Core 特定的东西,而不是 MVC。我认为您必须获取路线集合并尝试从那里解决它。我以后可以看看。
    • 据我了解,MVC 将构建一个IRouter,后者实现 RouteAsync(),这将在RouteContext-Object 中填充RouteData。但是创建IRouter 似乎很昂贵。关于这一点,如果路线存在(或至少仅出于学术目的),我可能不应该尝试检测......
    • MVC 的处理程序不填充RouteData,它在被RouteBase 命中之前完成,它调用TemplateMatcher 进行匹配。您实际上可以通过 HttpContext 访问IRoutingFeature,在中间件或任何地方访问填充的RouteData。您必须在 RouterMiddleware 运行后执行此操作,这将非常棘手,因为这实际上是调用 MVC 处理程序来调用您的操作的事情。
    • 好吧,看来我现在不应该那样做......但是我学到了一些关于 ASP.NET Core 路由的东西,这很好:)
    猜你喜欢
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 2011-11-02
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 2021-03-31
    相关资源
    最近更新 更多