2011-07-19 52 views
17

Ésta es una pregunta de dos partes con respecto asp.net mvc multilenguaje urls/enrutamiento y las mejores prácticas de SEO/beneficios ...asp.net mvc URLs multilenguaje/enrutamiento

Pregunta Parte 1)

estoy se le pide que cree un nuevo sitio web ASP.NET MVC que admitirá un mínimo (al principio) de dos idiomas (inglés y francés) quizás en el futuro, 3 idiomas ...

En cuanto a la localización de la aplicación (labels, jQuery errores, etc.) las cosas deberían estar bien usando los archivos de recursos y he encontrado muchos ejemplos sobre esto ... pero mi conce rn/question es más acerca de las URL.

En términos de SEO, ¿cuál es el enfoque recomendado entre estas dos modas?

Fashion 1 (no culture folder) 
www.mydomain.com/create-account 
www.mydomain.com/creer-un-compte 

Fashion 2 (with built in culture folder) 
www.mydomain.com/create-account 
www.mydomain.com/fr/creer-un-compte <--notice the “fr” folder 

¿Existe un problema o una penalización conocidos al usar uno sobre el otro?

¿O es tan pequeño que se vuelve irrelevante?


Pregunta Parte 2)

Para lograr Moda 2, ya he encontrado un artículo aquí: ASP.NET MVC - Localization route

Pero tengo curiosidad para encontrar la forma de lograr la moda 1

¿Alguien tiene algún enlace?

Además, y por lo que yo sé, la reescritura de URL es no lo que estoy buscando desde que no deseo “redirigir” usuarios ... Simplemente quiero las direcciones URL que se muestran en el idioma apropiado sin tener para mostrar la cultura en la url

Gracias de antemano por cualquier ayuda sobre esto!

Respuesta

18

puede crear controlador de base que tiene la lógica de localización de la siguiente manera:

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; 

    } 

} 

El controlador citados cumplen con la moda 2 de su pregunta si desea ignorar la carpeta de la cultura simplemente no asignar el idioma en el RouteDate.offcourse para lograr la moda 2 que hay que añadir el enrutamiento para la cultura de la siguiente manera:

  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

¡Guau, gracias Feras! Este código es excelente y me ayuda a comprender más acerca del enrutamiento y la localización. – Vlince

+0

Bienvenido en cualquier momento. –

+5

@FerasKayyali Hola Feras, gracias por compartir información. Estoy usando su código, pero encontré que la localización no puede ser reconocida por VS 2012. ¿Cuál es su espacio de nombres y dll? Thx – Franva

1

Para lograr lo que desea que básicamente necesita para implementar tres cosas:

Un multi-idioma ruta conscientes para manejar las direcciones URL entrantes:

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 } 
); 

Un LocalizationAttribute para manejar este tipo de solicitudes en varios idiomas:

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)); 
      } 
     } 
    } 
} 

Un método de ayuda para generar estas URL dentro de su aplicación: Esto se puede hacer de varias maneras, dependiendo de su lógica de aplicación. Por ejemplo, si necesita hacerlo dentro de sus Razor Views, lo mejor que puede hacer es escribir un par de métodos de extensión para hacer que su Html.ActionLink y Url.Action acepten un objeto CultureInfo como parámetro (y/o use CultureInfo.CurrentCulture como el predeterminado), tales como los siguientes:

(ambos escritos en C#)

puede también evite el patrón de método de extensión y escríbalo como MultiLanguageActionLink/MultiLanguageAction.

Para obtener información adicional y más muestras sobre este tema, también puede leer this post.