Asp.net core mvc 使用MVC路由器确定路由是否存在
是否可以使用ASP.NET Core MVC路由器来确定重定向到特定位置是否成功 我想注入MVC路由器,只是问问它,我想要使用的路由是否存在,但我正在努力寻找正确的类来注入,在MVC路由器中没有看到任何使用方法Asp.net core mvc 使用MVC路由器确定路由是否存在,asp.net-core-mvc,Asp.net Core Mvc,是否可以使用ASP.NET Core MVC路由器来确定重定向到特定位置是否成功 我想注入MVC路由器,只是问问它,我想要使用的路由是否存在,但我正在努力寻找正确的类来注入,在MVC路由器中没有看到任何使用方法 我也可以覆盖默认路由器,并用必要的方法扩展它。一种方法是将IActionSelector注入组件 该组件负责控制器操作选择,并可以告诉您是否存在具有给定参数的路由(即使存在不明确的匹配) 公共类HomeController:控制器 { 专用只读IActionSelector\u acti
我也可以覆盖默认路由器,并用必要的方法扩展它。一种方法是将
IActionSelector
注入组件
该组件负责控制器操作选择,并可以告诉您是否存在具有给定参数的路由(即使存在不明确的匹配)
公共类HomeController:控制器
{
专用只读IActionSelector\u actionSelector;
公共家庭控制器(IActionSelector actionSelector)
{
_actionSelector=actionSelector;
}
公共IActionResult索引()
{
var routeData=新routeData();
RoutedData.Values[“action”]=“DoesNotExist”;
路由数据值[“控制器”]=“主节点”;
var routeContext=新的routeContext(HttpContext)
{
路由数据=路由数据
};
IReadOnlyList候选者=_actionSelector.Select候选者(routeContext);
if(候选者==null | |候选者.计数==0)
{
//没有匹配的操作
}
其他的
{
尝试
{
var actionDescriptor=\u actionSelector.SelectBestCandidate(routeContext,候选者);
if(actionDescriptor==null)
{
//没有匹配的动作
}
//动作匹配
}
捕获(模糊UsactionException)
{
//超过1个动作匹配
}
}
返回视图();
}
}
它本质上就是MvcRouteHandler
所做的。首先找到所有可能的候选者,然后筛选出最佳候选者。如果发现多个异常,它可能会抛出一个异常,您可能希望也可能不希望处理这些异常
我想,如果你能通过扩展一个组件来改变行为,以某种方式更容易做到这一点,但是
MvcRouteHandler
并不是那么容易扩展的。如果没有匹配的操作,它当前只记录一条消息,这不会影响返回值。我们无法真正更改那里的签名。这与我想要的非常接近。基本上我想看看,如果存在一个派生位置,如果有一个404。因此,我必须使用中间件,而我目前不知道如何从任意Url构造RouteContext。尽管如此,我还是很感谢您的帮助。幸运的是,这实际上是ASP.NET核心特有的东西,而不是MVC。我认为,您必须获取路由集合并尝试从那里解决它。我可以稍后再看。据我所知,MVC将构建一个IRouter
,后者实现RouteAsync(),这将在RouteContext
-对象中填充RouteData
。但是创建IRouter
似乎很昂贵。关于这一点,我可能不应该尝试检测,如果路由存在(或者至少只是出于学术目的)…MVC的处理程序不填充routedData
,它是在被RouteBase
击中之前完成的,后者调用TemplateMatcher
进行匹配。通过HttpContext访问IRoutingFeature
,您实际上可以在中间件或任何地方访问已填充的routedData
。您必须在运行RouterMiddleware
之后执行此操作,这将非常棘手,因为这实际上是调用MVC处理程序来调用您的操作的事情。显然,我现在不应该这样做。。尽管如此,我还是学到了一些关于ASP.NET核心路由的知识,这很好:)
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();
}
}