June 2007 - Artículos

¿Es necesario instalar Microsoft AJAX Extension en mi servidor de producción?

Es una pregunta muy frecuente que me encuentro en foros y NewsGroup.

La respuesta es sí y creo que el porqué (sino estoy equivocado) es esta nota que encuentras en la documentación de ASP.NET AJAX sobre el proceso de instalación:

The installation process installs the ASP.NET AJAX assembly (System.Web.Extensions.dll) in the global assembly cache (GAC). Do not include the assembly in the Bin folder of your AJAX-enabled Web site.

http://ajax.asp.net/docs/InstallingASPNETAJAX.aspx

Es lógico no, si tira de la GAC (Ya que la DLL no se incluye en el Bin) y no tenemos la DLL instalada en el servidor, la aplicación fallará (Error J a v a s c r i p t: Sys no está definido creo que dá) puesto que es la que contiene el Framewrok de Cliente: Microsoft AJAX Library y el Framework de Servidor: ASP.NET AJAX Extensions. Lo que no sé si añadiendo (Si se puede) a manubrio la assembly System.Web.Extensions.dll al GAC sin msi funcionará...

Si alguien conoce mas a fondo el porqué o si estoy equivocado que me corrija y así aprendemos todos ;)

Salu2

We Love... Web

Ayer tuve la suerte de asistir al evento que ilitia Technologies SRL preparó en las instalaciones de Microsoft Ibérica.

El formato era muy novedoso y la verdad es que me gusto bastante. Era al primer evento al que asistía en el que no estas escuchando hablar a una persona/as durante 5 horas en las que alguna de las veces cierras los ojos o pegas una cabezada que otra, sino que pude participar con mi portátil realizando Hand on Labs con una máquina virtual que habían preparado. La agenda fue la siguiente:

Microsoft Office Sharepoint Server 2007 - Mañana

A lo largo de esta sesión nos familiarizaremos con la plataforma y la forma de trabajar de una forma sencilla y efectiva y posteriormente nos adentraremos un poco más en aquellos detalles técnicos de la misma. Todo el material teórico se reforzará con la inclusión y puesta en práctica de un conjunto de Hands On Lab guiados por instructor, permitiendo experimentar en tiempo real todos los conceptos, técnicas y herramientas expuestos.

Agenda de la sesión

Introducción a Entornos Colaborativos

- Arquitectura del entorno.

Overview de SharePoint

- Administración.

- Seguridad y Gestión de Roles / Permisos.

- Creación de Sitios y Listas.

- Creación de páginas Maestras.

- Desarrollo de Web Parts.

Sistema de Búsquedas

- Introducción a los sistemas de Búsquedas

- Creación de Áreas de Búsquedas personalizadas

Hands On Lab guiados por Instructor

                               Evaluación y preguntas

            Microsoft AJAX Extensions 1.0 para ASP.NET 2.0 - Tarde

En esta sesión trataremos las bases de la arquitectura de AJAX a nivel global, la serialización JSON (JavaScript Object Notation) y posteriormente nos centraremos en los detalles más técnicos del framework AJAX de Microsoft, las librerías de controles de servidor y cliente. Todo el material teórico se reforzará con la inclusión y puesta en práctica de un conjunto de Hands On Lab guiados por instructor, permitiendo experimentar en tiempo real todos los conceptos, técnicas y herramientas expuestos.

Agenda de la sesión

Introducción a AJAX Extensions

- Arquitectura

Desarrollo web asíncrono con ASP.NET 2.0

- Desarrollo en el lado de cliente, AJAX Client Library

- Desarrollo en el lado de servidor, AJAX Server Controls

- Asincronía basada en servicios Web

- Depuración de aplicaciones AJAX

Modelo de controles y componentes

- Introducción a AJAX Control Toolkit

- Desarrollo de AJAX Extenders

Hands On Lab guiados por Instructor

Evaluación y preguntas

Las 2 ponencias las llevaron a cabo David Herraiz (Por fin tuve el placer de conocerle personalmente) que nos mostró de maravilla lo poderoso que es Share Point 2007 y Miguel Jimenez que nos deleitó con una charla sobre AJAX y todo esto seguido de sus correspondientes Hand On Labs.

El balance por mi parte fue muy positivo y espero que esto sea sólo el principio de una nueva forma de vivir los eventos ;)

Felicidades y gracias a Ilitia.

Salu2

Una anécdota: Los lenguajes pedaleros

La verdad es que en el cliente donde estoy (no diré su nombre por respeto) cada día que paso alucino más y es que como dice mi novia:

Lo que Dios no dá, Salamanca no lo enseña...

Y porqué digo esto pues porqué cada día oigo decir algún Jefe de Poyecto (sí si, habéis leido bien, como la Poyeya pero en informática) barbaridades y claro, es que es Jefe de Poyecto porque cuando se hizo el sorteo de puestos le tocó la bola, o quizás porque es un pelota y si a eso le sumas que sólo existen 3 categorías: Analista - Jefe de Poyecto y Director...

Vamos al tema:

Estamos montando aplicaciones con ASP.NET 2.0, ATLAS y SAP Connector y la verdad es que el resultado es increible pero sólo saber poner pegas:

Es que esto en Oracle, no es así... porque esto en Oracle... porque aquello en Oracle... proque Oracle es mejor...

Yo día a día trato de enseñarles que Oracle y NET/JAVA... son 2 cosas totalmente diferentes y que la conbinación de NET, JAVA... y este gestor de base de datos permite sacarle un mayor provecho al negocio, mejorar la experiencia de usuario, mayor portabilidad, menores coste de despliegue y actualización... que trabajar en Cliente/Servidor con Developer 6, pero no lo entienden,  si el explorer da un problema es el .NET, si pido una consulta de 2.000.000 de registros a SAP y tarda es el .NET, si JavaScript no permite acceder al disco duro del cliente menuda mierda el .NET y podría tirarme 2 horas enumerando, pero hoy si que me he quedao de piedra y por eso la publicación de este post. Me dice un Jefe de Poyecto:

Te puedo hacer una pregunta: El portal corporativo se está desarrollando con JAVA ¿No?

Si

¿JAVA es tan pedalero como el punto NET ese?

Abro IE, tecleo www.rae.es, busco y:

pedalero, ra.

1. adj. Chile. Perteneciente o relativo al ciclismo.

2. m. y f. Chile. ciclista (‖ persona que practica el ciclismo).

Mi respuesta: NO

Gracias...

Pues nada chavales voy a seguir dando pedales ;)

Salu2

Publicado por Luis Ruiz Pavón | 6 comment(s)
Archivado en:

ASP.NET: Almacenamiento del estado de la sesión (Session State Mode)

El otro día un compañero me comentó:

Luis, estamos desarrollando una aplicación Web y como Session State Mode estamos utilizando InProc, pero no sabemos sí esta va a ser la configuración final. ¿Que debemos tener en cuenta en el desarrollo para que esta modificación no nos afecte?

A lo que le respondí:

¿Sabes cual es la diferencia entre los distintos Session State Mode?

El respondió:

No muy bien, te importaría explicarmelo.

ASP.NET soporta 5 tipos diferentes para el almacenamiento de la sesión:

  1. InProc: Es el modo por defecto. El estado de la sesión se almacena en la memeria del servidor web y es el que ofrece mejor rendimiento, pero como desventajas se pueden destacar  que no se persiste si reinicias la aplicación web o a traves varios servidores(Web Farm).
  2. State Server: El estado de la sesión se almacena en un servicio llamado ASP.NET State Service y el estado de la sesión persiste aunque reinicies la aplicación o a traves de varios servidores (Web Farm) pero ofrece menor rendimiento que el modo InProc
  3. SQL Server: El estado de la sesión se almacena en una base de datos de SQL Server. En las mismas condiciones de Hardware, ofrece menor rendimiento que State Server pero ofrece una mejor integridad de los datos y reporting.
  4. Custom: Permite especificar tu propio proveedor de almacenamiento de la sesión, eso sí, necesitas implentarlo tú.
  5. Off: Deshabilitar el estado de la sesión. Si en tu aplicativo no usas sesión, deshabilitalo para un mejor rendimiento.

Ahora me queda más claro, pero no has respondido a mi pregunta, ¿En que me afecta al desarrollo una u otra?

Pues la suerte que tenemos los desarrolladores es que es transparente en nuestro desarrollo que una vez puesta en producción un adminsitrador o nosotros mismos modifiquemos el Session State Mode, eso sí, siempre y cuando no lo deshabilitemos, porque no podremos utilizar variables de sesión y eso si nos condicionará el desarrollo.

¿Y que pasa si se deshabilita y en mi aplicación estoy trabajando con variables de Sesión?

Pues que ASP.NET cantará:

Sólo puede utilizar el estado de sesión cuando enableSessionState está establecido como true, en un archivo de configuración o en la directiva de la página

Muchas gracias Luis

Espero que os haya servido como a mi amigo ;)

Salu2

Publicado por Luis Ruiz Pavón | 12 comment(s)
Archivado en: ,,

Mejoras en ADO.NET 2.0: El método DataTable.Load

Para los que no conocéis este método aún, os diré que es una de las nuevas mejoras de ADO.NET 2.0 que mas me gusta.

En versiones anteriores de ADO.NET, para devolver un DataTable, teníamos que hacer todo aquella parafernalia de la conexión, comando, dataadapter, dataset... y el DataSet está pansado como un conjunto de resultados, entones tener que cargarlo con una sola tabla para tener que estar accediendo a su colección de tablas para devolver la tabla en concreto, no tiene mucho sentido desde mi punto de vista.

Ahora el DataTable viene provisto de un nuevo método Load, que podemos cargar el DataTable con los valores de un origen de datos utilizando la interfaz IDataReader:

   1:  DataTable table = new DataTable();
   2:   
   3:  using (SqlConnection conexion
   4:         = new SqlConnection("Cadena de Conexión"))
   5:  {
   6:      using (SqlCommand command = new SqlCommand())
   7:      {
   8:          command.Connection = conexion;
   9:          command.CommandText = "SELECT * FROM Tabla";
  10:   
  11:          conexion.Open();
  12:          using (SqlDataReader reader =
  13:              command.ExecuteReader
  14:                  (CommandBehavior.CloseConnection))
  15:          {
  16:              table.Load(reader);
  17:          }
  18:      }
  19:  }

 Además de esta manera seguimos manteniendo toda la potencia del objeto DataTable con un mejor performance en el acceso a datos ;)

Salu2

Controlar el tamaño de subida de los ficheros al servidor en ASP.NET

Esta pregunta es muy frecuente en las NewsGroup de ASP.NET. La solución es sencilla, basta con añadir la siguiente instrucción a nuestro Web.Config:

   1:  <configuration>
   2:     <system.web>
   3:         <httpRuntime maxRequestLength="Tamaño en kilobytes" />
   4:     </system.web>
   5:  </configuration>

 Por defecto el tamaño de subida está estipulado en 4 MB(4096 KB).

Un aclaración que me gustaría hacer, es que hay gente que quiere permitir la subida de archivos demasiado grandes al servidor y pone como valor del atributo maxRequestLength muchos MB y esto puede ser un problema de seguridad, porque si un atacante aprovecha una vulnerabilidad de nuestro sitio Web, puede hacer un ataque de denegación de servicio (denial of service) subiendo archivos de un tamaño excesivo al servidor, además en la MSDN encontramos esto:

This limit can be used to prevent denial of service attacks caused by users posting large files to the server

Es decir que este atributo lo podemos usar para prevenir este tipo de ataques ;)

Cuando queramos subir archivos grandes a un servidor es mejor usar un FTP.

Salu2

Publicado por Luis Ruiz Pavón | 4 comment(s)
Archivado en: ,,,

ASP.NET 2.0 CreateUserWizard(II): Enviar un correo personalizado cuando un usuario se crea una nueva cuenta en nuestro sitio web

En mi otro artículo hablaba de como enviar un correo a un usuario que se crea una nueva cuenta en nuestro sitio web, pero, ¿Y si además necesitamos personalizar ese correo?, pues no problem, capturando un simple evento del control CreateUserWizard llamado SendingMail y conociendo un poquito la clase MailMessage esta chupao. Y dirás:

¿Porqué la clase MailMessage?

Pues la respuesta es que el segundo argumento que recibe este evento es del tipo MailMessageEventArgs, que contiene una propiedad del tipo MailMessage que es el mensaje de correo que se va a enviar, el cual podemos modificar a nuestro antojo.

MailMessage es nueva en NET 2.0:

http://msdn2.microsoft.com/es-es/library/system.net.mail.mailmessage(VS.80).aspx

Por ejemplo, imagina uno de esos correos que te llegan diciendote:

"Bienvenido Fulanito... Tu usuario es.... y tu contraseña..."

Manos a la obra:

   1:  protected void CreateUserWizard1_SendingMail(object sender, MailMessageEventArgs e)
   2:  {
   3:      //Recuperamos la instancia del control CreateUserWizard
   4:      CreateUserWizard wizard = (CreateUserWizard)sender;
   5:   
   6:      //Creamos el texto del correo
   7:      StringBuilder mensaje = new StringBuilder();
   8:      mensaje.Append(String.Format("Bienvenido {0}:\r\n\r\n", wizard.UserName));
   9:      mensaje.Append("Para acceder a nuestra zona exclusiva para socios
  10:   http://misitio.com/members/\r\n\r\n");
  11:      mensaje.Append(String.Format("Código de Usuario: {0}\r\n", wizard.UserName));
  12:      mensaje.Append(String.Format("Contraseña:        {0}", wizard.Password));
  13:   
  14:      //Modificamos el cuerpo y el asunto
  15:      e.Message.Body = mensaje.ToString();
  16:      e.Message.Subject = "Acceso a nuestra zona exclusiva";
  17:  }

Fácil no???

Nota: Por motivos de seguridad no es recomendable enviar la password por correo electrónico, pero esto es sólo un ejemplo.

Salu2

ASP.NET 2.0 CreateUserWizard: Enviar un correo cuando un usuario se crea una nueva cuenta en nuestro sitio web

Un título demasiado largo para lo poco que se puede contar, pero eso sí, puede evitar a más de uno un quebradero de cabeza.

Cuando necesitamos que en nuestro sitio web, una vez que el usuario se ha creado una nueva cuenta se le envie un correo de esos de bienvenida y tal, necesitamos seguir estos pasos:

  1. Añadir una entrada válida de smtp a nuestro Web.Config:

       1:  <system.net>
       2:      <mailSettings>
       3:          <smtp>
       4:              <network host="miserver" password="" userName=""/>
       5:          </smtp>
       6:      </mailSettings>
       7:  </system.net>

  2. Configurar la propiedad CreateUserWizard.MailDefinition.From en la ventana de Propiedades o en el evento Page_Load, por ejemplo:

       1:  protected void Page_Load(object sender, EventArgs e)
       2:  {
       3:      CreateUserWizard1.MailDefinition.From = "Administrador@misitio.com";
       4:  }
Nota: Es obligatorio definir esta propiedad como he comentado en el punto 2, no sirve el atributo from de smtp:

   1:  <system.net>
   2:      <mailSettings>
   3:          <smtp from="Administrador@misitio.com"> NO FUNCIONA
   4:              <network host="" password="" userName=""/>
   5:          </smtp>
   6:      </mailSettings>
   7:  </system.net>

Aunque la etiqueta anterior si que es válida para el control PasswordRecovery, de hecho sino esta definida esa etiqueta y no definimos la propiedad CreateUserWizard.MailDefinition.From en la ventana de Propiedades o en el evento Page_Load, nos encontraremos con esta excepcion:

Se debe especificar una dirección de correo electrónico en la propiedad From o en la sección system.net/mailSettings/smtp config.

Descripción: Excepción no controlada al ejecutar la solicitud Web actual. Revise el seguimiento de la pila para obtener más información acerca del error y dónde se originó en el código.

Detalles de la excepción: System.Web.HttpException: Se debe especificar una dirección de correo electrónico en la propiedad From o en la sección system.net/mailSettings/smtp config.

Cosa que no ocurre con el control CreateUserWizard

Salu2

Crear una columna calculada en un DataTable

A veces necesitamos crear una columna calculada en base a otras que ya disponemos como por ejemplo un total, un %... Para ello sólo debemos agregar una nueva columna a nuestro DataTable, especificarle el Nombre y el Tipo de dato y asignar a la propiedad Expression del objeto DataColumn la fórmula que queremos calcular.

Por ejemplo, vamos a crear una columna llamada Total sobre un DataTable que contendrá la información de la tabla [Order Details] de la base de datos NorthWind, en la que vamos a calcular el Total de cada Línea de Detalle:

   1:  using (SqlConnection con = new SqlConnection(
   2:  @"server=WM00088\SQLEXPRESS;integrated security=true;database=Northwind"))
   3:  {
   4:      con.Open();
   5:      SqlCommand comando = new SqlCommand();
   6:      comando.CommandText = "SELECT * FROM [Order Details]";
   7:      comando.Connection = con;
   8:      DataTable dt = new DataTable();
   9:      dt.Load(comando.ExecuteReader());
  10:      DataColumn dc = new DataColumn("Total", typeof(decimal));
  11:      dc.Expression = "UnitPrice * Quantity";
  12:      dt.Columns.Add(dc);
  13:  }

Fácil no???

Salu2

Publicado por Luis Ruiz Pavón | 5 comment(s)
Archivado en:

Sobre el evento de ayer: Kill the Experts...with AJAX!

Ayer en las oficinas de Microsoft Ibérica tuvo lugar el evento del Grupo de Usuarios de Madrid Kill The Experts... with AJAX! y la verdad es que me quedé bastante satisfecho con el mismo (como en todos a los que puedo asisitir).

La cosa empezó como el capítulo de House en el que monta la pizarrita para ver quien gana, si el o Dios, en este caso no se contó con House pero si con 2 peasos de crases Miguel Jimenez y David Salgado y Dios que no era un dios normal, era %Dios% y al final acabó palmando, lógico no??

El evento consitía basicamente en coser a preguntas a los expertos con inquietudes sobre AJAX y estas son algunas de las preguntas que se hicieron:

  1. Llamadas entre dominios.
  2. Soporte en nuevas versiones de AJAX Control Toolkit para ell botón Atras del navegador
  3. Llamadas a servicios web con Autenticación de Windows Integrada (Sobre esto voy a hacer unas pruebas con una solución que comentó David y publicaré un pequeño artículo con los resultados)
  4. Tratamiento de excepciones en la parte cliente
  5. Bugs (Validadores y otros 2 (Uno que no es y otro que el coordinador del grupo de usuarios de Mallorca que pasará a Miguel y a David y seguro que publicarán algo al respecto)
  6. Compatibilidad de AJAX con SEO (Search Engine Optimization)
  7. Accesibilidad y Estandares
  8. Futures
  9. Extensores

y muchas más...

Dejo algunos enlaces donde encontre información referente a las llamadas entre dominios que me pareció bastante interesante:

Calling Cross Domain Web Services in AJAX

Brad Neuberg Coding In Paradise AJAX Tutorial How to Invoke Web Services From a Web Page On A Different Host

Y por último dar las gracias a Miguel Jimenez, David Salgado y toda la gente que no conozco por el esfuerzo y dedicación para hacer este tipo de cosas ;)

Salu2

Comprobar que todos los campos de un FormView están informados.

Con la llegada de los Validadores de ASP.NET, los desarrolladores nos confiamos y dejamos de lado la validación de los datos en el servidor y esto no es una buena practica, puesto que en un formulario donde todos los datos son obligatorios, puede ser que por algún motivo vengan vacíos y nos den de vez en cuando algún disgusto, aunque es verdad que una doble validación cliente-servidor implica mas tiempo de proceso y por consiguiente menos rendimiento, pero aumenta la seguridad tan importante hoy en día.

En el caso del FormView, podemos validar de una forma fácil y sencilla si todos los campos están informados.

Para realizar esta comprobación disponemos en su evento ItemUpdating e ItemInserting de una clase FormViewInsertEventArgs que nos devuelve una colección con los valores del Form, que podemos recorrer y comprobar como os muestro en el ejemplo:

   1:  protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
   2:  {
   3:      foreach (DictionaryEntry entry in e.NewValues)
   4:      {
   5:          if (entry.Value.ToString() == String.Empty)
   6:          {
   7:              this.ClientScript.RegisterStartupScript(this.GetType(), "Alert", 
   8:  "<script>alert('Todos los campos son obligatorios')</script>");
   9:              e.Cancel = true;
  10:              break;
  11:          }
  12:      }
  13:  }
  14:   
  15:  protected void FormView1_ItemInserting(object sender, FormViewInsertEventArgs e)
  16:  {
  17:      foreach (DictionaryEntry entry in e.Values)
  18:      {
  19:          if (entry.Value.ToString() == String.Empty)
  20:          {
  21:              this.ClientScript.RegisterStartupScript(this.GetType(), "Alert", 
  22:  "<script>alert('Todos los campos son obligatorios')</script>");
  23:              e.Cancel = true;
  24:              break;
  25:          }
  26:      }
  27:  }

 Salu2 y espero que os sirva.

Publicado por Luis Ruiz Pavón | 2 comment(s)
Archivado en: ,,

"Para hacer el Windows Vista contratamos a Antropólogos"

Pues sí señores no es broma, son algunas de las declaraciones de la Presidenta de Microsoft Ibérica, Rosa María García en la entrevista que concedíó al diário ADN y para los que no habéis leido la entrevista os dejo el enlace, página 15:

http://www.diarioadn.com/media/0000028500/0000028543.pdf

Salu2

Publicado por Luis Ruiz Pavón | 3 comment(s)
Archivado en: ,,

HotFix disponible para solucionar el problema de los Validadores de ASP.NET con UpdatePanel

Hace unos días Sergio hacía en su blog referencia a este problema que ocurre cuando utilizamos validadores en ASP.NET dentro de un UpdatePanel, bueno pues ya hay disponible un HotFix para solucionarlo ya que antes se proponía un parche temporal:

http://weblogs.asp.net/scottgu/archive/2007/01/25/links-to-asp-net-ajax-1-0-resources-and-answers-to-some-common-questions.aspx

El enlace para descarga:

https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=6106&wa=wsignin1.0

Salu2

Publicado por Luis Ruiz Pavón | con no comments

Crear un sitio web multiidioma (II)

En mi anterior artículo estabamos hablando sobre los tipos de recursos existentes y ya vimos los recursos locales. En esta ocasión vamos a ver los recursos globales:

Recursos Globales:

Pueden ser accedidos desde cualquier página o vía código de nuestro sitio web. Deberíamos echar mano de esta clase de recursos cuando tenemos varias páginas que necesitan acceder a un mismo recurso.

Los ficheros de recursos globales se almacenan en la carpeta App_GlobalResources y tienen la misma nomenclatura que los ficheros de recursos locales.

A continuación se detalla como crear un recurso global desde Visual Studio 2005:

  1. Botón derecho sobre el Proyecto Web -> Add ASP.NET Folder -> App_GlobalResources


  2. Botón derecho sobre la carpeta App_GlobalResources -> Add New Item... seleccionamos Resource File y le ponemos un nombre (Test.resx):


  3. Añadir los valores necesarios:


  4. Y para crear archivos de recursos globales para otros idiomas o culturas, copiar el que hemos creado, pegar y cambiar la extensión.

Una vez creados nuestros archivos de recursos globales, podemos asociar los valores del archivo con las propiedades de los controles que queramos. En este caso vamos a asociar a la propiedad Text de un Label para que muestre el mensaje que creamos anteriormente:

  1. En las propiedades del Label seleccionamos la propiedad Expressions:


  2. A continuación nos aparece una ventana flotante con las propiedades del control. Seleccionamos la propiedad Text, en Expression Type seleccionamos Resources y nos quedan 2 valores que indicar:

    • ClassKey: Si se trata de un archivo de recursos globales ponemos el nombre (En nuestro caso Test)
    • ResourceKey: Seleccionamos el recurso que corresponda:


  3. Aceptamos el cuadro y automáticamente VS nos muestra el valor del ResourceKey seleccionado:


  4. Y en la vista de código HTML:

También podemos acceder a los recursos globales vía código:

   1:  protected void Page_Load(object sender, EventArgs e)
   2:  {
   3:      Label2.Text = Resources.Test.Mensaje001;
   4:  }

Y sino disponemos de los recursos en tiempo de diseño, podemos utilizar los métodos GetLocalResourceObject o GetGlobalResourceObject:

   1:  protected void Page_Load(object sender, EventArgs e)
   2:  {
   3:      Label2.Text = (string)GetGlobalResourceObject("Test", "Mensaje001");
   4:  }

Ah! por cierto en el artículo anterior en unos de los comentarios me decían esto:

Te ha faltado explicar como hacer para que se detecte el idioma a través del  que está configurado en el navegador ;)

Si queremos probarlo con diferentes idiomas (Por ejemplo el Inglés que era el otro archivo de recursos que habíamos creado), en Internet Explorer, en el menú Herramientas -> Opciones de Internet:

Pulsamos sobre el botón Idiomas...

Pulsamos sobre el botón Agregar...

Buscamos Inglés (Reino Unido) y Aceptar

Por último seleccionamos de nuevo Inglés (Reino Unido) y Subir para configurar como lenguaje del navegador.

Una vez hecho esto visualizamos la aplicación y se muestra en Inglés.

Bueno pues espero que os sea útil. Salu2

Crear un sitio web multiidioma (I)

En algunas ocasiones necesitamos que nuestras aplicaciones soporten varios idiomas y al principio nos puede parecer un trabajo tedioso y complicado, pero con ASP.NET es un trabajo sencillo y rápido.

Para ello ASP.NET utiliza archivos de recursos (resx), que no son más que ficheros XML que contienen los textos en diferentes idiomas para los controles web.

Existe 2 tipos de recuros: Locales y Globales

Recursos Locales:

Son específicos para una página web en concreto y deben ser usados para suministrar versiones de la página en diferentes idiomas.

Estos ficheros se almacenan en la carpeta App_LocalResources de nuestro sitio web. Su nomenclatura es la siguiente:

<Nombre de la página>[.lenguaje].resx

Así por ejemplo para un recurso español tendríamos:

Default.aspx.es.resx

A continuación se detalla como crear un recurso local de una página web desde Visual Studio 2005:

  1. En vista de diseño nos situamos sobre la página o sobre un control:


  2. Pinchamos sobre el menú Herramientas -> Generar recurso local


  3. Y automáticamente VS nos crea (Si no estaba creada) la carpeta App_LocalResources y su correspondiente recurso:


  4. Y si nos vamos a la vista HTML de la página sobre la que hemos asignado el recurso, nos encontramos con que VS ha creado unas etiquetas especiales para indicar que esos controles están enlazados a una página de recursos:


Si añades nuevos controles a la página debes volver a generar el archivo de recursos para que se actualice con los nuevos controles por lo que generar los archivos de recursos debería ser una de las últimas fases en el desarrollo de la aplicación.

Para crear archivos de recursos de otros idiomas o culturas basta con copiar el por defecto y pegarlo sobre la misma carpeta, se cambia la extensión y se modifican los textos.

A continuación vamos a ver como aplicar esto con un ejemplo:

  1. Crear un sitio Web ASP.NET

  2. Añadir una Label y 2 Hyperlink a la página:


  3. Creamos el archivo de recursos como vimos anteriormente.
  4. Añadimos los textos:


  5. Copiamos el archivo de recursos y lo renombramos a Default.aspx.en.resx (Inglés):


  6. Añadimos los textos:


  7. Para cada Hyperlink modificamos su propiedad NavigateUrl:


  8. Y  sólo nos falta sobreescribir el evento InitializeCulture para cambiar el idioma de nuestro sitio en función del enlace:

       1:  using System;
       2:  using System.Data;
       3:  using System.Configuration;
       4:  using System.Web;
       5:  using System.Web.Security;
       6:  using System.Web.UI;
       7:  using System.Web.UI.WebControls;
       8:  using System.Web.UI.WebControls.WebParts;
       9:  using System.Web.UI.HtmlControls;
      10:  using System.Globalization;
      11:   
      12:  public partial class _Default : System.Web.UI.Page 
      13:  {
      14:      protected void Page_Load(object sender, EventArgs e)
      15:      {
      16:   
      17:      }
      18:   
      19:      protected override void InitializeCulture()
      20:      {
      21:          if (Request.QueryString["lang"] != null)
      22:          {
      23:              UICulture = Request.QueryString["lang"];
      24:          }
      25:          base.InitializeCulture();
      26:      }
      27:  }

  9. Y por último sólo falta probar (Os adjunto el código fuente):

En la siguiente entrega hablaremos sobre los recursos globales.

Salu2

ASP.NET: Error -> Acceso denegado: *.dll

Seguro que a más de uno y al que no suerte tiene, le ha aparecido este error cuando acaba de realizar una modificación en una aplicación Web y la sube a producción y alguien realiza la primera petición:

Server Error in '/MyWebApp' Application
Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Access is denied: 'mydll'.
Source Error:

Este error se puede producir porque en el servidor de pruebas/producción esté corriendo el servicio de Index Server (Cisvc.exe) y este vuelva a analizar el directorio de Archivos temporales de ASP.NET. El servicio de Index Server establece un bloqueo sobre esta carpeta de 1 a 5 minutos de duración dependiendo del tamaño de dicho directorio, y cuando alguien realiza la petición a nuestra aplicación el proceso Aspnet_wp.exe ó W3wp.exe no puede cargar la DLL y se muestra el susodicho error.

PRB: Access Denied Error When You Make Code Modifications with Index Services Running

Salu2

Publicado por Luis Ruiz Pavón | 5 comment(s)
Archivado en: ,,