コード例 #1
0
        /// <summary>
        /// Create the new list of action models for each localized route.
        /// </summary>
        /// <param name="controllerModel"></param>
        /// <param name="actionModel"></param>
        /// <param name="parameterTemplate"></param>
        /// <param name="sortedRouteParameters"></param>
        /// <returns></returns>
        public List <ActionModel> CreateLocalizedActionRoutes(ControllerModel controllerModel, ActionModel actionModel, string parameterTemplate, List <string> sortedRouteParameters)
        {
            string controllerName = controllerModel.ControllerName;
            string actionName     = actionModel.ActionName;
            var    actionLocalizationsAttributes = actionModel.Attributes.OfType <LocalizationRouteAttribute>().ToList();

            List <ActionModel> localizedActions = new List <ActionModel>();

            // For default actions we need to check if the [LocalizationRoute] Attribute exists or not.
            // This is so we can name the default action after the controller
            // For example otherwise HomeController for finnish Culture would be Home instead of Koti.
            if (actionName.Equals(LocalizationRouteDataHandler.DefaultAction, StringComparison.OrdinalIgnoreCase))
            {
                HashSet <string> cultures = LocalizationRouteDataHandler.SupportedCultures.Select(kvp => kvp.Key).ToHashSet();

                cultures.Remove(LocalizationRouteDataHandler.DefaultCulture);
                cultures.RemoveWhere(x => actionLocalizationsAttributes.FirstOrDefault(attr => attr.Culture == x) != null);

                // Iterate over all controllers that had a [LocalizationRoute]
                foreach (string culture in cultures)
                {
                    // The localized controller name is the link for the index action
                    string localizedControllerName = GetLocalizedControllerName(controllerModel, culture);
                    if (!localizedControllerName.Equals(controllerName, StringComparison.OrdinalIgnoreCase))
                    {
                        LocalizationRouteDataHandler.AddActionRouteData(controllerName, actionName, culture, "", localizedControllerName, sortedRouteParameters);
                    }
                }
            }

            foreach (LocalizationRouteAttribute attribute in actionLocalizationsAttributes)
            {
                string route = attribute.Route + parameterTemplate;
                // This copies all existing Attributes on the ActionModel,  [Route] [HttpGet] e.t.c.
                // Source file: https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/ApplicationModels/ActionModel.cs
                ActionModel newLocalizedActionModel = new ActionModel(actionModel);

                // Clear the Selectors or it will have shared selector data from default route.
                // This however clears the ActionConstraints like [HttpGet] and [HttpPost]
                newLocalizedActionModel.Selectors.Clear();
                AttributeRouteModel newLocalizedAttributeRouteModel = new AttributeRouteModel();
                newLocalizedAttributeRouteModel.Template = route;
                // Add the new actionModel for adding to controller later
                localizedActions.Add(newLocalizedActionModel);

                AddAttributeRouteModel(newLocalizedActionModel.Selectors, newLocalizedAttributeRouteModel);
                // Bug mentioned by anonymous through a comment on blog.
                // This is where the [HttpGet], [HttpPost] constraints are added back after being cleared earlier.
                foreach (var actionConstraint in actionModel.Selectors.Where(x => x.ActionConstraints.Count > 0).SelectMany(x => x.ActionConstraints))
                {
                    newLocalizedActionModel.Selectors[0].ActionConstraints.Add(actionConstraint);
                }

                string linkName = attribute.Link;
                // If the action is default (Index) and there is no LinkName set
                // Then the linkName should be the controllers name
                if (actionName.Equals(LocalizationRouteDataHandler.DefaultAction, StringComparison.OrdinalIgnoreCase) && !String.IsNullOrEmpty(linkName))
                {
                    linkName = GetLocalizedControllerName(controllerModel, attribute.Culture);
                }

                // Add the localized route for the action
                // Example of final route:  "fi/koti" + "/" + "ota_yhteyttä"
                LocalizationRouteDataHandler.AddActionRouteData(controllerName, actionName, attribute.Culture, attribute.Route, linkName, sortedRouteParameters);
            }

            return(localizedActions);
        }
コード例 #2
0
        /// <summary>
        /// Adds the localized routes for a controller
        /// </summary>
        /// <param name="controllerModel"></param>
        public void AddActionRoutes(ControllerModel controllerModel)
        {
            string controllerName = controllerModel.ControllerName;
            // All the new localized actions to add to the controllerModel after all calculations.
            List <ActionModel> newActions = new List <ActionModel>();

            // Loop through all the actions to add their routes and also get the localized actions
            foreach (ActionModel action in controllerModel.Actions)
            {
                string actionName = action.ActionName;
                // If any parameters are needed such as /{index}
                string parameterTemplate = "";

                SelectorModel defaultSelectionModel = action.Selectors.FirstOrDefault(x => x.AttributeRouteModel != null);

                List <string> sortedRouteParameters = new List <string>();

                // If there is no [Route()] Attribute then create one for the route.
                if (defaultSelectionModel == null || defaultSelectionModel.AttributeRouteModel == null)
                {
                    AttributeRouteModel attributeRouteModel = new AttributeRouteModel();

                    if (action.Parameters.Count > 0)
                    {
                        foreach (ParameterModel parameter in action.Parameters)
                        {
                            sortedRouteParameters.Add(parameter.ParameterName.ToLower());
                            // TODO: ParseParameterTemplate? I think you can't skip the [Route] attribute if you want parameters.
                        }
                    }

                    if (!action.ActionName.Equals(LocalizationRouteDataHandler.DefaultAction, StringComparison.Ordinal))
                    {
                        attributeRouteModel.Template = actionName;
                        // Add the action name as it is eg: about will be about!
                        LocalizationRouteDataHandler.AddActionRouteData(controllerName, actionName, LocalizationRouteDataHandler.DefaultCulture, actionName, actionName, sortedRouteParameters);
                    }
                    else
                    {
                        // For DefaultAction we don't want to have a template.
                        // Because the default action is reachable with /Controller as the url.
                        attributeRouteModel.Template = "";
                        LocalizationRouteDataHandler.AddActionRouteData(controllerName, actionName, LocalizationRouteDataHandler.DefaultCulture, "", controllerName, sortedRouteParameters);
                    }

                    AddAttributeRouteModel(action.Selectors, attributeRouteModel);
                }
                // If a route already existed then check for parameter arguments to add to the cultural routes
                else
                {
                    string template = defaultSelectionModel.AttributeRouteModel.Template;

                    parameterTemplate = ParseParameterTemplate(template, sortedRouteParameters);

                    LocalizationRouteDataHandler.AddActionRouteData(controllerName, actionName, LocalizationRouteDataHandler.DefaultCulture, actionName, actionName, sortedRouteParameters);
                }

                var localizedActions = CreateLocalizedActionRoutes(controllerModel, action, parameterTemplate, sortedRouteParameters);
                newActions.AddRange(localizedActions);
            } // End foreach controllerModel.Actions

            // Now add all the new actions to the controller
            foreach (ActionModel action in newActions)
            {
                controllerModel.Actions.Add(action);
            }
        }