protected virtual ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) { Contract.Assert(controllerContext != null); Contract.Assert(controllerContext.RouteData != null); Contract.Assert(controllerDescriptor != null); if (controllerContext.RouteData.HasDirectRouteMatch()) { List <DirectRouteCandidate> candidates = GetDirectRouteCandidates(controllerContext); DirectRouteCandidate bestCandidate = DirectRouteCandidate.SelectBestCandidate(candidates, controllerContext); if (bestCandidate == null) { return(null); } else { // We need to stash the RouteData of the matched route into the context, so it can be // used for binding. controllerContext.RouteData = bestCandidate.RouteData; controllerContext.RequestContext.RouteData = bestCandidate.RouteData; // We need to remove any optional parameters that haven't gotten a value (See MvcHandler) bestCandidate.RouteData.Values.RemoveFromDictionary((entry) => entry.Value == UrlParameter.Optional); return(bestCandidate.ActionDescriptor); } } else { ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); return(actionDescriptor); } }
public void SelectBestCandidate_ChoosesByOrder() { // Arrange Type controllerType = typeof(TestController); ReflectedControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType); DirectRouteCandidate better = new DirectRouteCandidate() { ActionDescriptor = ActionDescriptorFrom <TestController>(c => c.Action1()), ControllerDescriptor = controllerDescriptor, Order = 0, RouteData = new RouteData(), }; DirectRouteCandidate worse = new DirectRouteCandidate() { ActionDescriptor = ActionDescriptorFrom <TestController>(c => c.Action1()), ControllerDescriptor = controllerDescriptor, Order = 1, RouteData = new RouteData(), }; List <DirectRouteCandidate> candidates = new List <DirectRouteCandidate>() { better, worse, }; // Act DirectRouteCandidate actual = DirectRouteCandidate.SelectBestCandidate(candidates, new ControllerContext()); // Assert Assert.Same(better, actual); }
public void SelectBestCandidate_ReturnsNullOnEmptyList() { // Arrange & Act DirectRouteCandidate actual = DirectRouteCandidate.SelectBestCandidate(new List <DirectRouteCandidate>(), new ControllerContext()); // Assert Assert.Null(actual); }
public void SelectBestCandidate_Ambiguity() { // Arrange Type controllerType = typeof(TestController); ReflectedControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor( controllerType ); DirectRouteCandidate candidate1 = new DirectRouteCandidate() { ActionDescriptor = new ReflectedActionDescriptor( controllerType.GetMethod("Action1"), "Action1", controllerDescriptor ), ActionSelectors = new ActionSelector[] { (context) => true }, ControllerDescriptor = controllerDescriptor, Order = 0, Precedence = 1, RouteData = new RouteData(), }; DirectRouteCandidate candidate2 = new DirectRouteCandidate() { ActionDescriptor = new ReflectedActionDescriptor( controllerType.GetMethod("Action2"), "Action2", controllerDescriptor ), ActionSelectors = new ActionSelector[] { (context) => true }, ControllerDescriptor = controllerDescriptor, Order = 0, Precedence = 1, RouteData = new RouteData(), }; List <DirectRouteCandidate> candidates = new List <DirectRouteCandidate>() { candidate1, candidate2, }; string message = "The current request is ambiguous between the following action methods:" + Environment.NewLine + "Void Action1() on type System.Web.Mvc.Routing.Test.DirectRouteCandidateTest+TestController" + Environment.NewLine + "Void Action2() on type System.Web.Mvc.Routing.Test.DirectRouteCandidateTest+TestController"; // Act & Assert Assert.Throws <AmbiguousMatchException>( () => DirectRouteCandidate.SelectBestCandidate(candidates, new ControllerContext()), message ); }
public void SelectBestCandidate_SelectByActionNameSelector_UsesActionName() { // Arrange Type controllerType = typeof(TestController); ReflectedControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor( controllerType ); RouteData routeData = new RouteData(); routeData.Values["action"] = "Action1"; DirectRouteCandidate better = new DirectRouteCandidate() { ActionDescriptor = ActionDescriptorFrom <TestController>(c => c.Action1()), ActionNameSelectors = new ActionNameSelector[] { (context, name) => name == "Action1" }, ControllerDescriptor = controllerDescriptor, RouteData = routeData, }; DirectRouteCandidate worse = new DirectRouteCandidate() { ActionDescriptor = ActionDescriptorFrom <TestController>(c => c.Action2()), ActionNameSelectors = new ActionNameSelector[] { (context, name) => name == "Action2" }, ControllerDescriptor = controllerDescriptor, RouteData = routeData, }; List <DirectRouteCandidate> candidates = new List <DirectRouteCandidate>() { better, worse, }; // Act DirectRouteCandidate actual = DirectRouteCandidate.SelectBestCandidate( candidates, new ControllerContext() ); // Assert Assert.Same(better, actual); }
public void SelectBestCandidate_ExcludesFailedActionSelectors_NoneValid() { // Arrange Type controllerType = typeof(TestController); ReflectedControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor( controllerType ); DirectRouteCandidate better = new DirectRouteCandidate() { ActionDescriptor = ActionDescriptorFrom <TestController>(c => c.Action1()), ActionSelectors = new ActionSelector[] { (context) => false, }, ControllerDescriptor = controllerDescriptor, Order = 0, RouteData = new RouteData(), }; DirectRouteCandidate worse = new DirectRouteCandidate() { ActionDescriptor = ActionDescriptorFrom <TestController>(c => c.Action1()), ActionSelectors = new ActionSelector[] { (context) => false, }, ControllerDescriptor = controllerDescriptor, Order = 1, RouteData = new RouteData(), }; List <DirectRouteCandidate> candidates = new List <DirectRouteCandidate>() { better, worse, }; // Act DirectRouteCandidate actual = DirectRouteCandidate.SelectBestCandidate( candidates, new ControllerContext() ); // Assert Assert.Null(actual); }