miércoles, 31 de octubre de 2007

Sistema de Archivos: Unidades de Disco

La clase DriveInfo nos brinda los elementos necesarios para poder acceder a la información de las unidades disponibles en nuestro sistema. esto incluye no solo los discos rigidos, sino las unidades de red que tengamos mapeadas, unidades extraibles, etc.-

Esta clase posee un único metodo estático (GetDrives()) el cual devuelve la lista de todas las unidades de nuestro sistema.

Las instancias de esta clase cuentan con las siguientes propiedades:
- AvailableFreeSpace: Retorna el espacio disponible de una unidad (en bytes). Puede diferir del valor retornado por TotalFreeSpace, dependiendo de las cuotas de discos.
- DriveFormat: Retorna el formato de la unidad tal como FAT32 o NTFS.
- DriveType: Retorna una enumeración (ver el ejemplo) para el tipo de la unidad (Fijo, Optico, Red, etc.)
- IsReady: Retorna el estado de la unidad. Especifica si la unidad esta lista para ser accedida (por ejemplo no es posible acceder a mi unidad de CD mientras escucho mi CD de musica)
- Name: El nombre de la unidad.
- RootDirectory: Retorna un objeto DirectoryInfo que representa el directorio raiz de la unidad.
- TotalFreeSpace: Retorna el total de espacio libre en la unidad (en bytes).
- TotalSize: Retorna el tamaño total de la unidad.
- VolumeLabel: Retorna o escribe una etiqueta para unidades que no sean de solo lectura (CD/DVD).

Veamos un ejemplo utilizando algunos de estos conceptos:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Exam70536.FileSystemTest
{
class Program
{
private const string HARD_DRIVES = "Unidades de Discos duros";
private const string NETWORK_DRIVES = "Unidades de Red";
private const string OPTICAL_DRIVES = "Unidades de CD/DVD";
private const string REMOVABLE_DRIVES = "Unidades Extraibles";
private const string LINE = "--------------------------------------------";

static void Main(string[] args)
{
ViewSystemDrives();
Console.ReadKey();
}

private static void ViewSystemDrives()
{
DriveInfo[] drives = DriveInfo.GetDrives();
List<DriveInfo> hardDrives = null;
List<DriveInfo> opticalDrives = null;
List<DriveInfo> netDrives = null;
List<DriveInfo> remDrives = null;

try
{
hardDrives = new List<DriveInfo>();
opticalDrives = new List<DriveInfo>();
netDrives = new List<DriveInfo>();
remDrives = new List<DriveInfo>();

foreach (DriveInfo drive in drives)
{
switch (drive.DriveType)
{
case DriveType.CDRom:
if (drive.IsReady)
opticalDrives.Add(drive);
break;
case DriveType.Fixed:
hardDrives.Add(drive);
break;
case DriveType.Network:
netDrives.Add(drive);
break;
case DriveType.NoRootDirectory:
break;
case DriveType.Ram:
break;
case DriveType.Removable:
remDrives.Add(drive);
break;
case DriveType.Unknown:
break;
default:
break;
}
}

Console.WriteLine(HARD_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo hDrive in hardDrives)
{
Console.WriteLine("{0} Tamaño:{1}GB Espacio disponible:{2}GB",
hDrive.Name,
hDrive.TotalSize / 1024 / 1024 / 1024,
hDrive.AvailableFreeSpace / 1024 / 1024 / 1024);
}

Console.WriteLine();
Console.WriteLine(OPTICAL_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo oDrive in opticalDrives)
{
Console.WriteLine("{0}", oDrive.Name);
}

Console.WriteLine();
Console.WriteLine(REMOVABLE_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo rDrive in remDrives)
{
Console.WriteLine("{0}", rDrive.Name);
}

Console.WriteLine();
Console.WriteLine(NETWORK_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo nDrive in netDrives)
{
Console.WriteLine("{0}", nDrive.Name);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}

miércoles, 29 de agosto de 2007

ASP.NET AJAX Extensions: Introduccion

AJAX es un término genérico para definir una colección de tecnologías y procesos que podemos utilizar en nuestras aplicaciones web. ASP.NET AJAX es la implementación comenzada por Microsoft y que luego pasó a ser mantenida por una comunidad e incluye varios beneficios para los desarrolladores.

Muchos desarrolladores hemos encontrado un poco complicado crear aplicaciones con AJAX debido a la complejidad relacionada con JavaScript para implementar funcionalidad AJAX.

ASP.NET AJAX combina una extensa librería de código con una coleccion de componentes del lado del servidor que hacen la vida de los desarrolladores mucho mas simple y pueden ser utilizadas en nuestras aplicaciones AJAX-enabled. Algunos de los beneficios principales de la utilización de esta tecnología harán que nuestras aplicaciones web sean:

- Más dinámicas.
- Con mejores tiempos de respuesta.
- Más fáciles de utilizar.
- Más interesantes desde el punto de vista de usuario.
- Compatibles con la gran mayoria de los browsers.

Funcionalidad del lado del Cliente:
Del lado del cliente, ASP.NET AJAX provee un conjunto de archivos con código JavaScript conocidos como AJAX Library lista para ser agregada a nuestras aplicaciones web. Estos archivos. Estos archivos usan extensiones del lenguaje JavaScript para hacer posible que el código sea parecido a C#, incluyendo el uso de estructuras de Programación Orientada a Objetos (POO) . Esto nos permite a los desarrolles agregar codigo JavaScript a nuestras aplicaciones web de una forma mucho mas fácil. Además, esta librería trabaja con todos los browsers actuales liberando al desarrollador de la tediosa tarea de escribir código específico para cada browser.

Funcionalidad del lado del Servidor:
Para los desarrolladores ASP.NET 2.0 está disponible una serie de controles de servidor conocido como AJAX extensions, estos controles del lado del servidor permiten escribir muy pocas o ninguna linea de código JavaScript. Todos los controles de servidor generan el código JavaScript necesario. Algunos de estos controles conocidos como extenders afectan la funcionalidad o comportamiento de otros controles en vez de proveer su propia interfaz de usuario. De esta forma, podemos utilizar por ejemplo un text box extender para agregar la funcionalidad a un text box de nuestra aplicación para por ejemplo agregar la funcionalidad de autocompletar.

Framework Extensible:
ASP.NET AJAX nos permite extender o ampliar la funcionalidad existente, tanto de código del lado del cliento como de codigo del lado del servidor. Hay disponibles clases bases y archivos JavaScript de los cuales se pueden heredar y agregar funcionalidad. También se puede descargar el AJAX Control Toolkit con el cual tendremos disponibles muchos componentes listos para utilizar (extenders).
El AJAX Control Toolkit incluye una plantilla para simplificar la creación de componentes del lado del cliente.

Hasta aqui una breve introduccion. En proximas entradas ire profundizando en conceptos relaciondos.

viernes, 3 de agosto de 2007

Visual Studio add-in: GhostDoc

GhostDoc es un add-in para Microsoft Visual Studio 2003/2005 que permite generar de forma automátizada comentarios XML indispensables para la documentación en nuestros desarrollos. El mayor problema de escribir estos comentarios XML es quye es un trabajo tedioso que demanda tiempo y por lo general se termina escribiendo siempre comentarios generales y similares. El objetivo de GhostDoc es automatizar este trabajo tedioso mirando el nombre de nuestras clases y métodos como así también y realizar una "adivinanza" de lo que los comentarios XML deberían incluir. El único problema, pero que a largo plazo redunda en mejoras a nuestro código es que funciona en inglés y de acuerdo a las recomendaciones en la nomenclatura de nuestros elementos (clases, interfaces o métodos). No debería reemplazar nuestra tarea de documentación pero al menos se encarga de la parte repetitiva de la misma.

- Source / Download: http://www.roland-weigelt.de/ghostdoc/

- Licencia: FREE.

- COPYRIGHT. Copyright © Roland Weigelt

- Proceso de instalación: En el sitio web se pueden obtener los instaladores para las diferentes versiones de VS.NET (2003/2005). El proceso de instalación es bien sencillo y no ofrece complicaciones.

- Integración con el IDE de Desarrollo: Luego de la instalación al abrir VS 2005 nos aparecen dos pantallas para terminar de configurar el ad-in. En las mismas se nos requiere asignar un atajo de teclado donde CTRL+Shift+D es el atajo por defecto aunque podemos seleccionar de un drop down list otras opciones e incluso podemos omitir este paso. Este add-in tiene tres formas principales de integrarse a nuestro IDE

  • A través de una opcion en el menú Tools -> GhostDoc
  • A través del menú contextual con la opción "Document this"
  • A través del atajo de teclado una vez que hemos seleccionado un elemento (clase, interface, método)

- Veamos un ejemplo:

Supongamos que tenemos el siguiente método

    public DataSet getEmployeeList(long companyId, string companyName)
{
DataSet dsEmployees = new DataSet();
// Code for getting DataSet
return dsEmployees;
}

Al seleccionar el método y utilizar cualquiera de las tres opciones enumeradas anteriormente veremos que se genera de forma automática lo siguiente:

    /// <summary>
/// Gets the employee list.
/// </summary>
/// <param name="companyId">The company id.</param>
/// <param name="companyName">Name of the company.</param>
/// <returns></returns>
public DataSet getEmployeeList(long companyId, string companyName)
{
DataSet dsEmployees = new DataSet();
// Code for getting DataSet
return dsEmployees;
}

Como se puede observar, dependiendo de cuan descriptivo sean nuestros nombres de métodos y parámetros y las recomendaciones seguidas en cuestión de nomenclatura, resulta un complemento de mucha utilidad.

Visual Studio add-in: CopySourceAsHtml

CopySourceAsHtml es un add-in para Microsoft Visual Studio 2003/2005 que permite copiar código fuente, coloreo de sintaxis y todo el formato provisto por Visual Studio como HTML para que sea muy cómodo insertarlo en nuestros sitios webs, blogs o foros. En nuestra fase de prueba hemos notado algunos problemas en como se visualiza en Blogger pero si se edita el HTML de Blogger se pueden lograr resultados aceptables. Más abajo incluimos una sección de código C# (aunque puede ser utilizado con VB.NET o cualquier lenguaje soportado por el Framework) para dar un ejemplo de cómo funciona. La idea de este add-in es lograr que un browser visualice el código lo más parecido posible al entorno de desarrollo y lo logra de forma más que aceptable.

- Source / Download: http://www.jtleigh.com/people/colin/software/CopySourceAsHtml/

- Licencia: FREE. COPYRIGHT NOTICE. Copyright © 2006 J.T. Leigh & Associates Inc. All rights reserved.


- Proceso de instalación: En el sitio web se pueden obtener los instaladores para las diferentes versiones de VS.NET (2003/2005). El proceso de instalación es bien sencillo y no ofrece complicaciones.

- Integración con el IDE de Desarrollo: La integración con el IDE de desarrollo es realmente muy simple, intuitiva y efectiva. Todo lo que necesitamos es seleccionar nuestro código fuente y realizar click derecho donde encontraremos la opción "Copy As HTML". Esta opción abre una caja de diálogo donde podemos setear numerosas propiedades como agregar números de línea, el tamaño de la indentación, y hasta podemos incluir código CSS personalizado.


jueves, 2 de agosto de 2007

GridView - Paginacion y Ordenamiento simultaneo

Cuando trabajamos con el componente GridView las tareas mas comunes son las de Ordenamiento y de Paginación.
El hecho de lograr ambas tareas de forma simultanea en páginas ASP.NET presenta un pequeño cuidado; se debe mantener el índice de la página en la que estamos cuando establecemos un nuevo criterio de ordenamiento. De la misma forma debemos mantener el criterio de ordenamiento al cambiar el índice de la página a la que queremos acceder.

El código que sigue es un ejemplo o una de las formas, siempre hay mas de una forma :), de como se puede lograr esta tarea.-

- SortingPaging.aspx (nuestra página aspx)
    <asp:GridView ID="gridSample" runat="server" AutoGenerateColumns="false"
AllowPaging = "true" OnPageIndexChanging = "gridView_PageIndexChanging"
PageSize = "5"
AllowSorting = "true" OnSorting = "gridView_Sorting">
<Columns>
<asp:BoundField HeaderText="Nombre"
DataField="Nombre"
SortExpression = "Nombre" />
<asp:BoundField HeaderText="Edad"
DataField="edad"
SortExpression = "edad" />
</Columns>
</asp:GridView>
- SortingPaging.aspx.cs (nuestro archivo de code behind)
using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class SortingPaging : Page {
protected void Page_Load(object sender, EventArgs e) {
DataSet ds = new DataSet();
// Aqui llenamos nuestro DataSet
DataView dv = ds.Tables[0].DefaultView;
dv = sortDataView(dv, true);
gridSample.DataSource = dv;
gridSample.DataBind();
}

private string GridSampleSortDirection {
get { return ViewState["SortDirection"] as string ?? "ASC"; }
set { ViewState["SortDirection"] = value; }
}

private string GridSampleSortExpression {
get { return ViewState["SortExpression"] as string ?? "Nombre"; }
set { ViewState["SortExpression"] = value; }
}

private string getSortDirection() {
switch (GridSampleSortDirection) {
case "ASC":
GridSampleSortDirection = "DESC";
break;

case "DESC":
GridSampleSortDirection = "ASC";
break;
}
return GridSampleSortDirection;
}

protected void gridView_PageIndexChanging(object sender, GridViewPageEventArgs e) {
gridSample.DataSource = sortDataView(gridSample.DataSource as DataView, true);
gridSample.PageIndex = e.NewPageIndex;
gridSample.DataBind();
}

protected DataView sortDataView(DataView dataView, bool isPageIndexChanging) {
if (isPageIndexChanging) {
dataView.Sort = string.Format("{0} {1}",
GridSampleSortExpression,
GridSampleSortDirection);
} else {
dataView.Sort = string.Format("{0} {1}",
GridSampleSortExpression,
getSortDirection());
}
return dataView;
}

protected void gridView_Sorting(object sender, GridViewSortEventArgs e) {
GridSampleSortExpression = e.SortExpression;
int pageIndex = gridSample.PageIndex;
gridSample.DataSource = sortDataView(gridSample.DataSource as DataView, false);
gridSample.DataBind();
gridSample.PageIndex = pageIndex;
}
}

martes, 31 de julio de 2007

Navega tu sitio con siteMapPath

Vamos a ver un ejemplo de como agregar navegación simplificada a través de diferentes secciones de nuestro sitio sin importar la estructura de directorios del mismo.

Siguiendo con la idea de utilizar nuestra aplicación base de ejemplo, vamos suponer que tenemos una sección de inscripciones de alumnos y que vamos a mostrar en determinadas páginas de nuestro sitio el camino que recorre la aplicación (Inicio > Alumnos > Inscripciones).

Para ello ASP.NET nos provee de elementos que nos hacen la vida muy facil. Para nuestro ejemplo vamos a utilizar 3 elementos:

- <asp:SiteMapDataSource/>
- <asp:SiteMapPath/>
- Archivo Site Map (xml)

Como se trata de código que nos gustaría utilizar en diferentes páginas de nuestro sitio, vamos a crear un web user control y vamos a agregarle los dos primeros elementos que mencionamos. El código sería algo como lo siguiente:
<%@ Control Language="C#" AutoEventWireup="true"
CodeFile="siteNavigation.ascx.cs" Inherits="commonControls_siteNavigation" %>

<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
<asp:SiteMapPath ID="SiteMapPath1" runat="server"/>
Luego necesitamos crear el archivo web.siteMap.xml. Esto es tan simple como hacer click derecho en la aplicación > Add Item y seleccionar Site Map de las opciones en Visual Studio o bien agregar un archivo xml y nombrarlo web.siteMap.xml.

La estructura de este archivo es como el ejemplo que sigue. Note que todos los archivos están en el directorio raiz de mi aplicación pero a través de los nodos siteMapNode puedo lograr la creación de secciones lógicas de acuerdo a mis necesidades.
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~\inicio.aspx" title="Inicio" description="">
<siteMapNode url="~\alumnos.aspx" title="Alumnos" description="">
<siteMapNode url="~\alumnoInscripcion.aspx"
title="Inscripciones" description="" />
</siteMapNode>
</siteMapNode>
</siteMap>
Por último incluimos el web user control que creamos antes en las páginas que necesitamos que se muestre el path de la aplicación. Por ejemplo en nuestra página alumnoInscripcion.aspx:
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true"
CodeFile="alumnoInscripcion.aspx.cs" Inherits="alumnoInscripcion"
Title="Untitled Page" %>

<%@ Register Src="~/commonControls/siteNavigation.ascx"
TagName="siteNavigation" TagPrefix= "uc1" %>


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<uc1:siteNavigation ID="siteNavigation1" runat="server" />
</asp:Content>
Esto es todo lo que necesitamos; compilamos y ejecutamos la aplicacion y si vamos a nuestra página alumnoInscripcion.aspx veremos algo parecido a la siguiente imagen. Espero que les haya sido útil, no dejen de participar dejando comentarios.

lunes, 30 de julio de 2007

Dando formato a código C# y HTML

Una de las necesidades que surgen a partir de la decisión de comenzar un blog o sitio web que involucra tecnologías de desarrollo es la de ofrecer a tus lectores code snippets o porciones de código tanto HTML como C#.

Uno de los add-ins que he utilizado es CopySourceAsHTML. Pueden leer un artículo que he escrito en la siguiente url: http://www.ide-plugins.com.ar/visual-studio-add-ins/visual-studio-.net-2005/copysourceashtml.html

Esta extensión para Visual Studio funciona muy bien y me ha resultado muy util en otros sitios web y herramientas CMS (DNN, Joomla, etc), pero en lo que respecta a Blogger, no genera el código de forma óptima por lo cual he necesitado cambiarlo por uno que me recomendó mi amigo Martin Olivares Pick.

Se trata de un formateador online que podemos encontrar en: http://www.manoli.net/csharpformat/
Funciona mucho mejor con Blogger y es muy simple de utilizar, por lo tanto lo recomiendo ampliamente.

Gracias Martin!!!

jueves, 19 de julio de 2007

ASP.NET AJAX Toolkit: Download e Instalación

Una de las características principales de un desarrollo WEB 2.0 radica en la utilización de la tecnología AJAX. Microsoft nos provee de las herramientas necesarias para el desarrollo de aplicaciones con esta tecnología. Estas herramientas son las siguientes: las ASP.NET 2.0 AJAX Extensions 1.0 y el ASP.NET AJAX Control Toolkit. Vamos a ver en este primer contacto como conseguir estas herramientas, instalarlas en nuestro sistema y configurarlas en nuestro entorno de desarrollo.

- Download e Instalación
Para realizar el download de estas herramientas, apuntamos nuestro navegador favorito a la siguiente dirección: http://www.asp.net/ajax/downloads/;
aqui tenemos dos links para realizar el download de estas herramientas.

En el paso 1 vamos a hacer click en el link que muestra la figura para realizar el download de las ASP.NET Extensions v1.0. Este link nos direcciona una página del sitio web de Microsoft.

Una vez hecho el download procedemos a la instalación. El proceso de instalación es bastante estandar y no merece comentarios adicionales. La ruta donde se instalarán las extensiones es: C:\Archivos de programa\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025

Luego repetimos el proceso para el paso 2 hacieno click en el botón Download the Control Toolkit. En este caso, accederemos a una página en el sitio de CodePlex. Aqui podremos descargar tanto el Toolkit incluyendo el código fuente. En nuestro primer contacto, solo necesitamos el Toolkit sin incluir el código, el cual es evidentemente un download de menor tamaño. Hacemos click en AjaxControlToolkit-NoSource.zip y lo descomprimimos en algún lugar de nuestro disco. En lo personal prefiero mantener cierto orden para esta instalación para lo cual descomprimo este archivo en la siguiente ruta: C:\Archivos de programa\Microsoft ASP.NET\ASP.NET AJAX Control Toolkit\.



- Configuración del entorno
Una vez realizados los pasos anteriores (Downloads de los dos archivos e instalación de las ASP.NET Extensions -este es un paso requerido por el Toolkit-). Abrimos Visual Studio y creamos un nuevo sitio web eligiendo "AJAX Control Toolkit Web Site" an la sección My Templates.

Aquí vamos a agregar un tab en nuestro Toolbox para poder utilizar los controles provistos por el Toolkit. Para ello hacemos click derecho debajo del tab General y elegimos "Add Tab"; le ponemos un nombre como AJAX Toolkit; dentro de este nuevo tab hacemos click derecho y seleccionamos la opción "Choose Items...", un cuadro de diáologo aparece y hacemos click en "Browse..." y buscamos la carpeta bin del sitio de ejemplo en el path de la instalación de las AJAX Toolkit. Par nuestro caso la ruta completa es C:\Archivos de programa\Microsoft ASP.NET\ASP.NET AJAX Control Toolkit\SampleWebSite\Bin; alli seleccionamos el archivo AjaxControlToolkit.dll y listo. Ahora tenemos disponibles los controles para agregar en nuestras aplicaciones ASP.NET!

jueves, 15 de marzo de 2007

- Paging and Sorting

Las tareas de Paging y Sorting de forma simultanea en páginas ASP.NET presenta un pequeño cuidado; se debe mantener el índice de la página en la que estamos cuando establecemos un nuevo criterio de ordenamiento. De la misma forma debemos mantener el criterio de ordenamiento al cambiar el índice de la página a la que queremos acceder.

El código que sigue es un ejemplo o una de las formas, siempre hay mas de una forma :), de como se puede lograr esta tarea.-

- SortingPaging.aspx (nuestra página aspx)
    <asp:GridView ID="gridSample" runat="server" AutoGenerateColumns="false"
AllowPaging = "true" OnPageIndexChanging = "gridView_PageIndexChanging"
PageSize = "5"
AllowSorting = "true" OnSorting = "gridView_Sorting">
<Columns>
<asp:BoundField HeaderText="Nombre"
DataField="Nombre"
SortExpression = "Nombre" />
<asp:BoundField HeaderText="Edad"
DataField="edad"
SortExpression = "edad" />
</Columns>
</asp:GridView>
- SortingPaging.aspx.cs (nuestro archivo de code behind)
using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class SortingPaging : Page {
protected void Page_Load(object sender, EventArgs e) {
DataSet ds = new DataSet();
// Aqui llenamos nuestro DataSet
DataView dv = ds.Tables[0].DefaultView;
dv = sortDataView(dv, true);
gridSample.DataSource = dv;
gridSample.DataBind();
}

private string GridSampleSortDirection {
get { return ViewState["SortDirection"] as string ?? "ASC"; }
set { ViewState["SortDirection"] = value; }
}

private string GridSampleSortExpression {
get { return ViewState["SortExpression"] as string ?? "Nombre"; }
set { ViewState["SortExpression"] = value; }
}

private string getSortDirection() {
switch (GridSampleSortDirection) {
case "ASC":
GridSampleSortDirection = "DESC";
break;

case "DESC":
GridSampleSortDirection = "ASC";
break;
}
return GridSampleSortDirection;
}

protected void gridView_PageIndexChanging(object sender, GridViewPageEventArgs e) {
gridSample.DataSource = sortDataView(gridSample.DataSource as DataView, true);
gridSample.PageIndex = e.NewPageIndex;
gridSample.DataBind();
}

protected DataView sortDataView(DataView dataView, bool isPageIndexChanging) {
if (isPageIndexChanging) {
dataView.Sort = string.Format("{0} {1}",
GridSampleSortExpression,
GridSampleSortDirection);
} else {
dataView.Sort = string.Format("{0} {1}",
GridSampleSortExpression,
getSortDirection());
}
return dataView;
}

protected void gridView_Sorting(object sender, GridViewSortEventArgs e) {
GridSampleSortExpression = e.SortExpression;
int pageIndex = gridSample.PageIndex;
gridSample.DataSource = sortDataView(gridSample.DataSource as DataView, false);
gridSample.DataBind();
gridSample.PageIndex = pageIndex;
}
}

- Conversión de Ilist en DataTable

Nota: Este código ha sido probado con .NET Framework 2.0

Muchas veces retornamos de nuestra fuente de datos un set de datos de tipo Ilist, el cual enlazamos a nuestros GridViews sin ningún problema.

Como veremos en próximas entradas, hay una forma muy interesante de realizar sorting y paging al mismo tiempo, para ello necesitamos pasar como parámetro un DataTable en uno de los métodos que implementaremos , por lo cual vamos a escribir una utilidad que convierta un Ilist en un DataTable.

Como en casos anteriores, tomaremos la aplicación de ejemplo de este blog (virtualEducation) y agregaremos en el módulo de Utilidades la clase Converter.cs, la cual iremos completando en las próximas entradas. En esta oportunidad , solo definiremos el método public static DataTable IList2DataTable(IList iList) para tener solo el conversor que necesitamos.

Aquí tenemos el código:


using System;
using System.Collections;
using System.Data;
using System.Reflection;

namespace Utilidades {
public class Converter {
public static DataTable IList2DataTable(IList iList) {
DataTable oDataTableReturned = new DataTable();

if (iList.Count > 0) {
object _baseObj = iList[0];
Type objectType = _baseObj.GetType();
PropertyInfo[] properties = objectType.GetProperties();

foreach (PropertyInfo property in properties) {
DataColumn oColumna;
oColumna = new DataColumn();
oColumna.ColumnName = property.Name;
oColumna.DataType = property.PropertyType;
oDataTableReturned.Columns.Add(oColumna);
}

foreach (object objItem in iList) {
DataRow oFila;
oFila = oDataTableReturned.NewRow();
foreach (PropertyInfo property in properties) {
oFila[property.Name] = property.GetValue(objItem, null);
}
oDataTableReturned.Rows.Add(oFila);
}
}
return oDataTableReturned;
}
}
}

- Issue con nuevas clases en VS2005

El nuevo Visual Studio 2005 es una muy buena herramienta que nos ofrece muchas ventajas y nos ahorra muchos esfuerzos.

Sin embargo hay una característica que no me resulta del todo agradable. Cuando agregamos librerias de clases (class libraries) como en el ejemplo de virtualEducation y creamos una clase dentro de alguna de estas librerías como hemos hecho en una entrada anterior con el generador de GUIDs; notamos que las clases nuevas no tienen accesibilidad pública por lo que al querer utilizarlas no están disponibles.

Esto requiere que agreguemos el modificador de acceso a public y hagamos un rebuild de la librería de clases y a veces necesitamos hacer rebuild de toda la solución.-

Me gustaría saber si alguien conoce una forma de configurar el VS 2005 para que por defecto genere las clases como públicas.

lunes, 12 de marzo de 2007

- Subir archivos grandes con httpRuntime

En algunas situaciones necesitamos permitir que los usuarios de nuestra aplicación realicen upload de archivos de tamaño importante (digamos 6 a 10 Mb).
Hemos visto a través de una entrada anterior como subir archivos con ASP.NET y AJAX.
Por defecto, ASP.NET permite realizar uploads de hasta 4Mb. Hoy veremos como podemos configurar nuestros servidores o nuestra aplicación para que permita subir archivos mayores a este tamaño.

Esta configuración se puede realizar tanto en los archivos machine.config como en archivos web.config de cada aplicación. El elemento en cuestión que nos permitirá esta operación es <httpRuntime> a través de su atributo maxRequestLength.

Este atributo indica el tamaño máximo soportado por ASP.NET para un archivo que necesita ser subido a un servidor. El tamaño se debe especificar en kbytes. Como adelantamos antes el valor por defecto es 4096 kb.

El elemento <httpRuntime> debe ubicarse dentro de la sección configuration/system.web de nuestro archivo de configuración. Veamos un ejemplo simple para un archivo de 6Mb:
<configuration>
<system.web>
<httpRuntime maxRequestLength="6144"/>
</system.web>
</configuration>

- GUID Generator con C#

GUID es un acrónimo para Globally Unique Identifier o identificador único global, es un número de 128 bits que es producido por el sistema operativo Windows o por algunas aplicaciones Windows para identificar un componente particular, una aplicación, un archivo, un registro en una base de datos y/o un usuario. Por ejemplo, podemos tener un sitio web que genere un GUID y se lo asigne a un usuario para grabar las acciones de este usuario en la sesión (lo que se conoce como session tracking).

GUID se utiliza también en el registro de Windows para identificar dlls COM. Algunos DBAs incluso utilizan un GUID como claves primarias de sus bases de datos.
Un ejemplo de GUID generado es el siguiente: {ded53e2b-91e9-4682-b673-862ca6503b2e}

Si bien no está garantizado que un GUID generado sea único, el total de claves que se pueden generar (2 elevado a la 128 potencia
) es tan grande que la probabilidad de que se repita es realmente muy pequeña. Para dar una idea de esto podemos decir que una aplicación que genere 10 mil millones de GUID la probabilidad de que se repita una clave generada es de 1 en un quintillión (en la escala americana - 10 elevado a la 30 potencia en la escala tradicional).

Veamos entonces como se genera un GUID en una aplicación Windows con C#. Para mostrar un ejemplo vamos a utilizar la aplicación virtualEducation que generamos en una entrada anterior (ver entrada) y vamos a ubicar nuestra clase GUIDGenerator en el módulo de Utilidades.
Este es todo el código que necesitamos:



namespace Utilidades {
class GUIDGenerator {
public static string getGUIDString() {
string guidIdentifier = System.Guid.NewGuid().ToString();
guidIdentifier = guidIdentifier.Replace("-", string.Empty);
guidIdentifier.ToUpper();
return guidIdentifier;
}
}
}

viernes, 9 de marzo de 2007

- Tabs simples en ASP.NET

Algunas de nuestras aplicaciones necesitan mostrar tabs o elementos superpuestos. Vamos a ver como se logra este efecto utilizando dos elementos de ASP.NET; estos son el elemento asp:Menu y el elemento asp:MultiView. El código es realmente muy sencillo y nos ayudamos con un set de 4 imágenes. Dos imágenes para el primer y segundo tab (con sus estados activado y desactivado).


-SimpleTabulation.aspx (nuestra página aspx)
<body>
<form id="form1" runat="server">
<div>
<asp:Menu ID="MenuTab" Width="120px" runat="server"
Orientation="Horizontal" StaticEnableDefaultPopOutImage="False"
OnMenuItemClick="MenuTab_MenuItemClick">
<Items>
<asp:MenuItem ImageUrl="~/images/TabOneOn.jpg" Value="0"/>
<asp:MenuItem ImageUrl="~/images/TabTwoOff.jpg" Value="1"/>
</Items>
</asp:Menu>
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
<asp:View ID="View1" runat="server">
Contenido del Tab 1!
</asp:View>
<asp:View ID="View2" runat="server">
Contenido del Tab 2!
</asp:View>
</asp:MultiView>
</div>
</form>
</body>

-SimpleTabulation.aspx.cs (nuestro archivo de code behind)

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class SimpleTabulation : Page {
protected void MenuTab_MenuItemClick(object sender, MenuEventArgs e) {
MultiView1.ActiveViewIndex = Int32.Parse(e.Item.Value);
int selectedTab = Int32.Parse(e.Item.Value);

switch (selectedTab) {
case 0:
MenuTab.Items[0].ImageUrl = "~/images/TabOneOn.jpg";
MenuTab.Items[1].ImageUrl = "~/images/TabTwoOff.jpg";
break;

case 1:
MenuTab.Items[0].ImageUrl = "~/images/TabOneOff.jpg";
MenuTab.Items[1].ImageUrl = "~/images/TabTwoOn.jpg";
break;
}
}
}

- Custom Exceptions en ASP.NET

En esta entrada veremos como utilizar excepciones personalizadas o custom exceptions. La idea básica es muy simple. Se trata crear una clase que herede de la clase Exception de ASP.NET y pasarle argumentos básicos como puede ser el mensaje de la excepción e incluso parámetros personalizados. Vamos a ver un ejemplo muy simple en el cual tenemos un label en el cual mostraremos el mensaje de la excepción arrojada desde nuestra aplicación.

- CustomExceptions.aspx (nuestra página aspx)
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblException"
runat="server" Text="" />
</div>
</form>
</body>
- CustomExceptions.aspx.cs (nuestro archivo de code behind)
using System;
using System.Web.UI;

public class MyCustomException : Exception {
public MyCustomException(string message) : base(message) { }
}

public partial class TestCustomExceptions : Page {

public void Page_Load(object sender, EventArgs e) {
try {
if (1 == 1) {
throw new MyCustomException("Testing Custom Exceptions.-");
}
} catch (MyCustomException exc) {
Trace.Write(exc.Message);
lblException.Text = exc.Message;
}
}
}

- File Upload con AJAX

Vamos a ver en esta entrada el código necesario para realizar upload de un archivo y que la experiencia de usuario sea cómoda a través del uso de AJAX. El concepto es muy simple; utilizamos dos divs, uno para mostrar el componente FileUpload de ASP.NET y otro para mostrar un mensaje o una imagen animada al usuario mientras la tarea de subir el archivo se ejecuta en segundo plano y no se muestra al usuario ninguna acción de Postback o roundtrip al servidor. A través de AJAX utilizamos una serie de funciones JavaScript para mostrar/ocultar los divs.

He aquí el codigo necesario:
- FileUpload.aspx (Nuestra página aspx)

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>File Upload Test</title>
<script language="javascript" type="text/javascript">

function divFileHide() {
var divFile = document.getElementById('fileUploadDiv');
divFile.style.display = 'none';

var divLoading = document.getElementById('loadingFileDiv');
divLoading.style.display = 'block';
}

function divFileShow() {
var divFile = document.getElementById('fileUploadDiv');
iframe.style.display = 'block';

var divLoading = document.getElementById('loadingFileDiv');
divLoading.style.display = 'none';
}

function upload(){
divFileHide();
}

function onComplete( result ) {
divFileShow();
}
</script>

</head>
<body>
<form id="form1" runat="server">
<div id="fileUploadDiv">
<asp:FileUpload ID="FileUpload1" runat="server" Visible="true" />
<asp:Button ID="btnUpload" runat="server" Text="Subir Archivo"
OnClick="btnUpload_Click"
Visible="true" />
<asp:Label ID="lblError" runat="server" Visible="false"
Font-Bold="true" ForeColor="red" />
</div>
<div id="loadingFileDiv" style="display: none;">
El archivo está subiendo...
</div>
</form>
</body>
- FileUpload.aspx.cs (Nuestro archivo de code behind)
using System;
using System.Web.UI;

public partial class FileUpload : Page {
protected void Page_Load(object sender, EventArgs e) {
btnUpload.Attributes.Add("onclick", "return upload();");
}
protected void btnUpload_Click(object sender, EventArgs e) {
if (FileUpload1.HasFile) {
try {
String uploadFolder = "D:\\Uploads\\";
String file = FileUpload1.FileName;

FileUpload1.SaveAs(uploadFolder + file);
} catch (Exception ex) {
Trace.Write(ex.Message);
}
} else {
lblError.Text = "
El archivo no ha sido especificado";
lblError.Visible = true;
}
}
}

jueves, 1 de marzo de 2007

- Esqueleto de una aplicación Web en ASP.NET

En esta oportunidad quiero compartir con ustedes una de las formas básicas de crear una aplicación web que utilice componentes reutilizables, que tenga módulos independientes y que pueda integrar algún framework de persistencia como NHibernate o Ibatis.
Esta tarea la llevaremos a cabo utilizando el IDE de desarrollo Visual Studio 2005. Vamos a suponer que estamos desarrollando una aplicación orientada a e-learning. Lo primero que debemos tener presente es que todos estos módulos los tendremos en una misma carpeta. En mi caso la carpeta en cuestión es D:\NETProjects\E-Learning.

* Módulos de nuestra aplicación:
- Sitio Web: En éste módulo tendremos nuestras páginas .aspx con sus correspondientes archivos de code behind (.aspx.cs), las cuales utilizarán las clases y objetos (no se trata de otra cosa) del resto de los módulos involucrados en la aplicación.

- Módulo de Model: En éste módulo almacenaremos todas las clases de objetos que nuestra aplicación requiera. En nuestro caso, al tratarse de una aplicación de e-learning, ejemplos de clases que pondremos en este módulo son: curso, asignatura, profesor, etc.

- Módulo de Persistencia: En éste módulo crearemos dos carpetas. La primera será nuestra carpeta de Interfaces en la cual tendremos las interfaces de las clases que necesitamos persistir. El uso de interfaces nos permite además migrar de un framework a otro teniendo que modificar solo las implementaciones del mismo. Entonces necesitaremos una segunda carpeta que puede llamarse Implementaciones. En ella almacenaremos los archivos necesarios que dependerán del framework de persistencia que elijamos.

- Módulo de Servicio: En éste módulo se almacenarán las clases necesarias para ejecutar llamadas a las clases en el módulo de persistencia y eventualmente procesar reglas de negocio antes de realizar la persistencia.

- Módulo de Utilidades: En éste módulo se almacenarán aquellas clases que pueden ser reutilizables en más de un proyecto como pueden ser utilidades de conversion para listas, arrays, etc.-

Veamos como es el proceso en Visual Studio 2005 para lograr este esqueleto:

1- Sitio Web:
Creamos el sitio Web a través de la opción File... New Web Site... elegimos el lenguaje (C# en nuestro caso) , elegimos la ruta y el nombre de nuestro sitio o aplicación Web, para nuestro ejemplo será D:\NETProjects\E-Learning\virtualEducation donde E-Learning es la carpeta del proyecto conteniendo todos los módulos y virtualEducation es nuestro sitio web.

2- Módulos: Agregamos los móulos que vamos a necesitar. Abrimos la opción File... New Project y aquí tenemos varias opciones a tener en cuenta. Lo primero es elegir el tipo de proyecto. Elegimos Visual C# - Windows en Project types. Elegimos Class Library como template. Especificamos el nombre del poyecto, en nuestro caso Model, especificamos la ubicación: D:\NETProjects\E-Learning y por último seleccionamos el drop down list a Add to Solution.



Realizamos el mismo procedimiento para nuestros otros módulos teniendo en cuenta la creación de las dos carpetas en el módulo de Persistencia (Interfaces e Implementaciones)



3- Referencias: Ahora necesitamos agregar a nuestro sitio web las referencias a estos módulos para que al realizar la compilación nos genere dlls para estos proyectos. Para ello hacemos click derecho en nuestro sitio web y seleccionamos Add Reference... vamos al tab de Projects y seleccionamos los proyectos creados en el paso anterior.

4- Construir Solución: Por último, hacemos click derecho a nuestra solución Solution \virtualEducation (5 projects) y elegimos la opción Rebuild Solution. Vemos como se generan las dlls de nuestros proyectos en la carpeta Bin de nuestro sitio web.-



Con estos sencillos 4 pasos, tenemos listo nuestro esqueleto para una aplicación Web modularizada, escalable, lista para utilizar un framework de persistencia y componentes reutilizables.-

- Tooltips en columnas de GridView

Muchas veces por razones de espacio necesitamos poner nombres abreviados o acrónimos en las cabeceras de nuestros GridViews. Para enriquecer la experiencia de usuario podemos agregar tooltips a estas cabeceras de una forma muy sencilla de modo de proveer al usuario el nombre completo o mas descriptivo para determinado campo mostrado.

Pre-Requisitos:
* Tenemos establecida la conexión a la base de datos.
* Tenemos un DataSet con los datos para realizar el Binding al Dataview.
* Tenemos los datos en el gridview a traves de Databind().

Elementos Clave:
* Habilitar la propiedad HtmlEncode a false en cada campo enlazado.
* Utilizar elementos HTML en la propiedad HeaderText.

He aquí nuesto código:
- products.aspx (Nuestra página aspx)

<asp:gridview id="gvProducts" runat="server" autogeneratecolumns="false">
<Columns>
<asp:BoundField
HeaderText="Producto"
DataField="name"/>
<asp:BoundField
HtmlEncode="false"
HeaderText="&lt;div title='Cantidad'> Cant. </div>"
DataField="qty"/>
<asp:BoundField
HtmlEncode="false"
HeaderText="&lt;div title='Precio'> $ </div>"
DataField="price"/>
</Columns>
</asp:gridview>
Esta es solo una de las formas de realizarlo, otra forma es utilizando el tag <acronym> de HTML.