Reputation: 6258
Is it possible to use the ASP.NET Core MVC Router to determine, if a redirect to a specific location might be successfull?
I'd like to inject the MVC Router and just ask it, if the route I want to use exists at all, but I'm struggling finding the correct classes to inject and did not see any method of use in the MVCRouter.
I would also be okay in overriding the default router and extend it with the neccessary methods.
Upvotes: 1
Views: 2065
Reputation: 58743
One way to do this would be to inject IActionSelector
to your component.
That component is responsible for controller action selection, and can tell you if there is a route with given parameters (and even if there is an ambiguous match).
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();
}
}
It's essentially what MvcRouteHandler
does. First finds all the possible candidates, then filters that to the best candidate. It can throw an exception if it finds more than one, which you may or may not want to handle.
I thought if you could somehow do this easier by extending a component to change behaviour, but MvcRouteHandler
is not that easy to extend. It currently just logs a message if no action matches, which does not affect the return value. And we can't really change the signature there.
Upvotes: 1