public static Route MapLocalizedRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }
            if (url == null)
            {
                throw new ArgumentNullException("url");
            }

            var route = new LocalizedRoute(url, new MvcRouteHandler())
            {
                Defaults = new RouteValueDictionary(defaults),
                Constraints = new RouteValueDictionary(constraints),
                DataTokens = new RouteValueDictionary()
            };

            if ((namespaces != null) && (namespaces.Length > 0))
            {
                route.DataTokens["Namespaces"] = namespaces;
            }

            routes.Add(name, route);

            return route;
        }
Пример #2
0
 public static IEnumerable<LocalizedRoute> GetLocalizedRoutes(this RouteCollection routes)
 {
     foreach (var item in routes)
     {
         if (item is Route)
         {
             var localizedRoute = new LocalizedRoute(item as Route);
             if (localizedRoute.Language != null)
             {
                 yield return localizedRoute;
             }
         }
     }
     yield break;
 }
Пример #3
0
        /// <summary>
        /// Localizes all convention-based routes in the <paramref name="routeCollection"/> with a custom configured
        /// <see cref="LocalizationOptions"/> instance. This method should be called after all routes have been configured.
        /// </summary>
        /// <param name="routeCollection">The collection containing all the routes of the ASP.NET MVC application.</param>
        /// <param name="options">A callback to configure the default <see cref="LocalizationOptions"/> instance.</param>
        /// <exception cref="ArgumentException"><paramref name="routeCollection"/> is null.</exception>
        public static void Localize(this RouteCollection routeCollection, Action <LocalizationOptions> options)
        {
            if (routeCollection == null)
            {
                throw new ArgumentNullException(nameof(routeCollection));
            }

            // Create and initialize a new LocalizationOptions instance
            var localizationOptions = new LocalizationOptions();

            options?.Invoke(localizationOptions);
            localizationOptions.Dictionary.Init(localizationOptions.MvcTopologyProvider);

            // Create separate collection for all named and unnamed routes
            var namedMap = typeof(RouteCollection).GetField("_namedMap", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(routeCollection)
                           as Dictionary <string, RouteBase>
                           ?? throw new InvalidOperationException($"There is no _namedMap field in the {nameof(RouteCollection)} class.");
            var unnamedRoutes = routeCollection.Except(namedMap.Values);

            // And combine them to a common list with their nullable names as key
            var routes = namedMap.Concat(unnamedRoutes.Select(route => new KeyValuePair <string, RouteBase>(null, route))).ToList();

            // Iterate through all available routes
            foreach (var routeItem in routes)
            {
                // Which has the type Route
                if ((routeItem.Value is Route route) && (route.GetType() == typeof(Route)))
                {
                    // Create a new LocalizedRoute proxy
                    string routeName      = routeItem.Key;
                    var    localizedRoute = new LocalizedRoute(route, localizationOptions.Dictionary);

                    // Replace the original route with this new one
                    int index = routeCollection.IndexOf(route);
                    routeCollection[index] = localizedRoute;
                    if (!string.IsNullOrEmpty(routeName))
                    {
                        namedMap[routeName] = localizedRoute;
                    }
                }
            }
        }
        /// <summary>
        /// Creates localized routes
        /// You can override this method to change the source of localized routes - DB, File,...
        /// </summary>
        /// <returns>Localized routes</returns>
        protected virtual async Task <IEnumerable <LocalizedRoute> > GetRoutesAsync()
        {
            /*
             *
             *  LocalizedRouteController -  LocalizedRouteAction
             *  LocalizedRouteController -  RouteAction
             *  LocalizedRouteController -  OriginalAction
             *  RouteController - LocalizedRouteAction
             *  OriginalController - LocalizedRouteAction
             *
             */

            var localizedRoutes = new List <LocalizedRoute>();

            foreach (var routeDescriptor in _controllerActionDescriptorProvider.Get())
            {
                routeDescriptor.RouteValues.TryGetValue("controller", out var controller);
                routeDescriptor.RouteValues.TryGetValue("action", out var action);

                var controllerLocalizedRouteAttributes = GetControllersAttribute <LocalizedRouteAttribute>(routeDescriptor);
                var controllerRouteAttributes          = GetControllersAttribute <RouteAttribute>(routeDescriptor);
                var actionLocalizedRouteAttributes     = GetMethodsAttribute <LocalizedRouteAttribute>(routeDescriptor);
                var actionRouteAttributes = GetMethodsAttribute <RouteAttribute>(routeDescriptor);

                foreach (var controllerLocalizedRouteAttribute in controllerLocalizedRouteAttributes)
                {
                    var actionLocalizedRouteAttribute = actionLocalizedRouteAttributes
                                                        .FirstOrDefault(s => s.Culture == controllerLocalizedRouteAttribute.Culture);

                    if (actionLocalizedRouteAttribute != null)
                    {
                        AddLocalizedRoute(controllerLocalizedRouteAttribute.Culture, controllerLocalizedRouteAttribute.Template, actionLocalizedRouteAttribute.Template);
                    }
                    else if (actionRouteAttributes.Any())
                    {
                        foreach (var actionRouteAttribute in actionRouteAttributes)
                        {
                            AddLocalizedRoute(controllerLocalizedRouteAttribute.Culture, controllerLocalizedRouteAttribute.Template, actionRouteAttribute.Template);
                        }
                    }
                    else
                    {
                        AddLocalizedRoute(controllerLocalizedRouteAttribute.Culture, controllerLocalizedRouteAttribute.Template, action);
                    }
                }

                foreach (var controllerRouteAttribute in controllerRouteAttributes)
                {
                    foreach (var actionLocalizedRouteAttribute in actionLocalizedRouteAttributes)
                    {
                        AddLocalizedRoute(actionLocalizedRouteAttribute.Culture, controllerRouteAttribute.Template, actionLocalizedRouteAttribute.Template);
                    }

                    foreach (var actionRouteAttribute in actionRouteAttributes)
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controllerRouteAttribute.Template, actionRouteAttribute.Template);
                        }
                    }

                    if (!actionRouteAttributes.Any() && !actionLocalizedRouteAttributes.Any())
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controllerRouteAttribute.Template, action);
                        }
                    }
                }

                if (!controllerLocalizedRouteAttributes.Any() && !controllerRouteAttributes.Any())
                {
                    foreach (var actionLocalizedRouteAttribute in actionLocalizedRouteAttributes)
                    {
                        AddLocalizedRoute(actionLocalizedRouteAttribute.Culture, controller, actionLocalizedRouteAttribute.Template);
                    }

                    foreach (var actionRouteAttribute in actionRouteAttributes)
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controller, actionRouteAttribute.Template);
                        }
                    }

                    if (!actionLocalizedRouteAttributes.Any() && !actionRouteAttributes.Any())
                    {
                        foreach (var culture in _supportedCultures)
                        {
                            AddLocalizedRoute(culture.Name, controller, action);
                        }
                    }
                }

                void AddLocalizedRoute(string cultureName, string controllerName, string actionName)
                {
                    localizedRoutes.Add(LocalizedRoute.Create(cultureName,
                                                              RouteInformation.Create(controller, action),
                                                              RouteInformation.Create(controllerName, actionName)));
                }
            }

            return(localizedRoutes);
        }