Cambio automático de cultura en ASP.NET 2.0

A la hora de hacer aplicaciones multi-idioma hay muchas cosas a tener en cuenta. Entre ellas la fundamental es averiguar cuál es el idioma que desea emplear el usuario y adaptar tanto la interfaz de usuario como las otras características culturales (números, fechas, etc) al idioma elegido.


Si no disponemos de una lista desplegable, unas banderitas, o algo similar para que los usuarios elijan el idioma, lo que debemos hacer es adaptarnos automáticamente al idioma elgido por éstos en su navegador (Herramientas·Opciones de Internet·General·Idioma).


La lista de idiomas allí presente se envía de manera automática y transparente por el navegador (no sólo IE, sino en todos los navegadores) al servidor en forma de cabeceras HTTP con el nombre «Accept-Language». Estas cabeceras se pueden capturar en el servidor muy fácilmente, y en ASP.NET más todavía con la propiedad UserLanguages, y con ellas trabajamos para conseguir la adaptación automática al idioma.


El código sería básicamente este (dentro de Global.asax):



void Application_BeginRequest (Object sender, EventArgs e)
{
    try
    {
        if (Request.UserLanguages.Length > 0)
        {
            CultureInfo ci = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
            Thread.CurrentThread.CurrentCulture = ci;
            Thread.CurrentThread.CurrentUICulture = ci;
        }
    }
    catch (ArgumentException)
    {
    }
}


Como vemos lo que se hace es determinar los idiomas que le interesan al usuario y asignar el primero de ellos al hilo de ejecución actual a través de una clase CultureInfo. Se le asigna esta clase tanto a CurrentCulture como la interfaz de usuario.


Con esto lo que conseguimos es que, luego en las paginas, se considere esta cultura para dar formato a fechas, números y monedas, y que se tengan en cuenta a la hora de hacer ciertas cosas en la interfaz que están relacionadas ya no sólo con el idioma (traducir) sino con las propias características particulares del idioma (es la diferencia entre traducir y localizar).


Si por ejemplo colocamos un calendario en nuestra página y una etiqueta que muestre la fecha seleccionada en el idioma actual, tendríamos estas dos capturas en función de si entramos con una navegador en castellano o uno en inglés de Estados Unidos:



Es interesante fijarse en como, no sólo se han traducido los nombres de los días de la semana o los meses en el calendario o en la fecha mostrada, sino que además se ha cambiado el día en el que se considera que comienza la semana (el domingo en el caso de los EEUU) y la forma de escribir y separar las diferentes partes de la fecha. Lo mismo pasaría con las monedas (algunas van delante otras detrás de la cantidad), los separadores decimales y de miles, y muchos detalles más.


Obviamente todavía nos quedaría traducir los recursos de texto de la aplicación, pero ya estamos ganado bastante.


ASP.NET 2.0: más fácil aún


Lo anterior es bastante fácil pero nos obliga de todos modos a escribir código. En ASP.NET 2.0 se ha simplificado más todavía este asunto presentando una característica denominada cambio automático de cultura. Existe un nuevo atributo de las páginas que sirve para indicar que se gestione de manera automática el idioma del usuario. Basta con poner en la delcaración de una página lo siguiente:


<%@ Page Language=»C#» AutoEventWireup=»true» Culture=»Auto» UICulture=»Auto» CodeFile=»Cultura.aspx.cs» Inherits=»Cultura» %>


Con esto conseguimos exactamente el mismo efecto que el código anterior en una página, y sin tener que escribir código de ningún tipo.


Por supuesto podemos conseguir el efecto automático para toda la aplicación al mismo tiempo introduciendo el sigueinte nodo en web.config:



<globalization culture=»auto» uiCulture=»auto» />


Es cómodo ¿verdad?

Sin categoría

30 thoughts on “Cambio automático de cultura en ASP.NET 2.0

  1. Hola, despues de ver varias paginas (incliyendo esta) logre que funcione el multilenguaje. Lo que queria saber es como hago para que cuando el ususrio de mi sitio web cambien de idioma, yo pueda crear un cookie para uqe este user siempre vea la pagina en el idioma que seleccono la primera vez. No obstante tiene la opcion de cambiar nuevamente el idioma.
    Desde ya muchas gracias.
    Para tener en cuenta: Desarollo en VS2005, y ya tengo los archivos de recursos

  2. Hola:

    Lo tienes explicado arriba: estableces el CurrentCulture y CurrentUICulture con el lenguaje deseado, leyéndolo desde la Cookie, dentro del beginRequest.

  3. hola lo he probado, pero no e podido ver los resultados, la linea no sé en donde exactamente ponerla..y con la prueba del global asa no encuentra CultureInfo, donde está esta clase?
    Gracias

  4. Hola:

    Lo explica en el post: el nodo debes ponerlo en el archivo web.config

    Para ver eso en Global.asax tienes que incluir el espacio de nombres System.Globalization

    o si lo prefieres pon directamente

    System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);

    Saludos

    JM.

  5. hola lo he probado, pero no e podido ver los resultados, la linea no sé en donde exactamente ponerla..y con la prueba del global asa no encuentra CultureInfo, donde está esta clase?
    Gracias

  6. Lo de ‘‘ lo meto en el web.config antes de la etiqueta ‘‘ pero me dice que no reconoce la configuracion de la seccion globalization, (me pone: ‘unrecognized configuration section globalization’), además en el global.asax me dice lo mismo.
    cabe decir que lo estoy poniendo todo a la vez, lo del global.asax y el web.config quizá solo haya que usar uno de los dos metodos y por eso falla

    gracias

  7. Sigo sin cambiar el idioma, hago lo que dices en los dos articulos conjuntamente
    El código sería básicamente este (dentro de Global.asax) y en ASP.NET 2.0: más fácil aún..
    Pero nada, dime cual es mi fallo.. es correcto crear el global y modificar el web.config …gracias

  8. Hola:

    En el web.config tiene que ir dentro del nodo ya que es configuración de la Web.

    Lo del Gloabl.asax es sólo si lo quieres hacer a mano o si usas versiones anteriroes de ASP.NET. En ASP.NET 2.0 no es necesario porque tienes lo anterior.

    De todos modos si pones System.Globalization delante de cultureInfo te tiene que funcionar perfectamente.

    Si no quieres meterlo recuerda que puedes meter directivas Imports en Global.asax para importar los espacios de nombres pertinentes, en este caso System.Globalization y System.Threading, así:

    < %@ Import Namespace="System.Globalization" %>
    < %@ Import Namespace="System.Threading" %>

    Saludos

    JM.

  9. hola, sigo con el mismo problemilla, no sé si tengo los archivos de recursos.
    Cómo sé si los tengo?
    No me da error al lanzar mi web al navegador pero no traduce nada..
    Si me puedes decir algo..gracias

  10. Hola d eneuvo:

    Lo siento pero no sé qué más decirte. Siguiendo esos pasos te aseguro que funciona perfectamente y no hay que hacer nada extraño ni tener nada especial instalado.

    Obviamente no hace traducción automática (sólo de las fechas, jeje) así que sí, claro, necesitarás tener tu aplicación traducida en archivos de recursos para que se vea algo traducido.

    De todos modos para comprobar que funciona no necesitas nada de eso, basta con que pongas un control calendar en el formulario como he hehco yo en el ejemplo y verás que, al cambiar de idioma, te muestra el calendario de otra forma.

    ¿Has probado a cambiar en el navegador el idioma preferido?

    JM

  11. No sería mas correcto poner ese codigo en unas masterpage o pagina base, y hacer todo el tema del idioma ahí. para reutilizarlo para otros proyectos?

    Gracias

  12. Hola:

    El código del principio no lo puedes poner en una Master Page ya que en ASP.NET 1.x no existían éstas.

    Si quieres puedes meterlo en una DLL y hacer la llamada desde el mismo evento Begin_Request de los global.asax de tus proyectos, pero es un código tan escueto que no sé si merecerá la pena.

    Saludos

    JM

  13. tengo una pequeña duda si tengo una tabla conteniendo el nombre de los paises en español, como le hago para que aparezca en varios idiomas? he usado los globalresources de forma estatica y yo lo quiero de forma dinamica para cargar el nombre de los paises en varios idiomas. bueno alguna idea?

  14. Después de seguir los pasos, he conseguido cambiar el idioma desde una cookie.
    Ahora tengo un problema porque no puedo modificar el Global.asax del que tirar muchas aplicacíones y el administrador no quiere que se modifique. ¿Puede poner ese código en otra parte?
    He probado en el Page_Load de un WebForm, pero no me cambia el idioma.

  15. una duda, en el ejemplo el nombre del mes y de los dias se muestra en minusculas, que propiedad debo usar para cambiar la primera latra de cada palabra a mayusculas
    ********ej. mayo=Mayo, lunes=Lunes??

    ayudita porfis, porfiss!!!!

  16. Hola Yesi:

    la verdad es que no tengo ni idea de cómo hacer que la primera letra aparezca en mayúsculas ya que el formato es estándar y en español (que yo sepa en todos los países) los nombres de los meses salen en minúsculas con cualquier fomato que le pongas 🙁

    Si alguien sabe o averigua cómo hacerlo que lo ponga aquí. Gracias.

    Saludos

    JM

  17. Hola, tengo un problemilla, estoy utilizando el calendar extender de ajax y no hace efecto la configuración … por favor alguien me puede decir como solucionar ese problema 🙁

  18. Hola José Manuel, siempre reviso tu Blog y me ha sacado de muchos apuros. Gracias mil por compartir tus conocimientos, saludos desde Tacna-Perú 🙂

    @Noe, con el permiso de José Manuel, la solución a tu problema es que coloques:

    EnableScriptGlobalization=»true» EnableScriptLocalization=»true»

    dentro del ScriptManager, quedando asi:

    Espero te sea de utilidad.

  19. José Manuel:
    Mil gracias por compartir tus conocimientos. Realmente necesitaba esta información. Funcionó de primera.
    Te hago una consulta. Estoy usando un Calendario que es gratuito y muy bueno que se llama PopCalendar2005 este tiene una propiedad que se llama Format, ahi debo poner el formato que tendrá la fecha. En el caso que uno sepa de antemano que la cultura es por ejemplo «es-AR» se le pone en format dd mm yyyy pero si no es esa y pongamos que es «en-US» habria que colocar mm dd yyyy. ¿Como puedo leer la CultureInfo actual y asi poder asignar el que corresponda automáticamente?
    No se si me hago entender.
    Desde ya muchas gracias nuevamente.

  20. Hola Juan Carlos:

    El formato actual lo puedes averiguar a través de la clase DateTimeFormat, que tiene multitud de propiedades para obtener esta información. Así, por ejemplo, para sacar erl formato de fec ha corta (que es lo que tú quieres) de la cultura actual, sólo tienes que escribir:

    Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern

    Investiga esta clase y verás que tienes muchísima información.

    Saludos

    JM Alarcón
    Tutor de campusMVP

  21. No quiero ser reiterativo, pero tengo que decirtelo de nuevo.
    GRACIAS! Mil Gracias.
    Efectivamente esa era la clase y con este pequeño código pude resolver el problema.

    ‘Definir una instancia de CultureInfo en cui con el CurrentCulture actual
    Dim cui As CultureInfo = CType(CultureInfo.CurrentCulture, CultureInfo)

    ‘Asignar los parámetros pertinenes al PopCalendar
    PopCalendar1.Culture = CultureInfo.CurrentCulture.Name
    PopCalendar1.Separator = Trim(cui.DateTimeFormat.DateSeparator)

    ‘Todo esto de abajo es para sacar los separadores del Pattern (Asi los requiere PopCalendar)
    Dim separador As String = PopCalendar1.Separator
    Dim plantilla As String = Trim(cui.DateTimeFormat.ShortDatePattern)
    Dim a, b As String
    For i As Integer = 1 To plantilla.Length
    b = Mid(plantilla, i, 1)
    a = a + IIf(b = separador, » «, b)
    Next
    PopCalendar1.Format = a.ToLower

    ‘Esto para los ToolTip
    txtFecha.ToolTip = «Ingrese una fecha. Formato: (» & PopCalendar1.Format & «)»
    PopCalendar1.ToolTip = «Seleccione una fecha. Formato: (» & PopCalendar1.Format & «)»

    ‘Esto es todo. Gracias a José M. Alarcón

    Bueno, Acepto criticas ;-))

    Saludos.

  22. En realidad no es muy difícil de hacer pero no deja de tener su grado de complejidad, es un sistema para la administración general de un colegio.
    Te cuento, en mis horas libres trabajo para un colegio ad-honorem, es un colegio para discapacitados y trato de colaborar con la gente que trabaja allí en lo que pueda, realmente son admirables lo que hacen con esos chicos. Yo soy tambien discapacitado y la informática y sobre todo la programación me fascina.
    Bueno José, te mando un gran abrazo y de todo corazón te agradezco por todo, fué muy valioso para mi.

    Saludos

    Juan Carlos

  23. Hola,
    Yo realizo esto, pero me sucede que en mi PC local el formato del Nº es ###,##0.#0 y Fecha dd/mm/yyy y cuando subo el sitio al servidor es ###.##0,#0 y dd-mm-yyyy. Lo necesito como el primer formato. ¿ Alguien puede saber que puede ser ?.

  24. GRacias amigo por compartir tus conocimientos. porque cuando se publica mi aplicacion toma la hora del servidor y no la del cliente este tema tiene que ver con el post?? como se puede solucionar esto??

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *