asp.net mvc multilanguage urls/routing

前端 未结 3 1156
太阳男子
太阳男子 2020-12-04 17:21

This is a two part question regarding asp.net mvc multilanguage urls/routing and SEO best practices/benefits…

Question Part 1)

I’m being ask

相关标签:
3条回答
  • 2020-12-04 17:37

    you can create base controller that have the localization logic as below:

     public abstract class LocalizedController : Controller
     {
         protected override void ExecuteCore()
         {
             HttpCookie cookie;
             string lang = GetCurrentCulture();
             Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang, false);
    
             // set the lang value into route data
             RouteData.Values["lang"] = lang;
    
             // save the location into cookie
             cookie = new HttpCookie("DPClick.CurrentUICulture",
                 Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName)
                 {
                     Expires = DateTime.Now.AddYears(1)
                 };
    
             HttpContext.Response.SetCookie(cookie);  
             base.ExecuteCore();
         }
    
         private  string  GetCurrentCulture()
         {
             string lang;
    
             // set the culture from the route data (url)
    
             if (RouteData.Values["lang"] != null &&
                !string.IsNullOrWhiteSpace(RouteData.Values["lang"].ToString()))
             {
                 lang = RouteData.Values["lang"].ToString();
                 if (Localization.Locales.TryGetValue(lang, out lang))
                 {
                     return lang;
                 }
             }
             // load the culture info from the cookie
             HttpCookie cookie = HttpContext.Request.Cookies["DPClick.CurrentUICulture"];
             if (cookie != null)
             {
                 // set the culture by the cookie content
                 lang = cookie.Value;
                 if (Localization.Locales.TryGetValue(lang, out lang))
                 {
                     return lang;
                 }
    
             }
             // set the culture by the location if not speicified
             lang = HttpContext.Request.UserLanguages[0];
             if (Localization.Locales.TryGetValue(lang, out lang))
             {
                 return lang;
             }
             //English is default
             return Localization.Locales.FirstOrDefault().Value;
    
         }
    
     }
    

    The above controller satisfy fashion 2 of your question if you want to ignore the culture folder just don't assign the lang in the RouteDate. offcourse to achieve fashion 2 you have to add routing for culture as below:

                routes.MapRoute(
                "Localization", // Route name
                "{lang}/{controller}/{action}/{id}", // URL with parameters
                new {controller = "Default", action = "Index", id = UrlParameter.Optional}, // Parameter defaults
                new {lang = @"\w{2,3}(-\w{4})?(-\w{2,3})?"}
                );
    
    0 讨论(0)
  • 2020-12-04 17:39

    To achieve what you want you basically need to implement three things:

    A multi-language aware route to handle incoming URLs:

    routes.MapRoute(
        name: "DefaultLocalized",
        url: "{lang}/{controller}/{action}/{id}",
        constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },   // en or en-US
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
    

    A LocalizationAttribute to handle these kinds of multi-language requests:

    public class LocalizationAttribute : ActionFilterAttribute
    {
        private string _DefaultLanguage = "en";
    
        public LocalizationAttribute(string defaultLanguage)
        {
            _DefaultLanguage = defaultLanguage;
        }
    
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string lang = (string)filterContext.RouteData.Values["lang"] ?? _DefaultLanguage;
            if (lang != _DefaultLanguage)
            {
                try
                {
                    Thread.CurrentThread.CurrentCulture =
                    Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
                }
                catch (Exception e)
                {
                    throw new NotSupportedException(String.Format("ERROR: Invalid language code '{0}'.", lang));
                }
            }
        }
    }
    

    An helper method to generate these URLs within your application: this can be done in multiple ways, depending on your application logic. For example, if you need to do it within your Razor Views, the best thing you can do is to write a couple extension methods to make your Html.ActionLink and Url.Action accept a CultureInfo object as a parameter (and/or use CultureInfo.CurrentCulture as the default one), such as the following:

    • Code sample for multi-language Html.ActionLink extension
    • Code sample for multi-language Url.Action extension

    (both are written in C#)

    You can also avoid the extension method pattern and write them as MultiLanguageActionLink / MultiLanguageAction instead.

    For additional info and further samples on this topic you can also read this post on my blog.

    0 讨论(0)
  • 2020-12-04 17:45

    AttributeRouting can solve Fashion 1:

    AttributeRouting - Localization

    0 讨论(0)
提交回复
热议问题