Internacionalizar entradas de usuario en ASP.NET MVC

A raíz de un comentario que me hicieron en el post Internacionalización en ASP.NET MVC que escribí hace unos días, decidí realizar este post que tenía pensado hacer próximamente. Pero ya que se da la situación, lo hacemos ahora.

La pregunta realizada por Oscar Polanco fue la siguiente:

…en MVC cómo hago para validar entradas de usuario, como fechas, numeros con decimales, etc…. para las diferentes culturas?

La verdad que nunca tuve la oportunidad de trabajar con aplicaciones internacionalizadas en las que haya una interacción de usuario (aunque sería un muy lindo desafío). Así que me puse a investigar como llevar adelante esta tarea, de que las entradas de los formularios de nuestra aplicación puedan adaptarse a las diferentes culturas. Y el resultado me dejó bastante conforme..

Para comenzar, debemos setear en el archivo Web.config la configuración para que nuestra aplicación pueda tomar la cultura del usuario que accede a la misma. Para ello debemos agregar la siguiente línea dentro de configuration > system.web:

Configuración de cultura en Web.Config
Configuración de cultura en Web.Config

Luego creamos un modelo (TestModel) el cual contiene las siguientes propiedades:

  • Id (int)
  • Name (string)
  • StartDate (DateTime)
  • Amount (decimal)

Lo primero que vamos a hacer es hacer que todas estas propiedades sean obligatorias, de forma que nos facilite determinar solo las validaciones que queremos probar.

Para las pruebas siempre vamos a usar dos navegadores. El de la izquierda está configurado en español (de Argentina), mientras que el de la izquierda en inglés.

La primera prueba que vamos a hacer es probar el ingreso de la fecha 21/12/2014, la cual es válida en nuestra zona (Argentina). El resultado que vemos es el siguiente:

FechaIncorrectaInicial
Prueba inicial de fecha válida en Argentina

Son varias las cosas que podemos ver ya con esta prueba. La primera es que los mensajes de error ya están en el idioma asociado a la cultura que tengamos configurada en el navegador. La segunda es que la fecha que ingresamos es validada como correcta en el navegador en español, pero no así en el que está en inglés.
Esto ya nos da la pauta de que el framework ya está tomando la cultura del navegador del usuario, utilizándolo para hacer estas validaciones.

Si probamos ingresar una fecha en formato inglés en el navegador correspondiente, vemos que la validación pasa correctamente. Si hacemos una prueba con decimales vemos que ocurre una situación similar. Usando un formato válido en nuestra región (usando la coma), vemos que da un error de validación para el navegador en inglés (donde el separador adecuado es el punto):

DecimalIncorrecta
Validación de formato decimal en distintas culturas

Ahora es el momento de hacer validaciones un poco más complejas que las requeridas, como pueden ser los rangos. Para ello modificamos el modelo para que quede de la siguiente forma:

ModeloConRange
Modelo con validaciones de rango

Como se ve, agregamos validaciones de rango para los campos de fecha y decimal. El detalle al que debemos prestar atención en ambos casos (además de agregar el tipo de dato al cual aplica el rango) es el formato en el que expresamos dichos valores máximos y mínimos. Estos deben estar en el formato Invariant Culture, de forma que el framework posteriormente pueda hacer las comparaciones. Para el caso de la fecha, el formato deberá ser yyyy/MM/dd, y para los decimales el separador deberá ser el punto.

Otro detalle que podemos observar en los decoradores de la propiedades del modelo es como están definidos los atributos Display. Los mismos utilizan archivos de recursos, de la misma forma que vimos en el post anterior. Solo debemos especificar la clave que contiene el contenido y el archivo de recursos que se utilizará.

Probemos ahora con estas modificaciones. Si ingresamos en ambos campos valores fuera de los rangos, veremos los siguientes mensajes de validación:

ValidacionesRangos
Validaciones de los rangos según la cultura

Efectivamente, vemos que el framework está interpretando correctamente el rango para cada cultura haciendo la validación correctamente y mostrando el mensaje de error con el formato adecuado. Si ponemos valores adecuados a los rangos y en el formato adecuado a cada cultura, las validaciones pasarán correctamente.

Lo único que nos quedaría probar es que los datos se guarden correctamente en nuestra base de datos, y posteriormente se visualicen correctamente en una vista de detalle al recuperarlos. Vamos a verlo.

Para ello creamos una tabla con los mismos campos que las propiedades de nuestro modelo, la cual agregamos a nuestra aplicación utilizando Entity Framework con el técnica Database First (la cual veremos en un próximo post). En la acción asociada al HttpPost de la vista que contiene el formulario, haremos el guardado en la base de datos de la siguiente forma:

GuardadoTestModel
Guardado del modelo en la base de datos

Ahora guardamos desde los dos navegadores y vamos a la base de datos, en la cual vemos que los mismos están correctamente guardados (independientemente de la cultura de origen):

SelectDatosInternacionalizacion
Select a los datos guardados

Ahora hagamos una vista de detalle para este modelo, hecha de la forma tradicional (en este caso con una plantilla para hacer más rápida la tarea):

VistaDetalle
Vista de detalle del modelo

Si accedemos a dicha vista desde ambos navegadores con sus configuraciones culturales, veremos el siguiente resultado:

VistaDetalleInternacionalizada
Vista de detalle con datos adaptados a la cultura

Efectivamente los datos son visualizados en el formato adecuado a cada cultura, sin tener que realizar algún trabajo adicional en la vista o en el modelo mediante algún decorador.

Como conclusión final, podemos ver que el framework nos ofrece una solución efectiva a la hora de internacionalizar nuestra aplicación interactiva con entradas de usuario. Solo debemos aplicar ciertas cosas en el formato adecuado, pero no debemos tratar con mayores complicaciones.

Una consideración no menor a tener en cuenta es que a la hora de trabajar manualmente con entradas de usuario (por ejemplo para tareas de comparación) anteriormente debemos pasarla al formato Invariant Culture, permitiendo que se trabaje en el formato estándar y no tengamos algún comportamiento no deseado.

Para un próximo post queda pendiente como tratar la internacionalización de las entradas de usuario con Javascript, de forma que podamos utilizar en nuestra aplicación Client-Side Validation (validaciones del lado del cliente, sin necesidad de que el navegador haga un Post HTTP con datos que no son correctos).

Espero que les sea útil, gracias por leer!!

Anuncios

9 comentarios en “Internacionalizar entradas de usuario en ASP.NET MVC

  1. Una pregunta. Hice esto para la validación de decimales, del lado cliente pasa perfectamente la coma, pero en el servidor lo valida y me envía de nuevo la vista diciendo que el valor debe ser un numero. Es decir esto me permite ingresar la coma del lado de cliente y NO me lo pasa del lado servidor. Me dice que el Modelo NO es valido. 😦

    Me gusta

    • Buenas tardes Adan, muchas gracias por leer!
      Te comento que acabo de hacer la prueba y me funciona correctamente. Lo único que encontré es que en Google Chrome con el idioma Español (Latinoamérica) hace esto que mencionas, asocia como separador decimal al punto y no a la coma, motivo por el cual no lo bindea al modelo (si lo hace si colocas el punto).
      Por las dudas es eso lo que te está pasando? Sino pasame alguna información adicional y veo como reproducir la misma situación.

      Saludos!!

      Me gusta

  2. Hola Diego,

    Tanto este como un post anterior sobre internacionalización son increíblemente buenos. Mi enhorabuena y muchas gracias.

    Yo quería preguntarte, si es recomendable o no y como se haría para que un usuario pudiera cambiar el idioma de la web pues pulsando en una banderita o escogiendo un idioma de alguna manera sin tener que ver con la configuración del navegador.

    Muchas gracias

    Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s