Exemplo n.º 1
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.º 2
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.º 3
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);
        }