ScrumPeak (y una chiquita sobre ASP.NET MVC en IIS)

Como no andamos con mucho tiempo, vamos a hacer breves:

ScrumPeak, es una Aplicación Web para el seguimiento de proyectos con la característica que soporta Scrum. Para que tengan una idea de lo que se puede hacer con la web, dejo la siguiente pantalla:

http://sergiot2.com/blogimages/2010/09Sep/07_ScrumPeak.JPG

Por otro lado, la aplicación Web fue desarrollada con ASP.NET MVC, y si están en una versión de Windows que no tiene IIS 7 en modo Integrado, deben seguir algunos pasos adicionales para permitir la ejecución de la Web.

En este caso de ScrumPeak, como no disponemos del código fuente, la mejor opción sería habilitar que el mapeo todas las solicitudes del usuario sean hecho por asp.net, para lo cual, hacemos lo siguiente:

http://sergiot2.com/blogimages/2010/09Sep/07_ASP.NET_MVC_IIS_XP.JPG

Esta opción de habilitar el mapeo en el IIS no es recomendable porque afecta el rendmiento de la aplicación. Asumiendo que el portal será para uso interno, de equipos pequeños y estará en el servidor de desarrollo, no debemos notar esto. En una Aplicación Web para toda la internet, esta decisión no debe ser la primera.

Algunos enlaces relacionados:

 

Saludos,

[WebForms] Todavía no usas el ObjectDataSource?

Este es el intento N, de enviar un post de introducción al ObjectDataSource. Muchos post extensos se han quedado en el draft, veremos si este ve la luz.

ASP.NET disponible de varios controles para mostrar datos: GridView, ListView, DataList, Repeater, el mismo FormView. En cuanto controles para el artículo vamos a usar el GridView y el FormView. Veamos algunos ejemplos y al final intentamos definir al ObjectDataSource.

 

Mostrando datos

La forma tradicional, es el clásico:

   1: //enlazar gridView

   2: grdCategories.DataSource = blCatManager.GetAll();

   3: grdCategories.DataBind(); 

Con el ObjectDataSource no hago nada y todo es declarativo:

   1: <asp:GridView ID="grdCategories" runat="server" 

   2:        AutoGenerateColumns="False" 

   3:     DataKeyNames="CategoryID" DataSourceID="odsCategorias">

   4:     <Columns> <!-- Aqui Columnas --> </Columns>

   5:   </asp:GridView>

   6: <asp:ObjectDataSource ID="odsCategorias" runat="server" 

   7:     OldValuesParameterFormatString="original_{0}" SelectMethod="getAll" 

   8:     TypeName="CategoryManager">

   9: </asp:ObjectDataSource>

Este código no hay que aprenderlo de memoria, lo puede generar el asistente. Para grandes cantidades de información debemos usar paginación personalizada, el control GridView + ObjectDataSource, soportan esto de manera transparente, sólo hay que agregar un método count y mapearlo. Revisar más detalles en el siguiente artículo: Paginando Eficientemente en ASP.NET.

 

Ingreso de datos

Creo que este es el fuerte de los ObjectDataSource y una de las cosas por la cual lo uso en todos los proyectos de ASP.NET en que participo. Cuando he tenido la oportunidad de integrar nuevos equipos de desarrollo o visitar a algunos, muchos todavía siguen con el clásico recuperar/asignar el contenido de las cajas de texto de uno a uno, muchas veces por el desconocimiento de la existencia del control ObjectDataSource. Después de unas demos con el ObjectDataSource, también terminan adoptándolo, salvo algunos casos en que resisten al cambio, y trabajar con mas orden o porque tienen el famoso código: “mírame y no me toques”. si ese código donde si cambias un C= A + B, a C = B + A, la aplicación completa deja de funcionar.

Si quiere cargar el detalle de un registro en un formulario que tengo que hacer:

   1: //asignar información de objetos a las cajas de texto

   2: CategoryNameTextBox.Text = objItem.CategoryName; 

Y por el contrario si quiero recuperar el objeto para guardarlo en la base de datos, lo primero que debo hacer es recuperarlo de la caja de texto:

   1: //recuperar la información de las cajas de texto, para guardarlas en un objeto

   2: objItem.CategoryName = CategoryNameTextBox.Text; 

Un control FormView + ObjectDataSource, hace esto por ti, y todo de manera declarativa:

   1: <asp:FormView ID="frvDetCategoria" runat="server" 

   2:      DataKeyNames="CategoryID" 

   3:      DataSourceID="odsCatDetails">

   4:      <EditItemTemplate>

   5:        CategoryID:

   6:        <asp:Label ID="CategoryIDLabel1" runat="server" 

   7:          Text='<%# Eval("CategoryID") %>' />

   8:        <br />

   9:        CategoryName:

  10:        <asp:TextBox ID="CategoryNameTextBox" runat="server" 

  11:          Text='<%# Bind("CategoryName") %>' />

  12:        <br />

  13:        CategoryDescription:

  14:        <asp:TextBox ID="CategoryDescriptionTextBox" runat="server" 

  15:          Text='<%# Bind("CategoryDescription") %>' />

  16:        <br />

  17:        <asp:LinkButton ID="UpdateButton" runat="server" 

  18:           CausesValidation="True" 

  19:          CommandName="Update" Text="Actualizar" />

  20:        &nbsp;<asp:LinkButton ID="UpdateCancelButton" runat="server" 

  21:          CausesValidation="False" 

  22:           CommandName="Cancel" Text="Cancelar" />

  23:      </EditItemTemplate>

  24:      <InsertItemTemplate><!-- El formulario insert puede 

  25:             ser distinto por ya no se 

  26:              actualiza los campos claves --></InsertItemTemplate>

  27:      <ItemTemplate><!-- Informacion solo lectura --></ItemTemplate>

  28:    </asp:FormView>

  29:    <asp:ObjectDataSource ID="odsCatDetails" runat="server" 

  30:      DataObjectTypeName="Category" DeleteMethod="Delete" 

  31:      InsertMethod="Insert" 

  32:      OldValuesParameterFormatString="original_{0}" 

  33:      SelectMethod="getOneByID" 

  34:      TypeName="CategoryManager" UpdateMethod="Update">

  35:      <SelectParameters>

  36:        <asp:ControlParameter ControlID="grdCategories" 

  37:           Name="categoryID" 

  38:          PropertyName="SelectedValue" Type="Int32" />

  39:      </SelectParameters>

  40:    </asp:ObjectDataSource>

Con el control FormView se puede hacer prácticamente todo tipo de mantenimiento, se puede poner combos dentro de el y además que esté enlazados a base de datos a través de otro control ObjectDataSource. Podemos decir que el ObjectDataSource es un motorcito que permite mapear automáticamente controles de datos (tanto para mostrar como para recuperar) con clases y objetos. Imaginen un formulario de 20 campos y tener que asignar/recuperar uno por uno. Con el ObjectDataSource no es nada.

Para terminar, si están desarrollando en ASP.NET con WebForms, los animo a intentar usar el FormView + ObjectDataSource en los escenarios de mantenimiento que tengan, y si tienen alguna duda, puede dejar sus comentarios y vemos como los ayudamos. En base a las preguntas que tengan, podemos hacer ejemplos más elaborados y más puntuales.

Pueden descargar la aplicación ejemplo aquí: CRUD usando ObjectDataSource. (completar los acceso a datos del Insert, Update, Delete).

Página en el navegador:

El código que tiene la página aspx es:

   1: //pagina ASPX

   2: using System;

   3:  

   4: public partial class wfCategories : System.Web.UI.Page

   5: {

   6:     protected void Page_Load(object sender, EventArgs e)

   7:     {

   8:  

   9:     }

  10: }

La clase que use para el ObjectDataSource es la siguiente:

   1: //CategoryManager

   2: using System;

   3: using System.Collections.Generic;

   4: using System.ComponentModel;

   5:  

   6: [DataObject]

   7: public class CategoryManager

   8: {

   9:  

  10:   #region GetAll, getOne

  11:  

  12:   [DataObjectMethod(DataObjectMethodType.Select, true)]

  13:   public List<Category> getAll()

  14:   {

  15:     CategoryRepository catRep = new CategoryRepository();

  16:  

  17:     return catRep.getAll();

  18:   }

  19:  

  20:   [DataObjectMethod(DataObjectMethodType.Select, false)]

  21:   public Category getOneByID(Int32 categoryID)

  22:   {

  23:     CategoryRepository catRep = new CategoryRepository();

  24:     return catRep.getOneByID(categoryID);

  25:   }

  26:  

  27:   #endregion

  28:  

  29:   #region Insert, Update, Delete

  30:  

  31:   [DataObjectMethod(DataObjectMethodType.Insert,true)]

  32:   public void Insert(Category objItem)

  33:   {

  34:     //pendiente de implementacion

  35:   }

  36:  

  37:   [DataObjectMethod(DataObjectMethodType.Update, true)]

  38:   public void Update(Category objItem)

  39:   {

  40:     //pendiente de implementacion

  41:   }

  42:  

  43:   [DataObjectMethod(DataObjectMethodType.Delete, true)]

  44:   public void Delete(Category objItem)

  45:   {

  46:     //pendiente de implementacion

  47:   }

  48:  

  49:   #endregion

  50:  

  51: }

Saludos,

RAD con Oracle Application Express 4.0

Si han tenido la oportunidad de descargar Oracle Express Edition, se han podido percatar  que la herramienta de consulta (QueryAnalyzer o Sql Management Tool) era una interface Web, que además de poder hacer de consultas a las tablas, te permitía crear formularios, reportes, aplicaciones, entre otros, al estilo de lo que se puede hacer con una base de datos Access, esa Web es Oracle Application Express.

Parece que ya no es suficiente con tener versiones Express (Sql Express Edition y Oracle Express Edition), ahora veremos quien avanza más en el terreno de “algo mas”, que en este caso Oracle le lleva ventaja con el Oracle Application Express.

¿Se pueden hacer aplicaciones “serias” con este tipo de herramientas? Con MS Access he visto aplicaciones “serias” estilo ERP, claro con su limitantes, pero en producción y funcionando al fin y al cabo. ¿Imaginen poder hacer lo mismo, pero atrás una base de datos como SQL Server o Oracle?

Recientemente se ha liberado Oracle Application Express 4.0, pueden hacer una evaluación gratuita (crear base de datos, y crear aplicaciones de ejemplo) sin la necesidad de instalar Oracle, usando: apex.oracle.com.

Nuevas funcionalidades de Oracle Application Express 4.0 [] (en ingles para no atarantar con la traducción):

  • Websheets, is a quick and easy way to get content on the web.
  • Dynamic Actions, Users are demanding more user interactivity and client-side functionality whereby the application responds as soon as a value is changed or the user leaves a field.
  • Plug-Ins, allow for the Application Express framework to be readily extended with custom item types, region types, application processes and Dynamic Actions.
  • Team Development, is designed to manage software development.
  • Improved Charting with Gantts and Maps, the underlying charting engine has been upgraded to AnyChart 5.1 which is faster, provides better graphics, and decreases rendering time.
  • RESTful Web Services Support, are becoming more common, especially amongst public Web service providers, as an alternative to SOAP Web Services.
  • Enhanced Interactive Reports, Available since Application Express 3.1, Interactive Reports take much of the burden off developers to produce all the different online reports end-users want by allowing end-users to manipulate the data provided for themselves.
  • Improved Application Builder, has undergone a large overhaul designed to improve navigation and make it faster and easier for developers to create, maintain and enhance Oracle Application Express applications.
  • Better Themes, Application Express provides 20 themes.
  • APEX Listener, is a new Java based listener that can run on a J2EE based Web Server, such as Oracle WebLogic Server or OC4J.

 

Les recomiendo crearse una cuenta, y ver pueden hacer ustedes con esta herramienta, o también para tomar prestada alguna funcionalidad. En mi caso acabo de crear un cuenta, y una opción interesante para crear una tabla (con mantenimiento incluido) es importando información de hoja de calculo:

Y he aquí mi mantenimiento:

 

Además también hay una aplicación ejemplo para poder el poder de esta herramienta:

Saludos,

Publicando Aplicaciones Web Sobre IIS: Web Site, Virtual Directory, y Application

Esta entrada gira alrededor de IIS 6.0, pero los conceptos también se pueden aplicar a IIS 7.0.

Hay un error muy conocido cuando publicamos una aplicación ASP.NET a IIS:

It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level.  This error can be caused by a virtual directory not being configured as an application in IIS.

Si deseamos publicar una aplicación Web ASP.NET sobre IIS 6.0 en Windows Server 2003, debes poder diferenciar tres conceptos: Web Site, Virtual Directory, y Application. Estos términos no los traduciré en los siguientes párrafos, para no generar confusión en la definición de los mismos.

Web Site: Es la ruta base de una aplicación Web, y que se corresponde con un nombre de dominio o una ip de red: http://sergiot2.com, o http://servidorInformes. Por ejemplo, si estamos desarrollando un portal de reportes, y después de publicar nuestra aplicación tenemos que acceder así: http://serv2010/Reportes/, es por que no la hemos publicado a nivel de Web Site. Si la publicamos a nivel de Web Site, debemos poder acceder a la aplicación sólo ingresando la ruta: http://serv2010/. Mas claro el concepto de Web Site?

En IIS podemos tener múltiples Web Sites, y que básicamente se pueden diferenciar por el puerto usado y la carpeta. Por ejemplo, cuando se instala IIS crea un Default Web Site, que apunta a: C:inetpubwwwroot, y apunta al puerto 80. Cuando instalamos SharePoint, este crear varios Web Site, que usan otros puertos, dependiendo de la configuración seleccionada. Otro es caso en la instalación de Reporting Services, que por defecto se instala sólo como un Application dentro de un Web Site.

Web Site - sergiot2.com

 

Virtual Directory: Un “directorio virtual” sirve para mapear una subdirección de un Web Site a otra carpeta. Imaginen que un Web Site de venta de autos, http://crediAutos.com/ alojado en “C:inetpubwwwroot”, que desea usar las imágenes que están en otro disco duro: “F:imageAutos”, si deseamos cargar las imágenes en la siguiente ruta: http://crediAutos.com/images sin mover los archivos físicos, es ahí cuando podemos crear un Virtual Directory dentro del Web Site. Veamos la configuración del siguiente ejemplo:

Web Site Configuraton - Sergiot2.com

Y si lo vemos en el navegador:

Web Site Sample - sergiot2.com

Si colocamos páginas aspx dentro de un Virtual Directory, funcionará siempre y cuando y no tenga un archivo web.config con elementos de aplicación, por llamarlo así. Por ejemplo dentro de un Virtual Directory, que es un sub-directorio de nuestro Web Site, podemos colocar un archivo web.config con el elemento authorization, como se menciona en esta entrada. Pero no podemos colocar un elemento Authentication dentro de un web.config de un Virtual Directoty, debido a que este elemento sólo se permite a nivel de aplicación. De ahí el problema origen.

Si queremos que nuestro Virtual Directory se comporte como una aplicación aparte, es decir tenga un web.config con el elemento Authentication, para poder manejar su propia autenticación distinta al Web Site base, debemos convertir este Virtual Directory en un ASP.NET Application.

 

Application: También podemos llamarlo ASP.NET Application, y se crea de la misma forma que un Virtual Directory, pero con la diferencia de que si puede comportarse como una aplicación ASP.NET independiente, es decir puede tener su propio Application Pool, puede tener su propia versión de ASP.NET y el web.config permite elementos de aplicación como el famoso Authentication del error inicial. Se pueden crear varios ASP.NET Applications dentro de un Web Site, como se muestra en la siguiente figura:

 

Caso de la Vida Real: Un amigo X tenía el problema mencionado al inicio, cuando publico su aplicación ASP.NET en el hosting de otro amigo dueño, por cierto el hosting en mención es dattatec.com. Digamos que el dueño del hosting tenía su aplicación ASP.NET a nivel del Web Site del IIS, es decir: http://todoautos.com.pe, el amigo del dueño tenía una aplicación ASP.NET que quería probar, entonces publico su aplicación como un subdirectorio para no afectar la aplicación del dueño. Pero no funcionaba ninguna aspx, debido al error mencionado arriba. Dentro del panel de control de dattatec (dentro de lo que pude revisar a simple vista) sólo se podía convertir la carpeta del amigo invitado en un Virtual Directory, pero no había ninguna opción para convertirlo en un ASP.NET Application, y seguía el famoso problema del inicio.

La solución pasaría, si es que no hay una opción en el panel del control, mandar un correo al proveedor para que cree el Application manualmente, debe haber un administrador que monitorea los servidores no?.

Consejo: cuando renten un hosting, validen si se pueden crear muchos Virtual Directory y ASP.NET Application, pregunten por los dos por si ellos no tienen claro la diferencia entre los mismos.

Por cierto, un proveedor de hosting no tendría sentido habilitar la creación de Virtual Directory, porque no es lógico que administren carpetas en distintas ubicaciones para el mismo usuario, ¿será que pensaron que una aplicación ASP.NET podía correr en un Virtual Directory? Bueno si alguien tiene su hosting en Dattatec.com, y sabe más del tema, lo comenta por favor.

Lecturas complementarias:

Saludos,

[Apis] Html Agility Pack

Estoy iniciando un proyecto personal, portadas del Perú, cuyo fin es mostrar las portadas de los diarios locales, bajo cierta perspectiva. Hay diarios, por ejemplo elcomercio.pe, donde no hay problema en obtener la imagen de portada: http://e.elcomercio.pe/66/impresa/img/2010/05/10/ecpr100510a1.jpg, claro considerando una determinada hora de publicación. Es fácil identificar que el patrón de la imagen sólo esta determinado por la fecha del día, fácil de determinar con un juego de Strings:

   1:  

   2: String.Format("http://e.elcomercio.pe/66/impresa/img/{0}/ecpr{1}a1.jpg",

   3:               DateTime.Now.ToString("yyyy/MM/dd"), DateTime.Now.ToString("ddMMyy"));

   4: //

Pero otros (varios), como Perú21.pe, donde la imagen de portada tiene un atributo adicional: http://e.peru21.pe/102/impresa/img/2010/05/10/234399.jpg. Además de tener la fecha, tiene un número que imagino debe ser el ID de la imagen, podemos probar http://e.peru21.pe/102/impresa/img/2010/05/10/234400.jpg y http://e.peru21.pe/102/impresa/img/2010/05/10/234401.jpg. Estuve tratando de elaborar un algoritmo para obtener la secuencia de números entre portada y portada, pero no es constante. Además no creo que ellos usen un algoritmo para colocar una imagen en portada, ellos deben tener un campo cómo: “EsPortada”, con lo cuál es sencillo hacer un WHERE: “traer la imagen de portada del día tal”.

Cómo es seguro que no ellos no me van a dar acceso a su BD, la última opción es sacarlo del HTML crudo, última opción debido a que agregamos una variable de dependencia: si ellos cambian el html de su portal, podría provocar que nuestro código ya no funcione. Pero esperemos que esto no suceda muy a menudo.

¿Cómo convertir HTml Crudo, a un modelo de “objetos” html?

Antes usaba WebClient, para leer el html de una página, y era “manual” la búsqueda de elementos dentro del html. Cómo aprendizaje, es correcto empezar por ahí, pero después, es mejor usar la API: “Html Agility Pack”: http://htmlagilitypack.codeplex.com:

What is exactly the Html Agility Pack (HAP)?

This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don’t HAVE to understand XPATH nor XSLT to use it, don’t worry…). It is a .NET code library that allows you to parse “out of the web” HTML files. The parser is very tolerant with “real world” malformed HTML. The object model is very similar to what proposes System.Xml, but for HTML documents (or streams).

En resumen, permite convertir el contenido texto de HTML en un modelo rico de elementos Xml, que son de fácil lectura, por ejemplo, en mi escenario, si quiero recuperar la imagen de portada puedo hacer lo siguiente:

   1:  

   2: public String getImgPeru21()

   3: {

   4:   String imgPortada = ""; 

   5:  

   6:   hap.HtmlWeb docWeb = new hap.HtmlWeb();

   7:   hap.HtmlDocument doc = docWeb.Load("http://peru21.pe/impresa/");

   8:   foreach (hap.HtmlNode img in 

   9:             doc.DocumentNode.SelectNodes("//img[@title]"))

  10:   {

  11:     hap.HtmlAttribute att = img.Attributes["title"];

  12:     if (att.Value.ToLower() == "impresa")

  13:     {

  14:       imgPortada = img.Attributes["src"].Value;

  15:     }

  16:   } 

  17:  

  18:   return imgPortada;

  19: }

Y nada, con ese pequeño código puedo obtener la imagen de portada del diario Perú 21, siempre y cuando el designer no se despierte inspirado y cambie el diseño base, no haya cambios sustanciales en el diseño de la web.

Saludos,

[CodeSnippet] Enviar cuando correo cuando el usuario use Internet Explorer 6 (IE6)

Internet Explorer 6, es una de esas piedritas por la que a veces uno tiene que pensar, ¿damos soporte para IE6 o no?, claro hablando de diseño.

En un proyecto actual para una intranet, hemos decidido no dar soporte para IE6, no estresarnos haciendo diseños web paralelos. IE6, fue lanzado allá por el 2001, y como que ya va siendo hora de ni siquiera mencionarlo cuando definamos los navegadores a soportar por nuestra web. [Extra]: Mató IE6 la marca Internet Explorer??.

Regresando al tema, no vamos a bloquear a los usuarios que ingresen con IE6, lo que vamos hacer es enviar un email a Soporte, para actualizar a los usuarios que aún están usando IE6.

   1:  

   2: public static void ValidarIExplore()

   3: {

   4:   if (HttpContext.Current.Request.Browser.Type.ToUpper() == "IE6")

   5:   {

   6:     String fromEmail = ConfigurationManager.AppSettings["emailAdmin"];

   7:     String toEmail = ConfigurationManager.AppSettings["emailSoporte"];

   8:     String subject = String.Format(

   9:           "[{0}], necesita actualizar internet explorer", 

  10:           HttpContext.Current.User.Identity.Name);

  11:     String message = String.Format(

  12:             @"Sres. de soporte, <br/> El usuario {0} necesita actualizar [...] ",

  13:             HttpContext.Current.User.Identity.Name);

  14:  

  15:     SendEmail(fromEmail, toEmail, subject, message);

  16:   }

  17: }

El método es sencillo, y como tengo una página base para todos mis formularios web, aplico lo siguiente:

   1:  

   2: public abstract class ReportPageBase : System.Web.UI.Page

   3: {

   4:   protected void Page_Load(object sender, EventArgs e)

   5:   {

   6:     //si no esta logueado reenviarlo

   7:     if (!User.Identity.IsAuthenticated) { Response.Redirect("~/login.aspx"); }

   8:  

   9:     //validar browser

  10:     Helper.ValidarIExplore();

  11:     

  12:     //other code

  13:   }

  14: }

Para enviar correos desde ASP.NET, consulte la siguiente entrada.

Saludos,

Ejemplos de base de datos para SQL Server

 Ejemplos de Base de Datos - SQL Server

De vez en cuando, hay la oportunidad de revisar uno que otro proyecto Web ASP.NET disponible en la Web, para aprender de su Know-how. Es una manera rápida para aprender de golpe el desarrollo de aplicaciones Web.

Debido a que pienso usar algunas de estas base de datos, para posts futuros, voy a colgarlas en un nuevo proyecto que estoy usando, Gallery Server PRO (pendiente un post con la revisión de este site).

Las base de datos disponibles que he tenido la oportunidad de revisar, las que recuerdo y que sean open source, son las siguientes:

  1. La archi-conocida, Northwind, que es una especie de modelo ordenes de venta (maestro-detalle), y que puede registrar Productos, Clientes, y Vendedores.
  2. La archi-conocida, Pubs, para editoriales que deseen guardar información de libros, empleados, autores, y la venta de libros. Obviamente no es un modelo complejo, simplifica algunas funcionalidades, pero que puede ser un punto de partida si nos estamos iniciando.
  3. TheBeerHouse, proyecto en CodePlex, que maneja foros, artículos, encuentas, además de ofertar productos a la venta (seguimiento de la orden). Por cierto hay una nueva versión, que incluye este portal usando ASP.NET MVC.
  4. Classifieds, de uno de los tantos Starter Kit, y que básicamente podemos guardar clasificados para anunciarlos en nuestro web, además incluye administración de imagenes por clasificado.
  5. BlogEngine, es conocido motor de blog, y que permite manejar posts, comentarios, categorías, tags, y páginas.

Si quieren descargar los queries para la creación de alguna de estas base de datos, pueden hacerlo desde el siguiente enlace: SQL Server – Base de Datos Ejemplos (Powered by Gallery Server Pro)

P.D.: Si tienen sugerencia de alguna más, me avisan.

P.D.2: Recuerden que siempre es mejor visitar el sitio oficinal para tener la última versión de la base de datos, pero este es mi backup personal para el uso de estas base de datos, además de tener el enlace directo, y no tener que descargar todo el proyecto para tener la base de datos.

Saludos,

[CodeSnippet] Leer archivos ANSI en .Net (cuando C# no lee la enie)

Hace meses comentábamos sobre la integración de sistemas de información, y es que cuando empiezas a interactuar con otros sistemas te das cuenta que no todos trabajan de la misma forma que tu, ni todos usan los mismos estándares. Y lo mismo pasa con la codificación de archivos.

Y parece un tema trivial, pero imaginad que estas cargando unos clientes a tu sistema que vinieron en un archivo con formato ANSI, y alguno de los clientes se apellida Nuñez. En la reuniones de análisis, nunca se determino el formato del archivo. Así que el programador abrió el archivo como siempre le ha funcionado:

   1: using (StreamReader rd = new StreamReader("rutaArchivo")) 

El archivo se cargo exitosamente al sistema, después de unas semanas al cliente le llega su recibo de facturación y su apellido no dice Nuñez, dice Nu?ez.

Seguramente responsabilizaran al programador, por programar “mal”, y bueno, en parte tiene responsabilidad por no preguntar cual era la codificación a usar. Pero también la tiene el analista o persona que no definió correctamente el contrato de servicio para intercambiar información. Se debió especificar que se iba a usar un formato en específico, o hacer que el tipo de codificación sea parametrizable.

Para leer correctamente las cadenas, debemos agregar un atributo al constructor del StreamReader/Writer. Usaremos el siguiente ejemplo, dos archivos con el mismo contenido, pero guardados en distinta codificación:

Archivos ANSI UTF8 - Geeks.ms

   1: //leyendo por defecto

   2: String fileANSI = @"....FilesEjemplo_ANSI.txt";

   3: String fileUTF8 = @"....FilesEjemplo_UTF8.txt";

   4: using (StreamReader rdDefault = new StreamReader(fileANSI))

   5: {

   6:   Console.WriteLine("Usando StreamReader Default para leer ANSI: ");

   7:   Console.Write(rdDefault.ReadToEnd());

   8:   Console.WriteLine("n----------------n");

   9: }

  10: using (StreamReader rdDefault = new StreamReader(fileUTF8))

  11: {

  12:   Console.WriteLine("Usando StreamReader Default para leer UTF8: ");

  13:   Console.Write(rdDefault.ReadToEnd());

  14:   Console.WriteLine("n----------------n");

  15: }

  16:  

  17: //leyendo en ANSI

  18: using (StreamReader rdDefault = 

  19:        new StreamReader(fileANSI, Encoding.GetEncoding(1252)))

  20: {

  21:   Console.WriteLine("Usando StreamReader ANSI para leer ANSI: ");

  22:   Console.Write(rdDefault.ReadToEnd());

  23:   Console.WriteLine("n----------------n");

  24: }

  25: using (StreamReader rdDefault = 

  26:        new StreamReader(fileUTF8, Encoding.GetEncoding(1252)))

  27: {

  28:   Console.WriteLine("Usando StreamReader ANSI para leer UTF8: ");

  29:   Console.Write(rdDefault.ReadToEnd());

  30:   Console.WriteLine("n----------------n");

  31: }     

El resultado será el siguiente:

http://sergiot2.com/blogimages/2010/04Abr/06_CSharp_StreamReader_ANSI.JPG

Descargar solución ejemplo: Leer archivos ANSI desde C#.

Otros artículos referentes a la codificación de los archivos:

Saludos,

ASP.NET WebForms vs ASP.NET MVC, la nueva batalla

ASP.NET Web Forms, basado en armar todo por componentes  ASP.NET MVC - basado en construir todo el renderizado tu mismo

Últimamente los debates de C# o VB.Net quedaron atrás, ahora los nuevos debates dentro del mundillo .Net están entre usar ASP.NET Web Forms o ASP.NET MVC. Imaginen la desorientación sobre el tema, que hasta se dedico una sesión del MIX 2009 a tratar sobre este tema: Choosing between ASP.NET Web Forms and MVC. En los inicios de ASP.NET su principal objetivo era ganar terreno a PHP, JSP, y las otras tecnologías existentes, vendiendo que hacer aplicaciones Web era como hacer aplicaciones Windows, aunque haya un trabajo extra por detrás. Con los años de este Framework el uso de la comunidad ha hecho los Web Forms evolucionen, esfuerzos como reducir el tamaño del ViewState, los CSS Adapters, los Starter Kits, las buenas prácticas, entre otras, han ido mejorando el Framework. De hecho no creo que de Microsoft escuchemos no usen Web Forms, ahora usen ASP.NET MVC, por que por parte de ellos y de la comunidad hubo un gran esfuerzo, y mucho cariño, por hacer que los Web Forms, sean un buen Framework de desarrollo Web.

Antes de empezar quisiera usar y resaltar esta línea de un post de ScottGu relacionado con esta discusión, About Technical Debates (and ASP.NET Web Forms and ASP.NET MVC debates in particular):

“Great developers using bad tools/frameworks can make great apps. Bad developers using great tools/frameworks can make bad apps.”

Al citar esta cifra, creo que deben tener un idea de cual es mi punto de vista. Ahora dividamos el problema, vamos a establecer dos grupos de usuarios para dar nuestros comentarios:

  • Grupo de usuarios experimentados de ASP.NET, que tienen varios proyectos en producción y que no han tenido problemas de rendimiento, tiempo de respuesta, etc, cuando han desarrollado proyectos usando WebForms.
  • Grupo de usuarios nuevos de ASP.NET (y en general nuevos en el desarrollo Web), cuyo primero contacto fue hacer proyectos Web usando ASP.NET, y que no han tenido buenos resultados, han tenido problemas de rendimiento, de tiempo de respuesta, de diseño, y todos los que encontramos en los foros.

Usando el mismo patrón que recomendó Jorge Serrano en este artículo, C# o VB, VB o C#,… la envidia me corroe, si eres un usuario experimentando, no necesitas recomendaciones, sólo revisar las características de ASP.NET MVC y ver si alguna de ellas es la estabas buscando: ASP.NET MVC Overview. Cerramos el tema con ellos, y nos dedicamos a los usuarios nuevos en el desarrollo Web y que van a empezar con ASP.NET.

El problema para los nuevos usuarios, y para los que toman como cierto el mensaje: “Desarrolla Aplicaciones Web como si lo hicieras con Windows Forms, sólo arrastras controles y ya tienes tu Aplicación Web”. Y lo toman literalmente, no necesitan aprender la diferencia entre POST Y GET, no hay porque aprender el significado de QueryString, no es necesario saber si es malo guardar un DataSet en el ViewState de la página, sólo la hago para ya no consultar la base de datos y no tener lenta mi aplicación, no se preocupan en aprender HTML, no se preocupan en aprender JavaScript, entre todas las otras que suelen dejarse de aprender.

Entonces si eres un usuario nuevo en ASP.NET (y si no eres nuevo y no sabes que que usa POST o GET), la recomendación básica es aprender los fundamentos del desarrollo Web:

Estos son WebCasts impartidos por el amigo Jonas Stawski. Es más si pueden traten de hacer pequeñas Web simples usando sólo ASP clásico, verán los resultados y la diferencia cuando después aprendan ASP.NET.

Si ya aprendieron los fundamentos, la elección será más fácil. Por otro lado, tampoco es que ASP.NET MVC cambie totalmente la forma de hacer aplicaciones Web Forms, hay muchas funcionalidades que comparten en un común, la diferencia principal esta en como presentar el fron-ed al usuario, no vamos a entrar en detalles muy técnico por que quizás si fuerzas a cualquier de los dos frameworks puedes lograr la funcionalidad del otro, pero vamos mostrar el siguiente gráfico para mostrar algunas diferencias, y como podemos elegir en que escenario usar uno u otro:

Fuente del gráfico, y otro más detallado.

Como recomendación final, podríamos establecer la siguiente línea para aprender correctamente cualquier de las tecnologías y no caer en las malas practicas:

  • Aprender Html
  • Aprender JavaScript
  • Aprender ASP Clásico
  • Aprender ASP.NET MVC
  • Aprender ASP.NET Web Forms

Aprender al final ASP.Net Web Forms, nos ayudará a entender porque algunas opiniones dicen no usar Web Forms, principalmente por el mágico ViewState que hace que los WebForms sean Stateful, por el contrario de toda la Web que es Stateless.

Otros artículos con algunos detalles de este versus, unos más técnicos que otros:

Saludos,