Exemplo n.º 1
0
        private static void SetupRoutesUsingTestClasses()
        {
            RouteTableBuilder.ClearRoutes();
            var allTestControllerActions = SitkaController.GetAllControllerActionMethods(typeof(MyAbstractBaseController));

            RouteTableBuilder.Build(allTestControllerActions, null, new Dictionary <string, string>());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Builds a URL based on the Expression passed in
        /// </summary>
        /// <typeparam name="TController">Controller Type Only</typeparam>
        /// <param name="context">The current ViewContext</param>
        /// <param name="routeCollection">The <see cref="RouteCollection"/> to use for building the URL.</param>
        /// <param name="action">The action to invoke</param>
        /// <returns></returns>
        public static string BuildUrlFromExpression <TController>(RequestContext context, RouteCollection routeCollection, Expression <Action <TController> > action) where TController : Controller
        {
            // 4/4/2016 RL: We could not simply just use RouteValueDictionary routeValues = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression(action) because it is not Area aware;
            // so we had to get the guts of that method call and do it ourself to make it respect areas

            var body = action.Body as MethodCallExpression;

            Check.RequireNotNull(body, "MvcResources.ExpressionHelper_MustBeMethodCall");
            // ReSharper disable PossibleNullReferenceException
            var actionName = GetTargetActionName(body.Method);
            // ReSharper restore PossibleNullReferenceException

            var controllerType = typeof(TController);
            var controllerName = SitkaController.ControllerTypeToControllerName(controllerType);

            var routeValues = GetRouteValuesFromExpression(body, controllerType.Namespace, controllerName, actionName);

            var vpd = routeCollection.GetVirtualPath(context, routeValues);

            if (vpd == null)
            {
                return(null);
            }

            var routeUrl = vpd.VirtualPath;

            return(routeUrl);
        }
Exemplo n.º 3
0
        public void TestRouteBuilder()
        {
            List <MethodInfo> methods = SitkaController.FindControllerActions(typeof(RouteTableBuilderTestController));

            Assert.That(methods.Count, Is.EqualTo(6));

            List <SitkaRouteTableEntry> routeEntries = RouteTableBuilder.SetupRouteTableImpl(methods);

            Assert.That(routeEntries.Count, Is.EqualTo(11 + GetDefaultRouteCount()));
        }
Exemplo n.º 4
0
        public void CanFindActionsInheritedFromBaseClass()
        {
            var controllerActionMethods = SitkaController.FindControllerActions(typeof(MyTest1Controller));
            var methodNames             = controllerActionMethods.Select(x => String.Format("{0}.{1}", x.ReflectedType.Name, x.Name)).ToList();
            var expected = new[] { "MyTest1Controller.MyAction1", "MyTest1Controller.ActionWithNoParameters", "MyTest1Controller.ActionWithOneParameter", "MyTest1Controller.BaseAction" };

            Assert.That(methodNames, Is.EquivalentTo(expected), "Should find both base declared actions and derived actions");

            var abstractBaseControllerActionMethods = SitkaController.FindControllerActions(typeof(MyAbstractBaseController));

            Assert.That(abstractBaseControllerActionMethods, Is.Empty, "Should not find any in abstract base classes - they don't count for routes");
        }
Exemplo n.º 5
0
        public void AllMethodsExistCsvAndSoap()
        {
            var webServiceMethodNames =
                SitkaController.FindAttributedMethods(typeof(IWebServices), typeof(OperationContractAttribute)).Select(m => m.Name).Except(_webServiceMethodsNotAvailableViaMvcController);
            var webServiceControllerActionNames = _allWebServiceControllerActionMethodInfos.Select(a => a.Name).Except(_webServiceMethodsThatAreNotWebServices);

            var missingFromWebService = webServiceControllerActionNames.Except(webServiceMethodNames);

            Assert.That(missingFromWebService, Is.Empty, "There are CSV controller actions that aren't in the web service.");

            var missingFromCsvControllerAction = webServiceMethodNames.Except(webServiceControllerActionNames);

            Assert.That(missingFromCsvControllerAction, Is.Empty, "There are web service actions that aren't in the CSV controller actions.");
        }
Exemplo n.º 6
0
        public void RoutesShouldNotCollide()
        {
            List <MethodInfo>           allTestControllerActions = SitkaController.FindControllerActions(typeof(MyAbstractBaseController));
            List <SitkaRouteTableEntry> routeEntries             = RouteTableBuilder.SetupRouteTableImpl(allTestControllerActions);

            Assert.That(routeEntries.All(re => re != null));

            List <IGrouping <string, SitkaRouteTableEntry> > duplicateRouteNames = routeEntries.ToLookup(x => x.RouteName).Where(grp => grp.Count() > 1).ToList();

            Assert.That(duplicateRouteNames, Is.Empty, "All route names should be unique but there are duplicates");

            List <IGrouping <string, SitkaRouteTableEntry> > duplicateRouteUrls = routeEntries.ToLookup(x => x.RouteUrl).Where(grp => grp.Count() > 1).ToList();

            Assert.That(duplicateRouteUrls, Is.Empty, "All route urls should be unique but there are duplicates");
        }
Exemplo n.º 7
0
        public SitkaRoute(Expression <Action <T> > routeExpression)
        {
            RouteExpression = routeExpression;
            ControllerName  = SitkaController.ControllerTypeToControllerName(typeof(T));
            Body            = GetRouteExpressionBody(routeExpression);

            var actionName = Body.Method.Name;
            var attributes = Body.Method.GetCustomAttributes(typeof(ActionNameAttribute), false);

            if (attributes.Length > 0)
            {
                var actionNameAttr = (ActionNameAttribute)attributes[0];
                actionName = actionNameAttr.Name;
            }

            ActionName = actionName;
        }
Exemplo n.º 8
0
        private static void TestRouteParameterOptionality(int expectedCountOfRoutes, Type type, bool shouldThrow)
        {
            List <MethodInfo> methods = SitkaController.FindControllerActions(type);

            Assert.That(methods, Is.Not.Empty, $"Test Precondition: the test type {type} should have a controller action on it");

            if (shouldThrow)
            {
                Assert.Throws <PreconditionException>(() => RouteTableBuilder.SetupRouteTableImpl(methods), $"An illegal route was allowed into the route table! {type.Name}");
            }
            else
            {
                var routeEntries = new List <SitkaRouteTableEntry>();
                Assert.DoesNotThrow(() => routeEntries = RouteTableBuilder.SetupRouteTableImpl(methods), $"A legal route was not allowed into the route table! {type.Name}");
                Assert.That(routeEntries.Count, Is.EqualTo(expectedCountOfRoutes), $"Route count is not what was expected. {type.Name}");
            }
        }
Exemplo n.º 9
0
        private static IEnumerable <SitkaRouteTableEntry> MakeRoutesForSingleMethod(Dictionary <string, string> areasDictionary, MethodInfo controllerActionMethod, Dictionary <string, List <string> > getMethodsDict)
        {
            var sitkaRouteEntries    = new List <SitkaRouteTableEntry>();
            var controller           = SitkaController.ControllerTypeToControllerName(controllerActionMethod.ReflectedType);
            var controllerPartForUrl = SitkaController.ControllerTypeToControllerNameForUrl(controllerActionMethod.ReflectedType);

            var isRestrictedToPost = IsRestrictedToPost(controllerActionMethod);

            var httpPostRouteSuffix = (isRestrictedToPost ? "__HttpPost" : "");
            var action = controllerActionMethod.Name;

            var routeName = $"{controller}__{action}{httpPostRouteSuffix}";

            var allParameters = controllerActionMethod.GetParameters();

            var controllerAndAction = $"{controller}.{action}";
            var parameterString     = String.Join(",", allParameters.Select(x => $"{x.ParameterType.FullName} {x.Name}"));
            var actionControllerNameWithParameters = $"{controller}\t{action}\t{parameterString}";

            if (!isRestrictedToPost)
            {
                AssertOptionalParametersAreOnlyAtEndOfRoute(routeName, allParameters);

                if (!getMethodsDict.ContainsKey(controllerAndAction))
                {
                    getMethodsDict.Add(controllerAndAction, new List <string>());
                }
                getMethodsDict[controllerAndAction].Add(actionControllerNameWithParameters);
            }
            else
            {
                if (getMethodsDict.ContainsKey(controllerAndAction))
                {
                    if (!getMethodsDict[controllerAndAction].Any(actionControllerNameWithParameters.StartsWith))
                    {
                        var allGetRoutes = String.Join("\r\n", getMethodsDict[controllerAndAction]);
                        throw new ApplicationException($"The POST route {controllerAndAction} must have a corresponding GET route with the same parameters\r\nPOST route: {actionControllerNameWithParameters}\r\nGET routes: {allGetRoutes}");
                    }
                }
            }

            // see if it has a route attribute defined; if so, use that as the route url
            var routeAttribute = controllerActionMethod.GetCustomAttributes <RouteAttribute>(false).SingleOrDefault();

            // Now add in all the variants of the route based on parameter overloading
            // /Foo.mvc/Action/1 => FooController.Action(1)
            var appendParameters        = allParameters.OrderBy(p => p.Position).ToList();
            var crossAreaRouteAttribute = controllerActionMethod.GetCustomAttributes <CrossAreaRouteAttribute>(false).SingleOrDefault();
            var isCrossAreaRoute        = crossAreaRouteAttribute != null;

            if (areasDictionary == null || !areasDictionary.Any())
            {
                CreateSitkaTableRouteEntry(controllerActionMethod, appendParameters, routeAttribute, action, controller, routeName, sitkaRouteEntries, controllerPartForUrl, null, null, false);
            }
            else
            {
                if (isCrossAreaRoute)
                {
                    foreach (var areaKey in areasDictionary.Keys)
                    {
                        CreateSitkaTableRouteEntry(controllerActionMethod,
                                                   appendParameters,
                                                   routeAttribute,
                                                   action,
                                                   controller,
                                                   routeName,
                                                   sitkaRouteEntries,
                                                   controllerPartForUrl,
                                                   areaKey,
                                                   areasDictionary[areaKey],
                                                   true);
                    }
                }
                else
                {
                    var area = SitkaController.ControllerTypeToAreaName(controllerActionMethod.ReflectedType);
                    Check.Require(areasDictionary.ContainsKey(area), string.Format("Area \"{0}\" not found in Areas Dictionary!", area));
                    var areaAsSubdomainName = areasDictionary[area];
                    CreateSitkaTableRouteEntry(controllerActionMethod,
                                               appendParameters,
                                               routeAttribute,
                                               action,
                                               controller,
                                               routeName,
                                               sitkaRouteEntries,
                                               controllerPartForUrl,
                                               area,
                                               areaAsSubdomainName,
                                               false);
                }
            }
            return(sitkaRouteEntries);
        }