Buscar este blog

miércoles, 31 de marzo de 2010

Parseando html con HtmlAgilityPack

Con la librería HtmlAgilityPack para .Net es muy sencillo cargar archivos de html y manejar sus objetos programáticamente. Es cierto que también se puede hacer con la clase HtmlDocument de las librerías base de .Net, pero esta clase tiene como ventaja que no necesita una ventana para funcionar por lo que puede usarse en una dll o un ejecutable de consola, además puedes bajar solo lo que necesitas y no el documento con todas sus imágenes y scripts.
Para usarla declaramos una variable de la clase y usamos el método LoadHtml para cargar el documento, el argumento debe ser una cadena conteniendo el html, de momento no se pueden cargar documentos directamente:

HtmlAgilityPack.HtmlDocument doc
                = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(htmlstring);

Una vez que tenemos cargado el html podemos usar sus objetos programáticamente, para encontrar el nodo base del documento (que podria ser html), tenemos la propiedad DocumentNode:

doc.DocumentNode

Para buscar un nodo especifico a partir de otro nodo tenemos el método SelectNodes que toma como argumento una cadena con una expresión de XPath, por ejemplo para encontrar una tabla con ancho de 100%:

doc.DocumentNode.SelectNodes("//table[@width='100%']")[0]

Nótese que tomamos el primer elemento, ya que el método obtiene una colección con todos los elementos que cumplen la condición, alternativamente el método SelectSingleNode que obtiene solo el primer elemento.
Para obtener un elemento en particular de un nodo también podemos usar la colección ChildNodes del nodo la cual contiene todos los elementos directos del nodo:


doc.DocumentNode.SelectNodes("//table[@width='100%']")[0].ChildNodes[1]

En conclusión HtmlAgilityPack es una herramienta muy robusta y útil para lidiar con html, acepta html con errores y nos permite manejarlo de manera similar a Xml.

domingo, 21 de marzo de 2010

Propiedades automaticas

Una característica muy útil de C# es que nos permite declarar propiedades de clase casi sin escribir código simplemente escribimos el tipo de datos y el nombre de la propiedad y listo, si queremos que la  propiedad sea de solo lectura o solo escritura solo se pone como privado el accesor apropiado.
Es muy útil para declarar clases que solo almacenan datos.
Aquí esta el ejemplo:

public class Ejemplo {
        public string Prop1 {
            get;
            set;
        }
        public string Prop2 {
            get;
            private set;
        }
    }

martes, 9 de marzo de 2010

Accesando a un renglon o columna de un TableLayoutPanel

Es muy sencillo acceder a una columna o renglón específicos de un TableLayoutPanel simplemente se accede a ellos por la propiedad RowStyles o ColumnStyles, ambas son colecciones de columnas o renglones.

Por ejemplo para ocultar un renglón:

table.RowStyles[0].Height = 0;

lunes, 8 de marzo de 2010

Obteniendo el tamaño más apropiado para un Label

Los controles label de Windows.Forms tienen un método muy para determinar el tamaño que necesita el control para dibujarse, el método es GetPreferredSize, el método nos devuelve un objeto Size con el ancho y alto adecuados para el control.

Aquí les dejo el ejemplo:

label1.GetPreferredSize(new Size(0, 0));

sábado, 6 de marzo de 2010

Medir el ancho en pantalla de una cadena

Este pequeño truco nos da el ancho en pantalla de una cadena según se vería en un determinado control:

Graphics.FromHwnd(Control1.Hwnd).MeasureString(string1, Control1.Font);

viernes, 5 de marzo de 2010

Pruebas unitarias con Visual Studio

Desde Visual Studio 2005 en algunas versiones tenemos la opción de crear proyectos de pruebas unitarias, para crear un proyecto de este tipo vamos al menú archivo -> Add -> New Project y en el dialogo de nuevo proyecto seleccionamos Test Project como se ve en la imagen:

 
 

Una vez creado el proyecto nos crea una clase de prueba unitaria como ejemplo para usarla añadimos una referencia al proyecto que queremos probar en el que por ejemplo tenemos la siguiente clase:

public class Prueba {
        public int PruebaMiembro {
            get { return 1; }
        }
    }

Para probarla añadimos el siguiente código a la clase demostrativa que creo Visual Studio:

[TestMethod]
    public void TestMethod1() {
        Prueba p = new Prueba();
        Assert.AreEqual(1, p.PruebaMiembro);
    }

y listo.
Podemos correr las pruebas que tengamos, en modo normal o de depuración, y ver los resultados desde el menú de pruebas o desde el panel vista de pruebas (Test View) desde el cual podemos seleccionar solo algunas pruebas o todas como se muestra en la siguiente imagen:


Los resultados se muestran en el panel de resultado de pruebas podemos dar doble click y ver los detalles de la ejecución incluyendo la posición en el código en que fallo en caso de que esto ocurra y si ejecutamos en modo de depuración podemos establecer puntos de ruptura en los que se detiene la ejecución y podemos depurar normalmente.


Para aprender más acerca de las pruebas unitarias con .Net Framework visita:
Lista de artículos acerca de pruebas unitarias con .Net Framework

jueves, 4 de marzo de 2010

Elementos html de servidor

Como sabemos es posible usar cualquier elemento html en asp.net como un control de servidor añadiendo el atributo runat="server" en la etiqueta del control.
Lo que quizá no todos sabemos es que se puede utilizar el atributo InnerText en cualquier elemento de html al que convirtamos en control de servidor, aún cuando intelisense no nos marque el atributo como válido.
De esta forma podemos modificar el contenido del control programaticamente  o usando expresiones.
Aquí esta el ejemplo:

<h1 runat="server" InnerText="<%$ Resources:Labels, Ejemplo %>" />

miércoles, 3 de marzo de 2010

Deteccion de dispositivos mobiles en Asp.Net con libreria de www.51degrees.mobi

Hace unos días que estoy trabajando en la detección de dispositivos móviles con el api que se encuentra disponible en: http://www.51degrees.mobi/Products/NETMobileAPI.
El objetivo es mandar a tus visitas de dispositivos limitados a una pagina diseñada para las características  de un dispositivo reducido.
A primera vista estas librerías se ven muy buenas: son fáciles de usar y ofrecen un soporte muy amplio.
Sin embargo a la hora de ponerlas en producción fallan rotundamente frecuentemente detectan Internet Explorer 6 como móvil y mas frecuentemente ocurre lo mismo con Safari.
Como conclusión en Marzo de 2010 esta api no tiene la robustez necesaria para hacer el trabajo que propone, espero que este articulo le ahorre tiempo a quien este evaluando una api de estas características.

martes, 2 de marzo de 2010

Cómo terminar la sesión de un usuario del Membership provider de asp.net

Para terminar la sesión de un usuario logueado mediante el Membership provider de asp.net, utiliza el siguiente código:

       FormsAuthentication.SignOut()
       Response.Redirect(FormsAuthentication.LoginUrl)


La segunda línea simplemente redirige a la página establecida como inicio de sesión en el archivo web.config de la aplicación.
Otra manera simple de hacerlo es simplemente colocar el tag LoginStatus que automáticamente añade un vínculo para cerrar la sesión.