29 de diciembre de 2009

ASP.NET 4.0 Web Form ClientIDMode

Visual Studio 2010 Son muchas las novedades que se incluyen y que vamos descubriendo de a poco en la nueva versión de ASP.NET 4.0.
 
 
Hoy aprovecho para comentarles rápidamente una de ellas, me refiero a la propiedad:

ClientIDMode

Esta propiedad indica cómo se generara la propiedad ClientID de los controles.

Pero pongámonos en contexto, hasta ahora (antes de ASP.NET 4.0), cuando queríamos referirnos a un control desde el cliente (java script) lo hacíamos de la siguiente forma (Supongamos que queremos seleccionar el botón btnAceptar):

var btn = document.getElementById("btnAceptar");

Pero que sucedía si este botón estaba dentro de un control contenedor (Control de Usuario, Dentro de un ContentPlaceHolderID, etc..)

Sucede que ASP.NET al generar la página, autogenera estos ID, por ejemplo:

ctl00$ContentPlaceHolder2$btnAceptar

Y para poder acceder a ellos comúnmente hacíamos esto:

var btn = document.getElementById("<%=btnAceptar.ClientID %> ");

Con ASP.NET 4.0 tenemos otra manera de resolver este problema, y es el usar la propiedad ClientIDMode de la clase Web.UI.Control.

Si establecemos esta propiedad a:

ClientIDMode="Static"

Conseguiremos que al regenerar la pagina se mantenga el mismo ClientID y podríamos hacer lo siguiente:

var btn = document.getElementById("btnAceptar");

Veamos un ejemplo y después comentaremos sobre los posibles valores de la propiedad:

Código de la pagina (ASPX):

ASP.NET 4.0 ClientIDMode 

Código de la pagina generado (HTML):

ASP.NET 4.0 ClientIDMode Client

Expliquemos los distintos valores que pueden asignarse a esta propiedad y los resultados que se obtendrán:

Web.UI.Control.ClientIDMode

VALOR DESCRIPCION
Legacy El valor de ClientID es generado por la concatenación de los ID de cada uno de los padres con los nombres de contenedores del control.
Este algoritmo es el que se utiliza en las versiones de ASP.NET antes de ASP.NET 4.0.
Static El valor de ClientID se establece en el valor de la propiedad ID.
Predictable Este algoritmo se utiliza para los controles que se encuentran en controles enlazados a datos. El valor de ClientID se genera mediante la concatenación del valor ClientID  del padre. Si el control esta enlazado a datos y genera varias filas, el valor del campo de datos especificado en la propiedad ClientIDRowSuffix se añade al final. Si la propiedad ClientIDRowSuffix está en blanco, un número secuencial se añade al final en lugar de un valor de campo de datos. Cada segmento está separado por un carácter de subrayado (_).
Inherit El control usará (hereda) el mismo algoritmo que el padre.

 

Resumen (ClientIDMode):

Con ASP.Net 4.0 y la nueva propiedad ClientIdMode podemos especificar con precisión  como deben generarse los ClientID de nuestros objetos (Legacy, Static, Predictable, Inherit).

La propiedad ClientIdMode puede ser definida en:

  • En el control:

   <asp:Button ID="btnOk" ClientIDMode="Static"

  • Para todos los controles de una página:

   <%@ Page ClientIDMode="Static"

  • Para todas las páginas de una aplicación (web.config):

   <system.web>

     <pages clientIDMode="Static"></pages>

   </system.web>

Artículos Relacionados:

SQL 2008, Nuevos Tipos de Datos

 SQLServer2008_thumb

Nuevos Tipos de Datos

  • Fecha y Hora
  • Espaciales o Geográficos
  • Estructuras Jerárquicas
  • FileStrem

Fecha y Hora

SQL Server 2008 introduce cuatro nuevos tipos de datos de fecha y hora. Estos tipos permiten a las aplicaciones tener tipos independientes para la fecha y la hora, un mayor intervalo de años, mayor precisión en las fracciones de segundo, y compatibilidad para desplazamiento de zona horaria.

A continuación hago una comparativa de los 6 tipos de datos de fecha y hora, detallando el formato, el rango y el tamaño que ocupa cada uno de ellos:

TIPO DE DATOS CARACTERISTICAS
Time

hh:mm:ss[.nnnnnnn], 00:00:00.0000000 a 23:59:59.9999999, 3 a 5 bytes

Date

AAAA-MM-DD, 0001-01-01 a 9999-12-31, 3 bytes

Smalldatetime

AAAA-MM-DD hh:mm:ss, 1900-01-01 a 2079-06-06, 4 bytes

Datetime

AAAA-MM-DD hh:mm:ss[.nnn],  1753-01-01 a 9999-12-31, 8 bytes

datetime2(7)

AAAA-MM-DD hh:mm:ss[.nnnnnnn] De 0001-01-01 00:00:00.0000000 a 9999-12-31 23:59:59.9999999, 6-8 bytes

datetimeoffset(7)

AAAA-MM-DD hh:mm:ss[.nnnnnnn] [+|-]hh:mm, De 0001-01-01 00:00:00.0000000 a 9999-12-31 23:59:59.9999999 (en UTC), 8-10 bytes

 

Espaciales o Geográficos

Hay dos tipos de datos espaciales:

  1. Geometry: Admite datos planos o euclidianos (de tierra plana).
  2. Geography: Almacena datos elípticos (tierra redonda), como coordenadas de latitud y longitud GPS.

Solo 7 de los 11 tipos de datos Geometry y Geography admiten crear instancias; puede crear y trabajar con estas instancias (o crear instancias de las mismas) en una base de datos.

La figura siguiente describe la jerarquía de Geometry en la que se basan los tipos de datos Geography y Geometry. Los tipos a partir de los que pueden crearse instancias de Geometry y Geography se indican en azul.

SQLDatosEspaciales_thumb1 

Estructuras Jerárquicas

Los datos jerárquicos se definen como un conjunto de elementos de datos que se relacionan entre sí mediante relaciones jerárquicas. Las relaciones jerárquicas son aquellas en las que un elemento de los datos es el elemento primario de otro elemento. Los datos jerárquicos son comunes en las bases de datos. Entre otros, se incluyen los siguientes ejemplos:

  • Una estructura organizativa
  • Un sistema de archivos
  • Un conjunto de tareas de un proyecto
  • Un gráfico de vínculos entre páginas web

 

FileStream

Muchos de los datos que se crean todos los días son datos no estructurados, como documentos de texto, imágenes y vídeos. Estos datos no estructurados se almacenan fuera de la base de datos a menudo. Esta separación puede producir complejidades en la administración de datos. O bien, si los datos están asociados a almacenamiento estructurado, se pueden limitar las capacidades de transmisión por secuencias de archivo y rendimiento.

FILESTREAM integra SQL Server con un sistema de archivos NTFS almacenando los datos de objeto binario grande (BLOB) varbinary(max) como archivos en el sistema de archivos. Las instrucciones de Transact-SQL pueden insertar, actualizar, consultar, buscar y realizar copias de seguridad de los datos FILESTREAM.

El tamaño y el uso de los datos determinan si debería usar el almacenamiento de base de datos o el almacenamiento del sistema de archivos. Si las condiciones siguientes son verdaderas, debería pensar en usar FILESTREAM:

  • Los objetos que se están almacenando son, por término medio, mayores de 1 MB.
  • El acceso de lectura rápido es importante.
  • Está desarrollando aplicaciones que usan un nivel intermedio para la lógica de la aplicación.

 

Hasta aquí el comentario sobre los nuevos tipos de datos, como hemos visto solo hemos hablado a grandes rasgos de estos, pero bien merecería la pena hacer un articulo independiente para cada uno de ellos donde además de verlos en profundidad, podamos ver ejemplos de los mismos, en fin, es algo de lo que a lo mejor escriba en próximas semanas…

 

Artículos Relacionados:

SQL Server 2008, Novedades

SQLServer 2008

Novedades Principales de SQL Server 2008

La nueva versión del motor de base de datos de Microsoft, SQL Server 2008, viene con una serie de importantes mejoras, aprovecho este espacio para citar algunas que a mi juicio resultan muy interesantes:

  • Nuevos Tipos de Datos
  • Mejoras de código Transact SQL (T-SQL)
  • Tabla como parámetros
  • Columnas dispersas
  • Índices filtrados
  • Reporting Services ( SSRS )
  • ADO.Net Entity Framework
  • ADO.Net Synchronization Services
  • Énfasis en la Seguridad

Estas son las principales áreas donde se han introducido cambios significativos desde mi punto de vista, e iré comentando algunas de estas características en próximos artículos. Por lo pronto hoy comienzo hablando de los Nuevos Tipos de Datos (leer más …)

Bajar varios Javascript más rápidamente

.NET 3.5 SP1 introduce el nuevo elemento CompositeScript del control ScriptManager, que nos permite definir múltiples referencias de scripts. Todas las referencias del elemento CompositeScript se combinan en el servidor y son servidas como un script simple al cliente, reduciendo el número de peticiones al servidor y mejorando el tiempo de carga de las aplicaciones ASP.NET.

Cuando el navegador Web comienza a servir una página, nunca realiza más de 4 peticiones simultaneas, por esta razón, cuantas más peticiones, más lento es el proceso de carga de una página. De aquí se desprende que en ocasiones es preferible tener menos peticiones y archivos más grandes.

Pero bien, veamos como hacerlo:

<html>
<head>
    <title>Scripts Combinados</title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <CompositeScript>
      <Scripts>
        <asp:ScriptReference Path="~/Scripts/Script1.js" />
        <asp:ScriptReference Path="~/Scripts/Script2.js" />
        <asp:ScriptReference Path="~/Scripts/Script3.js" />
      </Scripts>
    </CompositeScript>
    </asp:ScriptManager>
 
  </form>
</body>
</html>

Espero te sea útil…

16 de diciembre de 2009

Error: Could not load 'Microsoft.Web.Extensions'

Recientemente, un cliente a quien le había echo un sitio Web ASP.Net, decidió cambiar el sitio de servidor, por motivos que no vienen a caso ahora. En fin, que al realizar el cambio hacia el nuevo servidor, le comenzó aparecer el siguiente error:

“Could not load file or assembly 'Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.”

El sitio lo había realizado usando:

  • ASP.NET 2.0
  • ASP.Net 2.0 AJAX Extensions

La causa y la solución son bastante simples.

Causa:

En el nuevo servidor no estaba instalado el ASP.Net 2.0 AJAX Extensions, que no son mas que un conjunto de extensiones que nos permiten utilizar la tecnología AJAX en los proyectos de ASP .Net 2.0.

Solución:

La solución no es otra que instalarnos el paquete de ASP.Net 2.0 AJAX Extensions, si quieres ver como hacerlo pincha aquí.

10 de diciembre de 2009

Concatenación de String (String vs StringBuilder)

Recientemente tuve que analizar el código de una página Web que presentaba un comportamiento bastante ineficiente.

Para focalizar el problema utilicé una excelente herramienta que no viene al caso ahora. En fin que después de detectado y analizado el método donde se producía el cuello de botella, descubrimos que la ineficiencia se debía a la actualización de una variable de tipo string dentro de un ciclo medianamente grande, para que me entiendan, el código despejándolo un poco era algo así:

public string ConcatenacionIneficiente()
{
  //Ejemplo de código ineficiente
  string strResult = string.Empty;
 
  for (int i = 0; i < 50000; i++)
  {
    //…
    strResult += i;
    //…
  }
 
  return strResult;
}

Al detectar semejante mala práctica, modificamos el código dejándolo de la siguiente manera:

public string Concatenacion()
{
    //Ejemplo de código eficiente
    StringBuilder sbResult = new StringBuilder();
 
    for (int i = 0; i < 50000; i++)
    {
        //…
        sbResult.Append(i.ToString());
        //…
    }
 
    return sbResult.ToString();
}

Como verán la diferencia entre un código y el otro es que remplazamos el uso de una variable string por otra de tipo StringBuilder. Y el resultado es el mismo pero con una notable mejora de eficiencia.

Explicación:

Las cadenas de .Net Framework son invariables (o sea, el texto al que se hace referencia es de sólo lectura después de la asignación inicial). Esto provoca que internamente, para concatenar un string, lo que se hace es crear una nueva instancia de string, copiar el string actual en esa nueva instancia y borrar la instancia original.

Conclusión:

La concatenación de strings es extremadamente ineficiente. Siempre que se pueda, aunque sea para las operaciones más simples, utilizaremos el StringBuilder frente a la concatenación de strings... y si es para operaciones más costosas ni lo pensaremos!!!!

9 de diciembre de 2009

JavaScript IntelliSense en Controles de Usuario (.ascx)

Vamos a describir un pequeño truco que puedes utilizar cuando quieres tener JavaScript IntelliSense en un control de usuario (.ascx).

A menudo, al trabajar con controles de usuario, no se desea incluir bibliotecas JavaScript dentro del control, mas bien las colocamos en las páginas que contienen a estos controles. El problema, por supuesto, es que al hacerlo Visual Studio no tiene manera de saber que el control en el que trabajamos si tiene acceso a la biblioteca a través de la página donde esta contenido, y por ende no se proporciona IntelliSense JavaScript.

Nota: Problemática similar se nos presenta con hojas de estilos CSS que no tenemos referenciadas en el control de usuario y si en la página contenedora.

Una forma con la que podemos habilitarlo es mediante la adición del siguiente código al control de usuario, pero rodeándolo con un bloque del lado del servidor, el cual siempre se evalúa a falso en tiempo de ejecución:

<% if (false) { %>
  <script src="../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<% } %>
O el siguiente código para la hoja de estilo CSS:
<% if (false) { %>
  <link href="../Estilos/Base.css" rel="stylesheet" type="text/css"/>
<% } %>

En tiempo de ejecución

ASP.NET nunca procesa esta secuencia (ya que se envuelve en un bloque que siempre es falso).

8 de diciembre de 2009

Error 'CompositeScript' en 'System.Web.UI.ScriptManager'

Hoy aprovecho para comentar algo que me ocurrió y que expongo aquí por si alguien tropieza con la misma piedra, que al menos tenga algo donde buscar.

El echo es que en días pasados al publicar uno de los Sitios Web ASP.Net en el servidor de producción, resulta que al intentar abrir una de las páginas publicadas me salió el siguiente error:

El tipo 'System.Web.UI.ScriptManager' no tiene ninguna propiedad pública cuyo nombre sea 'CompositeScript'.

Pues bien la causa del error es que estaba usando la propiedad ScriptManager.CompositeScript para bajar script compuestos o combinados.


Solución:


Para solucionarlo bastó con descargarme e instalar en el servidor de producción el Microsoft .NET Framework 3.5 Service Pack 1. Después de instalado el SP todo funcionó a la perfección.

Salu2 y mucha suerte,
Derbis

7 de diciembre de 2009

Leer clave desde el web.config

Mi consejo para leer claves del web.config  en ASP.NET es que usemos el siguiente método.

AppSettingsReader webConfigReader = new AppSettingsReader();
string strMailTo = (string)webConfigReader.GetValue("correo_OnerrorPage", typeof(string));

La principal ventaja de usar este método es que cuando la clave del web.config no existe, el error que nos muestra Visual Studio es muy claro, en lugar de un “referencia de objeto no establecida”.

6 de diciembre de 2009

Error HTTP 500.19 - Internal Server Error

Recientemente instalé Windows 7 en mi ordenador, y al hospedar en Internet Information Services 7.5 (localhost) las aplicaciones Web que estoy desarrollando, al intentar examinarlas me topé con el siguiente error:

Error HTTP 500.19 - Internal Server Error

No se puede obtener acceso a la página solicitada porque los datos de configuración relacionados de la página no son válidos.

Error Http 500.19

Solución al Error 500.19

El propio IIS te hace algunas sugerencias, las cuales no me ayudaron en lo mas mínimo, en fin que la solución encontrada fue la siguiente:

  1. Abrir el Panel de Control, Programas, Activar o desactivar las características de Windows.
  2. Aparecerá una ventana con todas las características de Windows; deberemos buscar  la casilla Internet Information Services, y verificar que las siguientes opciones estén seleccionadas:

Error Http 500.19, Caracteristicas IIS 

Las características resaltadas en amarillo son las que debemos tener marcadas, pero algunas de ellas ya vienen activadas por defecto; por lo general solo tendremos que marcar las que tenemos resaltadas en rojo.

Después de seleccionadas presionamos el botón aceptar y todo listo.

Suerte con IIS 7

Error instalando Visual Studio

Hace unos días mientras intentaba instalar Visual Studio 2008, me encontré con el siguiente error que me imposibilitó continuar con la instalación.

Respuesta: Error en instalación de visual.net

Error mostrado en el Log:
[07/04/09,23:46:54] setup.exe: [2] ISetupComponent::Pre/Post/Install() failed in ISetupManager::InternalInstallManager() with HRESULT -2147023293

Después de investigar un poco y varios intentos fallidos, pude dar con la solución que detallo a continuación:

  1. Desactivar en Windows Vista el (UAC) Turn on User Account Control.
  2. Si tienes instalado Office 2007, ir a Inicio - Run y coloca la siguiente línea de comando "msiexec /x {30120000-0044-0C0A-0000-0000000FF1CE}" esto te pedirá desinstalar una aplicación, a lo que debes responder que si!!!!
  3. Después de esto ya puedes instalar correctamente VS2008.
Mucha suerte con la instalación.

Nota sobre el Problema: Básicamente el tema se debió a una falta de comunicación entre el equipo de desarrollo de Visual Studio y el equipo de desarrollo de Microsoft Office 2007. Resulta que los muchachos de Microsoft, especialmente la gente de Office 2007, incluyen en ese producto, un sub producto llamado Microsoft InfoPath que es el causante del error en la instalación de Visual Studio. La solución es simple. Hay que desinstalar InfoPath y volver a instalar Visual Studio.

2 de diciembre de 2009

C# Nuevas Características

Veamos las nuevas características que se han incorporado en cada una de las entregas de este potente lenguaje de programación, comenzando por C# 2.0, C# 3.0 hasta C# 4.0

C# Evolucion, .Net, VS

C# es un lenguaje de programación que ha ido mejorando con el paso del tiempo, agregando nuevas e interesantes características en cada una de las versiones que han ido saliendo progresivamente con cada nueva entrega de Visual Studio, veamos entonces dichas mejoras:

 

C# 4.0, Lo Nuevo

Con la próxima llegada de Visual Studio 2010, sale la versión C# 4.0, incorporando las siguientes nuevas características:

  1. Parámetros Opcionales.
  2. Tipos Dinámicos (dynamic type).
  3. Covarianza y Contravarianza (Covariance and Contravariance).
Nota:
Existen otras muchas nuevas características incorporadas en esta nueva versión (C# 4.0) que iré incorporando a medida que las valla manipulando y comprendiendo ... sean pacientes, jejejeje

 

C# 3.0, Lo Nuevo

Con la llegada de Visual Studio 2008, sale la versión C# 3.0, incorporando las siguientes nuevas características:

  1. LINQ
  2. Expresiones Lambda (Lambda Expressions).
  3. Tipos Anónimos (Anonymous Types).
  4. Inicializadores de Objetos y Colecciones (Object and Collection Intializers).
  5. Métodos Extensores (Extension Methods).
  6. Expression Trees.
  7. Partial Methods.
  8. Propiedades Auto-Implementadas (Auto-Implemented Properties).

 

C# 2.0, Lo nuevo

Con la llegada de Visual Studio 2005, sale la versión C# 2.0, incorporando las siguientes nuevas características:

  1. Generics.
  2. Métodos Anónimos (Anonymous Methods).
  3. Iterators.
  4. Partial Types.
  5. Nullable Types.
  6. Delegados (Delegate Inference).
  7. Friend  Assemblies.
  8. Pragma warning.
  9. Captured Variables.

 

Artículos Relacionados:

Métodos Extensores

¿Que son los métodos extensores? ¿Como y donde usarlos? ¿Donde ver un ejemplo práctico? Si quieres aclarar estas preguntas, estas en el artículo indicado. Explicaremos mediante un ejemplo simples y práctico todo lo relacionado con los métodos extensores (Extension Methods).

Son varias las mejores que se incluyeron en C# 3.0, y seguramente la mayor es la inclusión de LINQ pero no vamos a hablar en este momento de LINQ, si no de los métodos extensores (Extension Methods).

¿Que son los Métodos Extensores?

Los métodos extensores, nos permiten “extender” o agregar funcionalidad a una clase ya existente sin necesidad de usar la herencia o polimorfismo.

Pero como de costumbre expliquémoslo mediante un ejemplo.

¿Ejemplo de Método Extensor?

En en ejemplo que explicaremos, “extenderemos” la clase string para implementarle un nuevo método extensor (ToInteger). Estoy seguro que en varias ocasiones has tenido que convertir un string en int, y para ello has hecho algo similar a lo siguiente:

    int numero = Convert.ToInt32(strEdad);

Pues con los métodos extensores podemos conseguir este mismo resultado pero de una forma más intuitiva, haciendo que parezca que el método extensor es propio de la misma clase. Para resolver el ejemplo planteado bastaría con agregar un método extensor a la clase string. Al hacerlo podríamos conseguir esto (ver imagen):

MetodosAnonimos

Pero veamos lo que tendríamos que hacer para conseguir el método extensor ToInteger().

Nota: Se puede ‘extender’ cualquier clase de cualquier tipo, ya sea de .NET o una clase definida por nosotros mismos o incluso un tercero.

Método Extensor C#

Para crear un método extensor en C# debemos usar la palabra reservada this como el primer parámetro del método.

Código C# de nuestro método extensor de ejemplo:

namespace dllComunes
{
  public static class Extensiones
  {  
    ///Metodo Extensor asociado a un string que devuelve un entero
    public static int ToInteger(this string cadena, int valorXDefecto)
    {
      int result = valorXDefecto;
 
      try
      {
        result = Convert.ToInt32(cadena);
      }
      catch {}
 
      return result;
    }
    ///Sobrecarga del Metodo Extensor. Si no pasamos el 2do parámetro, se asume 0
    public static int ToInteger(this string cadena)
    {
      return ToInteger(cadena, 0);
    }
  }  
}

En nuestro ejemplo extendimos la clase string, pero también podíamos haber extendido la clase object, y el mismo método extensor nos serviría en otras muchas situaciones prácticas, por ejemplo:

string strNumero = "03";
 
int numero1 = strNumero.ToInteger();
int numero2 = "05".ToInteger();
int numero3 = Request.QueryString["IdRegistro"].ToInteger();
int numero4 = Session["IdUsuario"].ToInteger();

Métodos Extensores, Requisitos

  1. Los métodos extensores además de ser estáticos (static), deben estar incluidos en clases estáticas.
  2. El primer parámetro del método será el tipo a extender y deberá estar precedido de la palabra reservada this.
  3. Es posible sobrecargar métodos existentes.
  4. Si definimos un método extensor coincidente con uno del tipo a extender, el nuestro será ignorado.
  5. Es posible extender clases, estructuras, interfaces y delegados.

Artículos Relacionados: