AttributeRouting icon indicating copy to clipboard operation
AttributeRouting copied to clipboard

extending TranslationProviderBase

Open Jogai opened this issue 11 years ago • 2 comments

I try to make my own translation provider. Currently I have this:

public class MyTranslationProvider : TranslationProviderBase
    {
        private ILocalization _localization { get; set; }
        private Localization localization { get; set; }

        public MyTranslationProvider()
        {
            _localization = Frontend.IocContainer.Resolve<ILocalization>();
            localization = new Localization(_localization);
        }

        public override IEnumerable<string> CultureNames
        {
            //get active translations from my database
            get { return localization.GetCultures(); }
        }

        public override string GetTranslation(string key, string cultureName)
        {
            return localization.GetString(key);
        }
    }

And its configured (and get instantiated).

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.Clear();
            // See http://github.com/mccalltd/AttributeRouting/wiki for more options.
            // To debug routes locally using the built in ASP.NET development server, go to /routes.axd
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{language}/{controller}/{action}/{id}",
                defaults: new {language = "EN", controller = "Home", action = "Index", id = UrlParameter.Optional}
                );

            routes.MapRoute(
                name: "NoLanguage",
                url: "{controller}/{action}/{id}",
                defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}
                );

            routes.MapAttributeRoutes(config =>
                {
                    config.AddTranslationProvider(new MyTranslationProvider());
                    //config.ConstrainTranslatedRoutesByCurrentUICulture = true;
                    config.CurrentUICultureResolver = (httpContext, routeData) =>
                        {
                            return (string) routeData.Values["language"]
                                   ?? Thread.CurrentThread.CurrentUICulture.Name;
                        };
                });
        }

But getTranslation never gets called despite my translationkey in my controller:

    [Authorize]
    [RoutePrefix("{language}/My", Precedence = 1, TranslationKey = "AccountRoute")]
    public class MyController : BaseController
    {
        [AllowAnonymous]
        [GET("Registration", TranslationKey = "RegisterAction")]
        public ActionResult Registration()
        {
            return View();
        }
    }

Thus all links are not localized:

@Html.ActionLink((string) ViewBag.Registration, "Registration", "My")

Result in host.tld/NL/My/Registration or host.tld/EN/My/Registration

Jogai avatar Apr 26 '13 15:04 Jogai

Looks like there's nothing stopping the first registered route from matching during route gen. Also, you have also not told AR to scan for anything (it assumes nothing by default). Do this:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Clear();

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    // See http://github.com/mccalltd/AttributeRouting/wiki for more options.
    // To debug routes locally using the built in ASP.NET development server, go to /routes.axd

    // TODO: Ensure this is before the MapRoute calls below, 
    // otherwise those routes will match before your AR's and cause you confusion.
    routes.MapAttributeRoutes(config =>
    {
        // TODO: Tell AR where to look for routes.
        config.AddRoutesFromAssemblyOf<MyController>();

        config.AddTranslationProvider(new MyTranslationProvider());
        //config.ConstrainTranslatedRoutesByCurrentUICulture = true;
        config.CurrentUICultureResolver = (httpContext, routeData) =>
        {
            return (string) routeData.Values["language"]
                   ?? Thread.CurrentThread.CurrentUICulture.Name;
        };
    });

    routes.MapRoute(
        name: "Default",
        url: "{language}/{controller}/{action}/{id}",
        defaults: new {language = "EN", controller = "Home", action = "Index", id = UrlParameter.Optional}
    );

    routes.MapRoute(
        name: "NoLanguage",
        url: "{controller}/{action}/{id}",
        defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}
    );
}

Let me know what happens.

mccalltd avatar Apr 26 '13 23:04 mccalltd

Well, that helps, but in any case there is always a route first without the localized route attributes. When I look in my routes.axd the first one is:

GET, HEAD {language}/My/Registration

The localized routes are like this (for dutch in this example, but there is one for every language):

GET, HEAD Mijn/Registratie
controller: My action: Registration inboundHttpMethod: IRouteConstraintProxy namespaces: Name.Space.Site.Controllers defaultSubdomain: www cultureName: NL

but they dont work because the're not in the format of {language}/{controller}/{action} and give a 404.

And then there are routes like this for every language (again, dutch example): GET, HEAD My_RoutePrefixUrl/Registratie But they dont work either because they fail on the CurrentUICultureResolver because there is no languageparameter, even if I do a tranlation for My_RoutePrefixUrl like NL/Registratie.

What I want to do is for every language a twolettercode after the root like /NL and after that a translated controller and action like /NL/Mijn/Registratie

Jogai avatar May 01 '13 14:05 Jogai