60
Agregando inteligencia a mis aplicaciones mediante SQL Server Data Mining dedicada a los profesionales de la plataforma .NET www.dotnetmania.com entrevista Michael Howard y Adam Shostack Senior Security Program Managers Microsoft Corp. nº 55 enero 2009 6,50 Visual Basic • C# • ASP.NET • ADO.NET • AJAX • Silverlight • .NET Framework dotNetManía Aplicación del patrón de diseño Acción. Definición de componentes en ASP.NET • HttpHandlers y HttpModules para SharePoint 2007 • Silverlight 2.0 Toolkit. Controles, visualización de datos y mucho más (I) SQL Server Un vistazo a Entity Framework TodotNet@QA Visual Basic ¿lenguaje dinámico? Isla VB Personalizando nuestras builds ALManía Autenticación y autorización en Servicios Web

dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

  • Upload
    doduong

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

Page 1: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Agregando inteligencia a mis aplicaciones mediante SQL Server Data Mining

dedicada a los profesionales de la plataforma .NET

www.

dotne

tman

ia.co

m

entrevistaMichael Howard y

Adam Shostack Senior Security Program Managers

Microsoft Corp.

nº 55 enero 2009 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • AJAX • Silverlight • .NET Framework

dotNetManía

Aplicación del patrón de diseño Acción. Definición de componentes en ASP.NET • HttpHandlers y HttpModules paraSharePoint 2007 • Silverlight 2.0 Toolkit. Controles, visualización de datos y mucho más (I)

SQL Server

Un vistazo a Entity FrameworkTodotNet@QA

Visual Basic ¿lenguaje dinámico?Isla VB

Personalizando nuestras buildsALManía

Autenticación y autorización en

Servicios Web

Page 2: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 3: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Bienvenido al número 55, de enero de2009, de dotNetManía.

Con el ejemplar que tiene ahora ensus manos, terminamos nuestro quintoaño de publicación. Estamos orgullososde esto, pero también somos conscien-tes de que la única forma de mantener-se —caso de que la haya— es seguir tra-bajando duro, manteniendo la tensión yesforzándonos en dar lo mejor de noso-tros mismos, en definitiva, con el mayorrespeto a los lectores y patrocinadoresde esta revista. Cada mes debemosempezar de nuevo con la ilusión del pri-mer número, pero con la experiencia deestos cinco años.

En esta ocasión, hemos tenido la suer-te de poder entrevistar a MichaelHoward y Adam Shostack, Senior Secu-rity Program Managers en MicrosoftCorp. Michael y Adam conversaron connosotros acerca de la seguridad del códi-go que se desarrolla con las herramien-tas de Microsoft hoy en día y del quedesarrollaremos en el futuro también.

Jeffrey Álvarez Massón y MiguelKatrib nos muestran las ventajas que eluso del patrón de diseño Acción ofrecepara el desarrollo de componentesASP.NET en el artículo “Aplicación delpatrón de diseño Acción. Definición decomponentes en ASP.NET”.

Tenemos nuestra dosis de Share-Point con Gustavo Vélez, que en suartículo “HttpHandlers y HttpModu-les para SharePoint 2007” describe las

posibilidades de los manejadores ymódulos HTTP, hasta el momento nodemasiado explotados por los desarro-lladores. Aprovecho la ocasión pararecomendarle la revista online totalmen-te gratuita que Gustavo ha creado y quepublica junto con otras personas enhttp://www.gavd.net/servers/comparti-moss/compartimoss_main.aspx.

El artículo de portada de este mes,“Autenticación y autorización en servi-cios Web con cabeceras y extensionesSOAP”, de Juan Luis Ceada, nos mues-tra cómo interceptar las llamadas a nues-tros servicios Web para tener controlsobre los accesos a ellos y mejorar nosolo la seguridad, sino también la cali-dad del servicio. Así podremos decidirquién, a dónde y cuántas veces puedeacceder a nuestros servicios.

Marino Posadas complementa lainformación publicada en su libro “Pro-gramación en Silverlight 2.0” con suartículo “Silverlight 2.0 Toolkit. Con-troles, visualización de datos y muchomás (I)”, primero de una serie de dos,que describe el nuevo paquete de herra-mientas y controles que complementa alas ya incluidas en el SDK del produc-to, y que se distribuyen bajo licenciapública de Microsoft (Ms-PL), códigofuente incluido, en CodePlex.

Además, encontrará nuestras seccio-nes habituales SQL Server, ALManía eIsla VB. Espero que todo esto sea de suagrado.

Cumplimos 5 años

editorialDedicada a los profesionales de la plataforma .NET

Vol. III •Número 55 • Enero 2009Precio: 6,50 €

EditorPaco Marín ([email protected])

Redactor jefeMarino Posadas([email protected])

RedacciónDino Esposito, Guillermo 'Guille' Som, LuisFraile, Luis Miguel Blanco y Miguel Katrib(Grupo Weboo)

Empresas colaboradoras

Alhambra-Eidos

Krasis

Plain Concepts

Raona

Solid Quality Mentors

Además colaboran en este númeroEnric Forn, Francisco González, GustavoVélez, Jeffrey Álvarez, Juan Luis Ceada yMagda Teruel.

Diseño y maquetaciónSilvia Gil (Letra Norte)

Atención al suscriptorPilar Pérez ([email protected])

Edición, suscripciones y publicidad.netalia

c/ Robledal, 13528522 - Rivas Vaciamadrid (Madrid)

www.dotnetmania.com

Tf. (34) 91 666 74 77Fax (34) 91 499 13 64

ImprimeGráficas MARTE

ISSN1698-5451

Depósito LegalM-3.075-2004

dotNetManíadotNetManía

Paco Marín

Page 4: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

sumario 55Entrevista a Michael Howard y Adam Shostack 10-12

Michael Howard y Adam Shostack, reconocidos expertos en temas relacionados con la seguridad,pasaron por Barcelona con motivo del reciente Tech-Ed 2008, que tuvo lugar a mediados denoviembre. Además de impartir algunas sesiones, tuvieron un rato para entrevistarse condotNetManía y hablarnos sobre ese aspecto tan importante para el software de hoy.

Aplicación del patrón de diseño Acción. Definición de componentes en ASP.NET 14-19En este artículo se propone un nuevo enfoque para la representación de acciones como componentesen aplicaciones visuales, y se muestran las múltiples ventajas que este enfoque proporciona a travésde su aplicación práctica al desarrollo de formularios Web ASP.NET.

HttpHandlers y HttpModules para SharePoint 2007 20-24Este artículo describe las posibilidades que ofrecen los manejadores HTTP (HttpHandlers) y losmódulos HTTP (HttpModules) de ASP.NET, y cómo pueden utilizarse estos mecanismos paraimplementar funcionalidades avanzadas en sitios de SharePoint 2007.

Autenticación y autorización en servicios Web con cabeceras y extensiones SOAP 26-35En ocasiones es necesario tener un control exhaustivo de los accesos que se producen a nuestrosservicios Web (quién accede, a dónde y cuántas veces), tanto por seguridad como para mantener lacalidad del servicio. En este artículo veremos cómo podemos cumplir estos requisitos interceptando lasllamadas realizadas por los clientes a nuestra plataforma de servicios Web.

Silverlight 2.0 Toolkit. Controles, visualización de datos y mucho más (I) 36-39En paralelo con la presentación de la versión final de Silverlight 2.0, se anunciaba en las webs“oficiales” de la plataforma la intención de mejorar el desarrollo mediante la publicación paulatinade nuevos controles y herramientas que potencien las posibilidades de creación de aplicaciones RIAcon Silverlight, al tiempo que se anticipaban algunas características de la versión 3.0, que segúnScott Guthrie estará disponible a finales de 2009. Vamos a revisar aquí algunas de las posibilidadesque ofrece el último paquete de herramientas, publicado a primeros del pasado mes de diciembre.

Agregando inteligencia a mis aplicaciones mediante SQL Server Data Mining 40-43La minería de datos se puede utilizar para analizar información y realizar predicciones. En esteartículo voy a ilustrar el uso de la minería de datos en una aplicación Web. Vamos a tomar los datosde venta de un portal Web y cierta información de nuestros clientes para analizar qué productosofrecer a determinados perfiles de clientes, realizar campañas publicitarias u ofrecer productos quesean comprados conjuntamente cuando un cliente agrega un producto a la cesta de la compra.

Personalizando nuestras builds 44-48En muchas ocasiones, en el momento en que generamos la versión de nuestra aplicación nos dejamosel último ensamblado añadido, la modificación del fichero de configuración, o los PDB generados seencuentran en modo Debug. Team Foundation Build nos ayuda a simplificar estas tareas,mejorando el versionado de nuestros proyectos.

Visual Basic ¿lenguaje dinámico? 50-53En la próxima versión de .NET Framework (la 4.0) se incluirá lo que se conoce como DLR(Dynamic Language Runtime), que viene a ser el motor de ejecución de los lenguajes dinámicos de.NET. De esa forma, se permitirá al CLR (y por extensión a los lenguajes como VB y C#) el accesode forma dinámica a los miembros de los objetos que haya en memoria, algo parecido a lo quesiempre se ha conocido como late binding... o casi...

dnm.todotnet.qa 54-56Un vistazo a Entity Framework

dnm.biblioteca 57ADO.NET Entity Framework. Aplicaciones y servicios centrados en datosApplication Architecture Guide 2.0: Designing Applications on the .NET Platform

dnm.desvan 58

Page 5: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 6: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Para promover una mayor interoperabilidad entre las apli-caciones de productividad, Microsoft publicó este 16 dediciembre la documentación que detalla su implementacióndel soporte para OASIS Open Document Format (ODF)versión 1.1 en Microsoft Office 2007 SP2, actualmente enfase beta y prevista para su liberación el próximo año. Notassimilares relativas a la implementación de Open XML (Ecma376 Edición 1) en Office aparecerán en las próximas sema-nas. Esta información se seguirá actualizando en la medidaen que los productos cambien a lo largo del tiempo y a par-tir de las sugerencias de los usuarios.

Estas notas de implementación ofrecen una guía com-pleta de cómo Microsoft está implementando ODF y OpenXML dentro de la suite Office. Las notas, disponibles gra-tuitamente en el sitio Web de la Document Interoperabi-lity Initiative (DII), en http://www.documentinteropinitiati-ve.org, serán de suma utilidad a los desarrolladores que bus-quen mejorar la interoperabilidad de sus soluciones con losproductos de Microsoft, e igualmente constituirán un inte-resante recurso de aprendizaje. Las notas contienen:

•Detalles sobre decisiones de implementación. Alimplementar un estándar, el implementador puede encon-trar el texto ambiguo o más permisivo de lo que seríaapropiado para una implementación particular. En talescasos, el implementador debe tomar la decisión que mejorsatisfaga sus necesidades. Este tipo de información per-mite a los desarrolladores ver qué dirección está siguien-do un fabricante y tomar decisiones informadas sobre suspropios esfuerzos de interoperabilidad.

•Detalles sobre datos adicionales incorporados a losficheros. Los estándares de formatos de ficheros típica-mente permiten almacenar en los ficheros informaciónadicional específica de las aplicaciones (por ejemplo, cier-tas personalizaciones). Suministrando esta información,

los fabricantes permiten a los desarrolladores interpre-tar correctamente esos datos adicionales.

•Detalles sobre las desviaciones en la implementa-ción. En cualquier aplicación se pueden presentar casosen que un implementador no puede seguir exactamenteel estándar por una u otra razón. En tales casos, es impor-tante que los fabricantes documenten exhaustivamentesu enfoque, de manera que otros fabricantes puedan tomardecisiones informadas sobre cómo enfocarán su imple-mentación.

La estandarización es un primer paso importante haciala interoperabilidad, pero se necesita más trabajo adicionalpor parte de los fabricantes para alcanzar ese objetivo:

•Seguimiento compartido de la evolución de los están-dares por parte de los cuerpos correspondientes. Micro-soft tiene el compromiso de participar activamente en laevolución de los estándares ODF, Open XML, XPS yPDF; ha contribuido a ODF en OASIS y colabora en elmantenimiento de Open XML en ISO/IEC.

•Transparencia. Los fabricantes deben ser transparentesal implementar estándares en sus propios productos. Publi-cando estas notas de implementación, Microsoft está ayu-dando a otros desarrolladores y fabricantes a tomar deci-siones informadas a la hora de crear sus productos.

•Colaboración. Los fabricantes deben colaborar con otrosfabricantes para identificar y resolver las "colisiones delmundo real" que surjan entre implementaciones, y crearherramientas y soluciones para mejorar la interoperabi-lidad a lo largo del tiempo. Microsoft llevará a cabo alre-dedor del mundo sesiones de trabajo de DII y otras acti-vidades para promover la colaboración entre fabricantesy, en definitiva, el intercambio efectivo de datos entreimplementaciones de estándares de formatos de datos.

dotN

etM

anía

<<

6

noticiasnoticias

noticias

noticias

noticias

Microsoft da pasos concretos hacia la interoperabilidad

Con el objetivo último de pro-mover el desarrollo de aplica-ciones basadas en las últimastecnologías de interfaz deusuario de Microsoft, losorganizadores del conocido

evento MIX han creado un concurso bajo el lema “Ins-pire al mundo con solo 10K”. Se trata de desarrollar

una aplicación Silverlight o WPF para navegador cuyocódigo fuente y recursos embebidos no sobrepasen entotal los 10 KB. El ganador obtendrá un pase gratuitopara el evento MIX ’09 que se celebrará en Las Vegasentre el 18 y el 20 de marzo, además de tres noches dehotel y una tarjeta Visa con 1.500 dólares.

Para más información y las bases del concurso, visi-te http://2009.visitmix.com/MIXtify/TenKGallery.aspx.

Concurso “Inspire al mundo con solo 10K”

La empresa promueve la transparencia publicando las notas de implementaciónde ODF y Open XML

Page 7: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

7

<<dnm.directo.noticias

Hace unos días, Microsoft liberó unabeta pública de BizTalk Server 2009,conjuntamente con módulos destina-dos a simplificar los despliegues RFID.Se trata de la primera versión públicapara pruebas de la plataforma de inte-gración basada en Arquitecturas orien-tadas a servicios (SOA) de Microsoft.Se espera que la versión definitiva sealanzada durante la primera mitad de2009, según Burley Kawasaki, Direc-tor de la División de Sistemas Conec-tados de Microsoft.

"Es una versión completa en lo querespecta a características", dijo Kawasa-ki. "Estamos buscando recibir mucho másfeedback sobre el producto como parte desu terminación". La beta está disponiblepara su descarga para los clientes actua-les de BizTalk suscritos al programa Soft-ware Assurance.

BizTalk Server 2009 soporta losproductos más recientes de la platafor-ma Microsoft, principalmente la ver-sión de Windows CommunicationsFoundation (WCF) incluida en .NETFramework 3.5 SP1, además del sopor-te completo para Visual Studio 2008SP1 y las ediciones más recientes deSQL Server y Windows Server.Además, soporta nativamente Hyper-V y ofrece clustering mejorado, mejo-ras en la tolerancia a fallos y adaptado-res e interfaces de integración con hostadicionales. Igualmente se brindasoporte para un nuevo registro basadoen las especificaciones de UDDI 3.0.

Para las organizaciones dedicadas aldesarrollo, BizTalk Server 2009 ofrece

nuevas posibilidades para la gestión delCiclo de vida de las aplicaciones median-te el soporte para Team Foundation Ser-ver, que permitirá a los equipos de pro-gramadores aprovechar la gestión decódigo, seguimiento de fallos e integra-ción de builds que éste ofrece. Los desa-rrolladores que lleven a cabos desarrollosa medida basados en .NET podránconectarse a BizTalk y mapear cualquie-ra de los artefactos que BizTalk gestionaen sus aplicaciones, como si de códigofuente se tratara.

Como parte de la versión liberadahoy, Microsoft también ha liberado Biz-Talk RFID Standards Pack y RFIDMobile. El primero es un módulo de ser-vidor de BizTalk que soporta los princi-pales estándares RFID, incluyendo RagData Translation (TDT) y Low LevelReader Protocol (LLRP). El segundofunciona bajo Windows Mobile y dispo-sitivos basados en Windows CE. RFIDMobile ofrece una API común para todoslos dispositivos que ejecuten Microsoft.NET Compact Framework y para la ges-tión remota de esos dispositivos.

Finalmente, Microsoft ha liberadotambién una CTP de la versión actuali-zada de Enterprise Service Bus Gui-dance 2.0, que incluye nueva documen-tación y prácticas recomendadas para eldesarrollo de aplicaciones basadas enSOA. "Estamos aprovechando algunas delas nuevas posibilidades de Visual Studioy añadiendo nuevas herramientas visua-les que permitan definir y actualizar topo-logías de bus de servicios dentro de VisualStudio", dijo Kawasaki. También haentrado en funcionamiento un nuevoportal Web "que permite a los desarro-lladores agregar publicadores o suscrip-tores al bus sin necesidad alguna de desa-rrollo personalizado. Es un modelo deautoservicio".

Microsoft libera primera betade BizTalk Server 2009Se libera conjuntamente con módulos destinados asimplificar los despliegues RFID

Disponible actualización para.NET 3.5 SP1

El pasado día 20 fue puesta a dispo-sición del público una actualizaciónpara .NET Framework 3.5 SP1. Estaactualización corrige problemasdetectados en .NET 2.0 SP2, .NET3.0 SP2 y .NET 3.5 SP1 desde suaparición. Puede descargar e instalarlos paquetes correspondientes(específicos para las distintas combi-naciones de procesador y sistema ope-rativo) desde http://support.micro-soft.com/kb/959209.

Nuevo portal sobre capacitacióntecnológica de Alhambra-Eidos

Como parte de la línea de continuoreforzamiento de su área de Formación,Alhambra Eidos pone en marcha sunuevo portal temático sobre capacita-ción tecnológica en las líneas tecnoló-gicas que son de su especialidad: desa-rrollo de software, sistemas avanzados,comunicaciones y telefonía, así comosobre los distintos aspectos de seguri-dad comunes a todas ellas.

El acceso a dicho portal puede rea-lizarse a través de www.formaciontic.com.En él se podrá encontrar datos relati-vos a la oferta de formación de la com-pañía, información sobre novedadestecnológicas y anuncios de interés paraaquellos que deseen mantener al día suscapacidades técnicas.

Entre las primeras informacionesrelevantes que pueden consultarse seencuentran las relativas a los nuevoscursos y seminarios de alta especializa-ción sobre desarrollo seguro, expe-riencia de usuario, Visual Studio 2008,virtualización, etc. Los interesados tam-bién encontrarán allí todo lo relativo alplan de formación subvencionada parapartners de Microsoft, ya que Alham-bra Eidos ha sido una de las compañíasseleccionadas para impartir dicho plandurante el curso 2008-2009.

Page 8: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

8

dnm.directo.noticias<<

A principiosde diciembre,el equipo quese encarga delos sitios para

desarrolladores Channel 8, 9 y 10liberó el motor de blogs y gestión decontenidos conocido como Oxite, quepuede obtenerse en el sitio de Code-Plex http://www.codeplex.com/oxite. Oxi-te fue desarrollado originalmente parael sitio Web del evento MIX(http://www.visitmix.com) y se apoya,como cabría esperar, en ASP.NETMVC y SQL Server. Esta herramien-ta viene a suplir, según sus creadores,la ausencia hasta el momento de ejem-plos de gran calado basados enASP.NET MVC, y se suministra concódigo fuente bajo el modelo de licen-cia Ms-PL, ofreciendo así a los desa-

rrolladores el derecho a incorporarOxite en sus propios productos.

El proyecto, deliberadamente, noestá orientado a usuarios finales, sinoa desarrolladores. Aunque Oxite ofre-ce todas las características que un sis-tema de blogs debe soportar (feeds RSS,moderación de comentarios, pingbacks,etc.) carece de las características de ins-talación y configuración sencillas querequiere el software para usuarios fina-les, utilizando en vez de eso Visual Stu-dio Web Developer Express para esastareas. La idea de Microsoft es que losdesarrolladores se basen en Oxite paracrear sus propias aplicaciones de blogso CMS. Se trata, sin embargo, de unproyecto de la comunidad, por lo quesi ésta lo convierte en un producto másorientado a los consumidores, Micro-soft no interferirá.

Microsoft libera Oxite para los desarrolladores

Desde el pasado 16 de diciembre estádisponible el Service Pack 3 (SP3) deSQL Server 2005, así como la Actua-lización acumulativa (CumulativeUpdate) 11 para SQL Server 2005SP2. Según la compañía, el SP3 inclu-ye mejoras en el motor de bases dedatos, así como en los servicios dereplicación, Notification Services yReporting Services; adicionalmente,contiene todas las actualizaciones deseguridad y corrección de errores apa-recidas anteriormente. Para aquellosclientes que opten por no aprovecharlas nuevas posibilidades, la Actualiza-ción acumulativa contiene únicamen-te los hot fixes.

La versión más general del SP3 deSQL Server 2005, aplicable a las edi-ciones Enterprise, Developer, Standard

y Workgroup, puede descargarse des-de: http://www.microsoft.com/downlo-ads/details.aspx?FamilyID=ae7387c3-348c-4faa-8ae5-949fdfbe59c4.

Por otra parte, SQL Server 2005SP3 Express está disponible aquí:http://www.microsoft.com/downloads/details.aspx?familyid=3181842A-4090-4431-ACDD-9A1C832E65A6.

Y SQL Server 2005 SP3 Expresswith Advanced Services aquí:http://www.microsoft.com/downloads/details.aspx?familyid=B448B0D0-EE79-48F6-B50A-7C4F028C2E3D.

Al mismo tiempo, Microsoft haliberado versiones actualizadas al nivelSP3 de las extensiones opcionales queforman parte del Feature Pack paraSQL Server 2005. Puede descargaresas extensiones aquí: http://www.micro-soft.com/downloads/details.aspx?Famil-y ID=536fd7d5-013f-49bc-9 f c7-77dede4bb075.

Disponible SP3 de SQL Server 2005 Liberado IronPython 2.0

A principios de diciembre, JasonZander anunció la disponibilidad deIronPython 2.0, una implementacióndel lenguaje Python diseñada paraejecutarse sobre la plataforma .NET,poniendo todas las librerías de .NETa disposición de los programadoresPython y manteniendo al mismotiempo compatibilidad total con laversión estándar del lenguaje.

La novedad esencial incorporadaen esta versión es que IronPythonfunciona ahora sobre el DynamicLanguage Runtime (DLR), un motorde ejecución genérico para lenguajesdinámicos que se ejecuta sobre elCLR y hace posible la interoperabi-lidad de múltiples lenguajes dinámi-cos a nivel del sistema de tipos.

Para más información y descar-gas (incluyendo el código fuente), visi-te http://www.codeplex.com/IronPython.

Presentada Galería de diseñosde ASP.NET MVC

Hace unos días, Microsoft publicóuna nueva galería de diseños paraaplicaciones basadas en la arqui-tectura ASP.NET Model-View-Controller. Esta galería aloja plan-tillas de diseños de sitios Web queel usuario puede descargar y utili-zar en sus desarrollos. Cada plan-tilla de diseño incluye un ficheroSite.master, una hoja de estilosCSS y, opcionalmente, un con-junto de recursos y código desoporte.

Cualquiera puede “subir”nuevos diseños a la galería, quefunciona bajo licencia bajo licen-cia Creative Commons. Visítelaen http://www.asp.net/mvc/gallery/default.aspx.

Page 9: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 10: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

entrevista

Magda Terueles Team Leader de

Raona. Magda esMCPD Windows

Developer.http://www.magda.es.

Luis Fraile es MVP deTeam System y cola-bora activamente enMAD.NUG (Grupode usuarios de .NETde Madrid). Actual-mente es director

técnico en Multido-mo Networks. Pue-

de con sul tar sublog en

www.lfraile.net.

Senior Security Program Managers en Microsoft Corp.

entrevista a

Michael Howard y Adam Shostack

Michael Howard y Adam Shostack,reconocidos expertos en temas rela-cionados con la seguridad, pasaronpor Barcelona con motivo delreciente Tech-Ed 2008, que tuvolugar a mediados de noviembre. Ade-más de impartir algunas sesiones,tuvieron un rato para entrevistarsecon dotNetManía y hablarnos sobreese aspecto tan importante para elsoftware de hoy.

Magda Teruel y Luis Fraile

¿Qué opináis del panorama actual del softwareque se hace actualmente? ¿Es suficientementeseguro?

Michael Howard: En lo que respecta a Micro-soft, y con la incorporación de SDL (Secure Deve-lopment Lifecycle), sí. A través de SDL, tenemosdesde 2004 procesos estrictos de seguridad, paratodos y cada uno de los productos expuestos a Inter-net o bien productos destinados a empresas. Detodas maneras, ahora es más fácil aplicar prácticasde seguridad y privacidad a nuevos productos por-que no hay que preocuparse de dar un soporte here-dado. En mi opinión, y respondiendo a vuestra pre-gunta, los nuevos productos de Microsoft sonmucho más seguros que los antiguos.

Page 11: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

¿Y a nivel de la industria?Michael: La industria tiene un gran

camino por recorrer. Hoy en día elfoco de ataques está en los productosde terceros, y estos ataques provocangrandes pérdidas a las empresas. Paraayudar en esto, estamos externalizan-do nuestro modelo de automatización.SDL nos ha servido a nosotros ennuestros productos (SQL Server, Offi-ce, Windows), por lo que lo ofrecemosa la industria como herramienta paraque sus productos sean también másseguros.En cuanto a los productos de Micro-soft que requieren desarrollo porparte de los partners (BizTalk, Sha-rePoint), ¿cuál es la estrategia?

Michael: La postura es clara: Micro-soft y Bill Gates nos dicen “Lo hare-mos, no importa cuánto cueste”, perono sabremos lo que harán los partners.Para ponérselo más fácil, externaliza-mos nuestras buenas prácticas, reco-mendaciones y las lecciones que hemosaprendido. Y además les damos unaherramienta para hacerlo.Recientemente se está haciendomucho hincapié en campos como laUX. ¿No estamos olvidándonos dela seguridad?

Adam Shostack: No. Estamosempezando a aprender todos. Antes, laseguridad era cosa de especialistas sola-mente. Obviamente, la experiencia deusuario es importante, si la gente noquiere usar nuestro software, tenemosun problema. Pero poco a poco la segu-ridad (en unos dos años) empezará atener un papel relevante, y se hablaráde seguridad como se habla ahora deinterfaces de usuario.¿Y qué está haciendo Microsoft parapopularizar la seguridad?

Michael: Ciertamente, hoy porhoy la seguridad es una materia deexpertos, pero no debería serlo, tieneque formar parte del proceso. Ahoraque subimos a la nube, y todo el mun-do pone su software al alcance detodos, es importante introducir laseguridad como parte importante dela metodología.

¿Qué hay del software en la nube?Sin duda, lanza nuevos retos encuanto a seguridad.

Michael: Sí, son numerosos y dis-tintos los retos que, por ejemplo, Win-dows Azure debe afrontar respecto aWindows 7. Cada uno de ellos ha pasa-do por SDL, pero tenemos requisitosespecíficos confeccionados para cadaproducto, así como elementos comu-nes como el modelado de amenazas(threat modeling), aplicables tanto aWindows Azure como a Windows 7.¿Y hay algo en concreto que hayarecibido una especial atención?

Adam: Sí, sin duda. Desde 2006, SDLha incluido requerimientos específicos deseguridad y privacidad para los serviciosonline. De hecho, los requerimientos deseguridad de SDL comprenden y seexpanden a lo largo de múltiples fases deldesarrollo, y están diseñados para miti-gar problemas comunes de las aplicacio-nes Web, como por ejemplo la inyecciónde SQL o las vulnerabilidades XSS.

Michael: También el modelado deamenazas se considera absolutamentecrítico en tecnologías como WindowsAzure y Live Mesh.Ahora con VS2010 tenemos nuevasherramientas de testing, comoCamano, que nos facilitan las tare-as relacionadas con las pruebas(fallos no reproducibles, etc.). ¿Seestá pensando en herramientas quepermitan realizar pruebas de segu-ridad relacionadas con la inyecciónde SQL u otros ataques?

Michael: No, de momento solo sedispone de herramientas de terceros. Laspruebas son importantes, pero son solouna parte de la solución. Hemos hechograndes progresos para construir algúntipo de herramienta de pruebas de aspec-tos de seguridad, como fuzz testing (untipo de prueba que consiste en proveerel sistema con datos aleatorios), y hemospublicado código fuente para que losdesarrolladores puedan generar este tipode pruebas. Algunas partes del testeo deseguridad pueden ser automatizadas,pero hoy en día el estado del arte es toda-vía muy inmaduro.

Hay mucho movimiento respecto aALM (metodologías, buenas prácti-cas, etc.). ¿Cómo veis la integraciónde SDL en este contexto?

Michael: Es completamente necesa-rio que los fabricantes de software tratenlas amenazas de seguridad y privacidadconvenientemente. Construir y preser-var una mayor confianza en el mundo dela informática significa que todos los fabri-cantes de software deben incorporarrequisitos de seguridad y privacidad ensus productos para mitigar las amenazas.

Adam: Para la industria del softwa-re, las buenas prácticas y la formaciónayudan, pero la clave para mejorar laseguridad y la privacidad es implemen-tar procesos repetibles que aportenavances medibles. Se necesitan proce-sos así para minimizar el número de vul-nerabilidades de seguridad en diseño,código y documentación, y para detec-tar y eliminar esas vulnerabilidades tantemprano en el ciclo de vida como seaposible. Y la necesidad es mayor parael software de empresa o consumo queprocesa datos recibidos de Internet,para controlar sistemas críticos con peli-gro de ser atacados o para procesarinformación personal identificable.

Michael: En Microsoft, es muyimportante que añadamos herramientasde seguridad y prácticas a los métodosactuales de desarrollo, y éste es el foco denuestro grupo. Pero todavía estamos enun proceso temprano, y necesitamosinvertir más tiempo y esfuerzo.Falta madurez en el proceso,entonces.

Adam: Mejorar la seguridad de lasaplicaciones implica muchos compo-nentes, desde comprender las amenazas,requerimientos de diseño, herramientasde desarrollo, herramientas de pruebasy reducir la superficie de ataque. No hayuna fórmula mágica. Para cumplir contodos estos requisitos, Microsoft formaa todos sus desarrolladores, testers, y pro-gram managers en el desarrollo de códi-go más seguro, y siempre trata de man-tener el número de vulnerabilidades deseguridad al mínimo a través del proce-so de SDL.

dotN

etM

anía

<<

11

dnm.directo.entrevista<<

Page 12: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

12

dnm.directo.entrevista<<

Michael: Cuando preguntan cuán-tos expertos en seguridad tenemos enMicrosoft, la respuesta es 6.500. Esdecir, cada ingeniero posee los conoci-mientos y habilidades necesarios parala seguridad, y esto va en aumento: cadavez nuestro conocimiento es mayor.

Adam: Y aunque cada vez sabemosmás, es importante poder prescindir delrol de experto en seguridad, y que cadaingeniero sea capaz de tener una madu-rez mínima en cuanto a seguridad.¿Entonces vamos a integrar SDLcon el resto de herramientas dedesarrollo?

Michael: De momento no, quiénsabe si en un futuro… Por ahora, y comoprimer paso, vamos a proporcionar herra-mientas cómodas que faciliten la inte-gración de la seguridad. Para ello hemoscreado la herramienta Threat ModelingTool (http://msdn.microsoft.com/en-us/security/dd206731.aspx).

Siempre está cuestionada la seguri-dad de los productos de Microsoft.Como parte del equipo de seguri-dad, ¿cuál es vuestra percepción?

Michael: ¡Estoy de acuerdo! Hemoshecho increíbles progresos en los últi-mos años, y ahora estamos compar-tiendo nuestra experiencia para quetodo el mundo pueda aplicar nuestras

prácticas. Si se mira una gráfica tem-poral, el número de vulnerabilidades vadisminuyendo sustancialmente en cadaversión.¿Entonces en unos años no habrávulnerabilidades?

(risas) Michael: Para ser honestos, lacota de cero vulnerabilidades es inalcan-zable. Pero la tendencia es a la baja, sinduda. Por ejemplo, las vulnerabilidadesde red están ahí, y están para todos lossistemas, pero hemos conseguido trans-formarlas de críticas a solamente impor-tantes. SDL pretende reducir el númerode vulnerabilidades en nuestro software,y está demostrado que introducir la segu-ridad y la privacidad en el código desdelos inicios nos ha permitido mejorar nota-blemente nuestro software. Es algo de loque estamos muy orgullosos.

Al menos, hay que agradecer que eltiempo de reacción sea corto.

Michael: Sí, aunque hay que mirarla foto completa. Es muy fácil detectarun bug y alarmarse.Siempre hay el dedo que señala.

Adam: Sí, y queremos evitar losdedos acusadores. En Microsoft se haapostado por hacer una inversión realen seguridad. De hecho, la gran mayo-ría de los anuncios recientes estánorientados a informar de que se presta

gran atención a resolver los problemasde seguridad.Para finalizar, habladnos del futurode SDL.

Michael: Últimamente me pregun-tan esto a menudo. Yo soy un eternooptimista. Y esto es crítico cuando tra-bajas en seguridad para Microsoft (risas).El último informe de Security Intelli-gence (http://www.microsoft.com/secu-rity/portal/sir.aspx) indica que hay quedar un paso más, que la industria debecambiar su forma de pensar. Cada vezlo hacemos mejor, sacamos más y másversiones y aunque no son perfectas, soncada vez más buenas. Si me hubieranpreguntado hace cinco años, no hubie-ra pensado que íbamos a hacer el pro-greso que hemos hecho, y creo que ven-drán todavía más mejoras en los próxi-mos cinco años. ¿Hacia dónde va la tendencia?

Michael: Vamos a ver un mayormovimiento destinado a proveer mássoporte específico para la Web. Yahemos hecho mucho con respecto aesto, pero es un panorama bastanteincierto, y vamos a poner más recur-sos en esta área. También van a apare-cer muchas más herramientas. Y situviera que desear una sola cosa, meencantaría ver la seguridad como par-te habitual de la entrega de softwareen todos los proveedores. En esta mis-ma línea, me gustaría ver que fuera deMicrosoft los equipos empiezan aimplementar SDL en sus organizacio-nes. Con los ataques dirigiéndose haciala capa de aplicación, es incluso máscrítico que los desarrolladores de soft-ware protejan a sus clientes embe-biendo seguridad y privacidad en susproductos.

Hablando con clientes y partners,hay un interés bastante significativo enadoptar SDL. Algunas compañías yahan implementado procesos alineadoscon los de SDL, y con nuestro esfuer-zo para compartir nuestras herramien-tas con la industria, confío en que cadavez más se irán añadiendo.

Michael Howard

Adam Shostack

Page 13: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 14: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Reducir al mínimo el código fuente

Hasta el momento, las tecnologías de componentesse han dirigido a la implementación de funcionali-dades generales que no dependen de las reglas deun negocio en particular. Una vez que el progra-mador entiende cómo utilizar un componente, esta-blece un “contrato” con él y debe ser capaz de adap-tarlo a sus necesidades propias. Este artículo se cen-tra en el desarrollo de un tipo de componentes paraASP.NET que interactúan con otros ya existentespara darles un significado semántico. Esto se hace apartir del patrón de diseño Acción o Comando.

El primer ejemplo en el que se utiliza el patrónde diseño Comando (Command), también común-

mente llamado Acción (Action), apareció en unartículo de Lieberman en 1985. MacApp, ET++,InterViews y Unidraw definen clases que sigueneste patrón; para más detalles, ver [1]. Chris Lasa-ter explica el patrón y ofrece una implementaciónen C# [2], y Alex Homer [3] lo usa en ASP.NET,aunque no desde el enfoque de componentes.

Este patrón (figura 1) consiste en encapsularcomo un objeto la solicitud de ejecutar cierta fun-cionalidad, permitiendo parametrizar a los clien-tes con peticiones diferentes, poner en cola las peti-ciones y soportar operaciones de deshacer [1]. Laprincipal utilidad de este patrón consiste en quemuchas veces es necesario realizar una operacióncuya implementación, invocador y receptor pue-

Aplicación del patrón de diseño AcciónDefinición de componentes en ASP.NET

En este artículo se propone un nuevo enfoque para la representaciónde acciones como componentes en aplicaciones visuales, y se muestranlas múltiples ventajas que este enfoque proporciona a través de su apli-cación práctica al desarrollo de formularios Web ASP.NET.

Figura 1: Diagrama del patrón Acción o Comando. Tomado de [1].

Jeffrey Álvarez MassónMiguel Katrib

plataforma.net

Miguel Katrib es doctor yprofesor jefe de programa-ción del departamento de

Ciencia de la Computa-ción de la Universidad deLa Habana. Miguel es líderdel grupo WEBOO, dedi-

cado a la orientación aobjetos y la programaciónen la Web. Es redactor dedotNetManía y asesor dela empresa DATYS Tec-

nología y Sistemas.

Jeffrey Álvarez Massón esestudiante de la Maestría

en Ciencia de la Computa-ción de la Universidad de laHabana y colaborador delgrupo WEBOO. Es desa-

rrollador .NET de laempresa DATYS Tecno-

logía y Sistemas.

Page 15: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

15

dnm.plataforma.net<<

den cambiar en tiempo de ejecución.Por ejemplo, se tiene una tabla con datosproducidos por una consulta SQL y sedesea ocultar columnas u ordenar poruna de ellas. El invocador puede ser elmanejador de un evento de botón o decasilla de verificación, el receptor es lacolumna de la tabla que se desea ocul-tar o por la que se va a ordenar, y laacción puede ser ocultar u ordenar.

Acciones contra manejadores de eventosTeniendo en cuenta este patrón y las ven-tajas que ofrece para el desarrollo decomponentes la tecnología ASP.NET[4], en el presente trabajo se considerarála implementación de una acción comoun componente visual que tendrá aso-ciado una funcionalidad específica (unapetición) cuya ejecución se desembocaráa través de un evento. Por ejemplo: enuna página Web, se desea hacer una pre-gunta de sí o no al usuario a través deque éste haga clic en un determinadobotón. Si el usuario responde sí, se leredirecciona a otra página. Si la respuestaes no, permanece en la página actual.Una implementación típica incluiría unafunción script en la página Web y unainvocación de la función. Si tenemos quehacer muchas preguntas de esta natura-leza, habrá que incluir la función, modi-ficar parámetros y adicionar manejado-res de eventos cada vez. Sin embargo, sise cuenta con un control de ASP.NETque se encargue de ello mediante lageneración automática de JavaScript enel cliente, previa configuración de pro-piedades, se acelera considerablementeel trabajo.

La acción no debe considerarse uncontrol de usuario (user control). Su obje-tivo no es personalizar una interfaz deusuario, sino asociar operaciones a loseventos de controles que ya tienen unainterfaz definida; se deja a cargo delprogramador de la acción definir a quéevento(s) se asociará la ejecución de laacción; por ejemplo, al evento Click dealgún botón.

El proceso de adicionar una acciónen el diseñador Web de Visual Studio

o de cualquier otro ambiente de desa-rrollo debe ser el siguiente:

1. Se busca en las acciones existentesen las bibliotecas de acciones paracomprobar si existe alguna con lafuncionalidad deseada. En caso afir-mativo, la acción encontrada searrastra del cuadro de herramientashacia el área de diseño donde seencuentran los demás componentes.

2. Se establecen —siempre en tiempode diseño— las propiedades de laacción necesarias para que ésta fun-cione correctamente.

3. Se garantiza que la acción sea ejecu-tada en algún evento de la aplicación(inicio de sesión, ocurrencia de unerror), de un control (clic en unbotón, cambio de selección en uncombo), de la página (Load, Init), etc.

4. Se colocan en orden las acciones en lapágina, ya que si se asignaran dos o másacciones al evento Click del mismobotón, podría ser importante tener encuenta que la acción que aparece antesen la página se ejecutará primero.

Al convertir el patrón Acción en uncomponente para ASP.NET, se crea unaentidad declarativa, visiblemente seme-jante a un caso de uso. A través de ella,se pueden relacionar actores, opera-ciones y receptores, tanto en tiempo dediseño como en ejecución. Esto ofrecemayor flexibilidad para cambiarlos enel momento necesario.

Implementación del patrónAcción Se llamará A ctionBase (listado 1) a la cla-se base de todas las acciones, que cons-ta de los siguientes miembros:

• Método público Execute. Como sunombre indica, ejecuta la petición,operación o lógica programada en laacción.

• Método público virtual Undo. Desha-ce la operación realizada. Si no es posi-ble deshacer, se lanza una excepciónNotSupportedException (éste es el com-portamiento predeterminado).

using System;using System.ComponentModel;

namespace Weboo.Web.UI.WebControls {public abstract class A ctionBase : Control {public A ctionBase() : base() { }

public sealed void Execute() {CancelEventHandler be = BeforeExecute;if (be != null) {CancelEventA rgs args = new CancelEventA rgs();be(this, args);if (args.Cancel)return;

}InternalExecute();if (A fterExecute != null) {A fterExecute(this, new EventA rgs());

}

public virtual void Undo() {throw new NotSupportedException();

}protected abstract void InternalExecute();

public event CancelEventHandler BeforeExecute;public event EventHandler A fterExecute;

}

}

Listado 1: La clase ActionBase

Page 16: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

16

dnm.plataforma.net<<

• Método protegido y abstracto Inter-nalExecute. Debe ser implementadopor las clases herederas para prove-er al control de su funcionalidadcorrespondiente.

• Evento BeforeExecute. Se dispara antesde ejecutar la acción. A través de esteevento, el programador puede can-celar la ejecución de la acción en casode que ello sea conveniente.

• Evento A fterExecute. Se dispara des-pués de ejecutar la acción. Median-te este evento se puede hacer algúntratamiento posterior a la ejecuciónde la acción, como deshacer o incor-porar lógica adicional.

Las acciones que hereden de A ction-Base no pueden reemplazar al métodoExecute. El implementador de unaacción concreta lo que debe es heredarde A ctionBase y redefinir el método abs-tracto InternalExecute, que como es pro-tected no puede ser llamado directa-mente por un cliente, sino solo a travésde Execute.

Aunque un código cliente de un tipoderivado de A ctionBase podrá invocarexplícitamente al método Execute, estono es lo que se pretende. Una vez quese han establecido correctamente laspropiedades de una acción en tiempode diseño, ésta debe ser capaz de regis-trar sus propios métodos en un eventode cualquier control, ya sea un clic deun botón, un cambio de selección enun control de lista, etc. Es el códigomanejador del evento el que debe lla-mar entonces a Execute.

Eventos en el cliente y en elservidor

En el desarrollo de componentesWeb ASP.NET, una de las característi-cas más importantes a tener en cuentaes que tenemos dos tipos de eventos: losde cliente (navegador) y los de servidor.Por un lado, los scripts o segmentos decódigo interpretado (JavaScript, VB -Script, etc.) son los encargados del fun-cionamiento de los controles en el nave-gador sin provocar llamadas al servidor;y por el otro, a través de envíos de infor-

using System;using System.ComponentModel;using System.Web.UI.WebControls;using System.Web.UI;using System.Reflection;

namespace Weboo.Web.UI.WebControls {public abstract class ButtonA ction : A ctionBase { public ButtonA ction() : base() {}

[Description("ID del botón que ejecutará la acción."),DefaultValue(""),TypeConverter(typeof(WebControlIDConverter)),WebControlIDFilter(typeof(IButtonControl))]public string ButtonID {get {string o = ViewState["ButtonID"] as string;return (o == null) ? String.Empty : o;

}

set {ViewState["ButtonID"] = value;

}}

protected void SetClientClick(WebControl button) {if (!(button is IButtonControl))throw new A rgumentException("El control con ID = '" + ButtonID +

"' no implementa la interfaz IButtonControl.");Type buttonType = button.GetType();PropertyInfo propClientClick =

buttonType.GetProperty("OnClientClick");string functionCode = "javascript:" + GetClientEventScript() +

((!this.ContainsServerCode) ? "; return false;" : "");try {if (propClientClick== null)button.A ttributes["onclick"] = functionCode;

elsepropClientClick.SetValue(button, functionCode.ToString(),

new object[] { });}catch (Exception ex) {throw new InvalidOperationException(

"La propiedad OnClientClick del control " +ButtonID + " no se pudo cambiar. ", ex);

}}

protected virtual string GetClientEventScript() {return null;

}

protected void SetServerClick(WebControl button) {if (!(button is IButtonControl))throw new A rgumentException("El control con ID = '" + ButtonID + "' no implementa la interfaz IButtonControl.");

IButtonControl ib = (IButtonControl) button;ib.Click += new EventHandler(HandleClick);

}

protected virtual void HandleClick(object sender, EventA rgs e) {this.Execute();

}}

}

Listado 2: Implementación en C# de una acción asignable a un botón de ASP.NET

Page 17: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

17

dnm.plataforma.net<<

mación convenientemente oculta en lapágina, se reportan vía HTTP comoeventos al servidor [5].

El código del listado 2 muestra unaimplementación para una acción asig-nable a un botón de una página WebASP.NET (note que la acción es a suvez abstracta, porque no se ha dado nin-guna implementación particular almétodo InternalExecute).

Para mayor brevedad, las imple-mentaciones del convertidor de tipo (typeconverter) WebControlIDConverter y del atri-buto WebControlIDFilterA ttributehan sidoomitidas. Un convertidor de tipo, enpocas palabras, permite convertir unobjeto de tipo X en una representación

de tipo Y. Por ejemplo, existen converti-dores para transformar números a cade-nas y viceversa. Asociando un converti-dor de tipo a través del atributo TypeCon-verterA ttribute a una propiedad de uncontrol (Windows Forms o ASP.NET)se pueden obtener valores posibles paraasignar a la propiedad cuando ésta se con-figura en la rejilla de propiedades deVisual Studio. En el paso 3 de la figura2, puede notarse cómo el usuario ha ele-gido “Button1” de una lista de valoresposibles de la propiedad ButtonID. Web-ControlIDConverter permite obtener unalista de los ID de controles presentes enla página Web, mientras que WebContro-lIDFilterA ttribute le indica al converti-

dor de qué tipos deben ser los controlespara ser incluidos en dicha lista.

El método SetClientClick permiteincluir en el elemento HTML del botónque se usará para ejecutar la acción elatributo onclick cuyo valor será la lla-mada a la función JavaScript (obtenidamediante GetClientEventScript), quedeberá ser implementada en una cade-na con el código de la función y regis-trada a través del método Page.ClientScript.RegisterClientScriptBlock por losherederos de esta clase.

Por su parte, el método SetServer-Click, según la forma tradicional en C#para registrarse a eventos, incluye unallamada a Execute en el evento Click delbotón.

Como se puede apreciar, algunas delas ventajas de esta implementación sonla posibilidad de ejecutar la acción tan-to en el cliente como en el servidor yel registro automático de los métodosde la acción en los eventos del objetoinvocador.

Una acción para borrar el contenido de formulariosWeb

Como ejemplo de aplicación de lapropuesta de este artículo, presenta-remos una acción real para limpiar(poner en blanco el contenido de cua-dros de texto y anular la selección enlos controles de selección como Drop-DownList, ListBox, etc.) un formularioWeb. Como se muestra en la figura 2,tal acción se arrastra desde el cuadrode herramientas al área de diseño dela página, y se le asocia un botón paraejecutarla; en este caso, habrá tambiénque asociarle el control contenedor(por ejemplo, un panel) cuyo conte-nido se quiere limpiar (vaciando loscontroles que éste contiene). Por últi-mo, se decide si la acción se ejecutaráen el cliente o en el servidor (propie-dad ServerSide).

Como se puede observar, en estecaso es en el método OnLoad donde sellama a los métodos encargados deregistrar la acción en el evento Click delFigura 2: Pasos para adicionar y configurar la acción Limpiar en Visual Studio .NET

La posibilidad de ejecutar la acción tanto en el cliente como en el servidor y el registro automáticoen los eventos del objeto invocador son ventajas

de esta implementación

Page 18: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

18

dnm.plataforma.net<<

botón. Si además el evento se procesaen el cliente, se llama al método Regis-terScriptCode para registrar el códigoJavaScript que garantizará la operación.En este caso InternalExecute solo se eje-cutará si la propiedad ServerSide es true.Note que es este método quien invocaal método RecursiveClear para limpiarlos controles.

Se ha hecho también una redefi-nición (override) de GetClientEventS-cript para personalizar la llamada a lafunción script registrada con el ID delcontenedor a limpiar. Por ejemplo, siFunctionName es igual a Clear y Contai-nerID es Panel1, este método devolveráClear('Panel1').

Por último, tenga en cuenta queel método FindControl de la clase Con-trol busca en el contenedor de nom-bres actual (naming container) un con-trol con el ID especificado comoparámetro [4]; sin embargo, enmuchas ocasiones esto no es suficientepara encontrar un control, así que laclase Util (que no se ha incluido pormotivos de espacio, pero puede des-cargarse del sitio Web de dotNet-Manía) incluye una versión estáticade FindControl que si no encuentra elcontrol en su naming container subeun nivel hacia arriba en la jerarquíade contenedores, repitiendo la bús-queda hasta llegar al nivel de la ins-tancia de Page. Si a pesar de todo elcontrol no se encuentra, el métododevuelve null.

using System;using System.Text;using System.Web.UI;using System.ComponentModel;using System.Web.UI.WebControls;using System.Drawing;

namespace Weboo.Web.UI.WebControls {[DefaultProperty("ContainerID"),ToolboxBitmap(typeof(A ctionBase), "A ction.bmp")]

public class A ctionClear : ButtonA ction {public A ctionClear() {ViewState["FunctionName"] = "Clear";this.ServerSide = false;

}

[Description("Indica si los controles se limpian " +"actualizando sus propiedades en el servidor (true) " +"o en el cliente (false)."),

DefaultValue(false)]public bool ServerSide {get {return (bool)ViewState["ServerSide"];

}set {ViewState["ServerSide"] = value;

}}

[Description("ID del control contenedor en el que se encuentran " + "los controles que se limpiarán."),DefaultValue(""),TypeConverter(typeof(A ssociatedControlConverter))]public string ContainerID {get {string o = ViewState["ContainerID"] as string;return (o == null) ? String.Empty : o;

}set {ViewState["ContainerID"] = value;

}}

[Description("Nombre de la función script cliente " +"que ejecuta la acción de limpiar."),

DefaultValue("Clear")]public string FunctionName {get {string o = ViewState["FunctionName"] as string;return (o == null) ? String.Empty : o;

}set {ViewState["FunctionName"] = value;

}}

protected override void OnLoad(EventA rgs e) {base.OnLoad(e);Control button = Util.FindControl(this, this.ButtonID);if (button == null)return;

if (ServerSide)SetServerClick(button);

else {SetClientClick(button);RegisterScriptCode();

}}

Hasta el momento, enASP.NET las acciones se

habían implementado comoobjetos a los que se hacíanpeticiones a través de unmétodo como Execute

Page 19: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

19

dnm.plataforma.net<<

Conclusiones

Hasta el momento, en ASP.NET lasacciones se habían implementado comoinstancias de objetos a las que se hacíanpeticiones a través de un método comoExecute. Los parámetros, como el recep-tor, se asignaban a propiedades desdeel código. Con este nuevo enfoque dela acción en forma de componente deASP.NET se obtienen las siguientesventajas:

• Solo hay que colocar el códigoimprescindible –es decir, el que espropio para cada página- en codebehind. Todas las funcionalidades dela página se programan una sola vezen las acciones, lo cual conduce a unamayor facilidad de mantenimientodel código fuente.

• El funcionamiento de la página pue-de definirse completamente en tiem-po de diseño.

• Mayor modularidad, reusabilidad yextensibilidad para incorporar nue-vas funcionalidades a las páginas.

• Facilidad para indicar que las accio-nes se ejecuten en el navegador, enel servidor o en ambos.

• La creación de páginas WebASP.NET desde Visual Studio pue-de realizarse sin muchos conoci-mientos de la tecnología.

La aplicación de este enfoque aotros patrones de diseño, como Obser-vador (Observer) o Publicación-Sus-cripción (Publish-Subscribe) [3], asícomo Fábrica Abstracta (Abstract Fac-tory), Constructor (Builder) [1] y otrospueden aumentar las capacidades dedesarrollo para definir y utilizar com-ponentes en ASP.NET.

protected override void InternalExecute() {Control control = Util.FindControl(this, ContainerID);if (control == null)throw new InvalidOperationException(

String.Format("Control con ID = {0} no encontrado.", ContainerID));

RecursiveClear(control);}

private void RecursiveClear(Control control) {if (control is TextBox)((TextBox)control).Text = String.Empty;

elseif (control is ListControl)((ListControl)control).ClearSelection();

elseforeach (Control current in control.Controls)RecursiveClear(current);

}

private void RegisterScriptCode() {Type pageType = Page.GetType();if (!Page.ClientScript.IsClientScriptBlockRegistered(

pageType, FunctionName)) {Page.ClientScript.RegisterClientScriptBlock(pageType,

FunctionName, String.Concat("<script language=\"javascript\">","function ", FunctionName, "(id) {"," var c = document.getElementById(id);"," for (i = 0; i < c.all.length; i++)"," if ((c.all.item(i).tagName == \"INPUT\" &&"," c.all.item(i).type == \"text\") || "," c.all.item(i).tagName == \"TEXTA REA \")"," c.all.item(i).value = \"\"; "," else if (c.all.item(i).tagName == \"SELECT\" &&"," c.all.item(i).options.length > 0)"," c.all.item(i).options[0].selected = true; ","}</script>")

);}

}

protected override string GetClientEventScript() {string idControl = this.ContainerID;if (ServerSide) {Control container = Util.FindControl(this,

this.ContainerID);if (container == null)throw new A rgumentException("El control con ID = '" +

ContainerID + "' no se encuentra.");idControl = container.ClientID;

}return String.Format("{0}('{1}')", FunctionName, idControl);

}}

}

Listado 3: Acción que limpia el contenido de un formulario Web.

BibliografíaGamma, Erich, et al. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley Longman, 1998.

Lasater, Christopher G. CodeProject. Design Patterns: Command Pattern. Free source code and programming help. Enhttp://www.codeproject.com/KB/books/DesignPatterns.aspx, 2006.

Homer, Alex. Design Patterns for ASP.NET Developers. Part 3: Advanced Patterns. En http://www.devx.com/dotnet/A rti-cle/34220/1763, 2007.

Microsoft Developer Network for Visual Studio 2005. Microsoft, 2005.

MacDonald, Matthew y Szpuszta, Mario. Pro ASP.NET 2.0 in C# 2005. Apress, 2005. págs. 67-69.

[1]

[2]

[3]

[4][5]

Page 20: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

En el principio de los tiempos, solamente existíaHTML. HyperText Markup Language (HTML)fue rápidamente aceptado, y constituye hoy en díala base de todo tipo de aplicaciones Web. PeroHTML solamente permite mostrar contenidoestático, lo que rápidamente fue visto como unalimitación seria para el desarrollo de tecnologíasWeb. Los desarrolladores necesitan mecanismospara que las aplicaciones Web sean dinámicas ypermitan generar contenido a partir de bases dedatos o siguiendo las preferencias de los usuarios.Por esta razón, los fabricantes de servidores Webcomenzaron a crear tecnologías complementariaspara garantizar el desarrollo dinámico en la Red:Microsoft creó la Internet Server API (ISAPI) parasu Internet Information Services (IIS), que tam-bién fue adoptada por Apache, y Netscape desa-rrolló NSAPI (Netscape Server API) con el mis-mo objetivo.

ISAPI consta de dos mecanismos principales:las extensiones y los filtros:

• Las extensiones no son más que aplicacionesnormales que se pueden hacer ejecutar median-te una solicitud Web. La parte más conocidade las extensiones ISAPI es la cadena de con-sulta (query string) que aparece al final de unURL en la forma de un signo de interroga-ción seguido de al menos una asociación pará-metro-valor, éstos últimos separados entre símediante el símbolo “&” (por ejemplo,

http://Servidor/default.aspx?param1=valor1&param2=valor2).

• Los filtros son lo que la palabra indica: algoque destila y modifica la información entrela solicitud y la respuesta Web.

Trabajar programáticamente con ISAPI nunca hasido fácil por su complejidad: hay que utilizar directa-mente los compiladores de la familia Win32, y el desa-rrollo tradicionalmente solo ha sido posible con C/C++.Para aliviar este problema, ASP.NET ofrece los mane-jadores HTTP (HttpHandlers) y los módulos HTTP(HttpModules):

• Los manejadores HTTP pueden ser vistoscomo un equivalente de las extensiones ISA-PI, y a nivel de programación son compo-nentes que implementan la interfaz Sys-tem.Web.IHttpHandler.

• De forma similar, los módulos HTTP pue-den ser comparados con los filtros ISAPI,e implementan la interfaz System.Web.IHttp-Module.

El funcionamiento de SharePoint 2003 sebasaba completamente en un filtro ISAPI espe-cialmente diseñado para manejar el enrutamientode las solicitudes Web. Esto producía algunosefectos colaterales, como por ejemplo que el ser-vicio IIS estaba totalmente “secuestrado” porSharePoint, impidiendo el funcionamiento de

HttpHandlers y HttpModulespara SharePoint 2007

Sharepoint

Gustavo Vélez es ingenie-ro mecánico y electrónico,especializado en el diseño,desarrollo e implementa-

ción de software (MCSD)basado en tecnologías deMicrosoft, especialmenteSharePoint. Es creador y

webmaster dehttp://www.gavd.net/ser-

vers, y trabaja como seniordeveloper en Winvision(http://www.winvision.nl)

Este artículo describe las posibilidades que ofrecen los manejadoresHTTP (HttpHandlers) y los módulos HTTP (HttpModules) de ASP.NET,y cómo pueden utilizarse estos mecanismos para implementar funcio-nalidades avanzadas en sitios de SharePoint 2007.

Gustavo Vélez

Page 21: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

21

dnm.servidores.sharepoint<<

otras aplicaciones Web en el mismoservidor. En la versión 2007 de Sha-rePoint, el filtro ISAPI ha sido susti-tuido por manejadores y módulos,garantizando de esta manera la com-patibilidad con ASP.NET y liberandoel servicio IIS. Otra gran ventaja esque ahora disfrutamos de un modeloabierto: el desarrollador puede crearsus propios módulos para implemen-tar tareas específicas de un determi-nado portal utilizando C# o VisualBasic.

HttpHandlers para SharePoint 2007Para crear un manejador HTTP paraSharePoint 2007, comience por crear unnuevo archivo con la extensión .ashx enel directorio C:\A rchivos de progra-ma\A rchivos comunes\Microsoft Sha-red\Web server extensions\12\TEMPLA -TE\LA YOUTS. El código de ejemplo que sepresenta en el listado 1 (basado en unapresentación de Ted Pattison) escribeen pantalla un texto establecido en elcontexto de la página.

Después de agregar una referenciaal ensamblado de SharePoint y heredarde la interfaz IHttpHandler, se imple-mentan la propiedad IsReusable y elmétodo ProcessRequest de la interfaz.En éste último se crean objetos SPSitey SPWeb basados en el contexto para mos-trar un texto informativo. El métodoIHtttpHandler.ProcessRequest recibecomo parámetro el HttpContext de lapágina, de tal forma que la propiedadResponse de éste pueda ser utilizado paraescribir en la pantalla.

Este es un ejemplo muy sencillo, peroútil para mostrar el funcionamiento deun manejador HTTP. El tipo MIME dela respuesta que se va a generar (Con-tentType) es “text/plain” en el ejemplo,pero podría utilizarse cualquier otro tipo,como XML, flujos binarios (por ejem-plo para devolver imágenes), Adobe PDFo cualquier tipo de documento de Offi-ce. La extensión .ashx es reconocida pordefecto por IIS como correspondiente aun manejador HTTP, pero se puede uti-lizar cualquier otra extensión que sedesee, siempre que se la registre comotal en la sección httpHandlers de web.con-fig o machine.config.

SharePoint se encarga de compilarel código en el momento de ser utili-zado, por lo que no es necesario gene-rar ni instalar DLL alguna. El archivotampoco es guardado en memoria, porlo que tampoco es necesario ejecutarun IISRESET después de modificarlo.

El ejemplo mostrado podría habersido desarrollado prácticamente con elmismo código usando una página .aspxtradicional. La ventaja de un manejadorHTTP reside en la posibilidad de hacerreconocer extensiones propias en IIS, yde interpretarlas y mostrarlas en pantallautilizando un tipo específico de transfor-mación (definido por la propiedad Con-tentType). De esta manera es posible, porejemplo, enviar directamente al navega-dor documentos PDF o implementaralgún tipo de contenido propio.

HttpModules para SharePoint 2007Los módulos HTTP permiten imple-mentar una funcionalidad más generalque la de los manejadores HTTP. Ladiferencia fundamental entre ellos dosradica en que los módulos se ejecutanpara todas las solicitudes, sean del tipoque sean, sin importar la extensión con-creta de la URL que se esté solicitan-do ni el manejador HTTP que será uti-lizado para satisfacerla. Esto abre laspuertas a crear código que siempre rea-lice alguna actividad en el sistema.

Formalmente, la interfaz IHttpMo-dule que deben implementar los módu-los consta solamente de dos métodos,Init y Dispose. En Init se implementala inicialización del módulo, y el méto-do recibe como parámetro una refe-rencia al contexto (objeto HttpA pplica-tion) que representa a la aplicación Weben ejecución. Típicamente, en estemétodo se “enganchan” manejadorespara los eventos globales de la aplica-ción, como BeginRequest, EndRequest,A cquireRequestState, A uthenticateRequesto A uthorizeRequest. Normalmente, loseventos más interesantes son BeginRe-quest y EndRequest, que permiten actuar,respectivamente, sobre la solicitud delusuario antes de que SharePoint la pro-

<%@ WebHandler Language=”C#” Class=”HolaHttpHandler” %><%@ A ssembly Name=”Microsoft.SharePoint, Version=12.0.0.0,

Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

using System;using System.Web;using Microsoft.SharePoint;

public class HolaHttpHandler : IHttpHandler{

public bool IsReusable{

get { return false; }}

public void ProcessRequest(HttpContext context){

SPWeb miSitio = SPContext.Current.Web;context.Response.ContentType = “text/plain”;context.Response.Write(“HolaHttpHandler desde el sitio “ +

miSitio.Title + “ en “ + miSitio.Url);}

}

Listado 1

Page 22: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

22

dnm.servidores.sharepoint<<

cese, y sobre la respuesta una vez queestá lista para ser enviada de regreso.

El ejemplo más sencillo de módu-lo HTTP que se puede pensar es unoque genere la misma respuesta paratodas las solicitudes al sistema. Porsupuesto que éste es un ejemplo bas-tante poco útil en la vida práctica, peroque podría utilizarse para, por ejem-plo, presentar una página de avisocuando el portal esté en manteni-miento. Recuerde que el módulo seejecutará para todas las solicitudes, sinimportar el tipo de URL que utilicecualquier usuario; la respuesta siem-pre será la página de mantenimiento.El código de este módulo se muestraen el listado 2.

Como se puede observar, en el méto-do de inicialización hemos añadido alevento BeginRequest del contexto delmódulo un delegado asociado al métodoEmpezarSolicitud, que se deberá ejecutarcuando dicho evento se dispare. En elcuerpo de EmpezarSolicitud se transfierela llamada a nuestra página de manteni-miento. El método Dispose, por supues-to, es indispensable de ser implementa-do, y deberá contener el código necesa-rio para liberar cualesquiera recursos quepudieran haber sido adquiridos en Init.

El ensamblado resultante de compi-lar este proyecto (de tipo “Class Library”)deberá ser firmado con un nombre segu-ro y copiado al directorio Bin de la apli-cación Web respectiva en IIS (por ejem-plo, C:\Inetpub\wwwroot\wss\VirtualDi-rectories\80\bin). En realidad, podríainstalarse también en la GAC; pero paralimitar el alcance de un ensamblado a unadeterminada aplicación Web es preferi-ble situarlo en el directorio Bin. Para hacerque SharePoint reconozca el módulo, lalínea que se muestra en el listado 3 (sus-tituyendo los valores adecuados para elnombre, tipo y clave pública) debe seragregada al archivo web.config de la apli-cación Web en IIS, bajo la sección Http-Modules.

Como podrá observar, en la secciónHttpModules del archivo web.config Sha-rePoint ya tiene configurados algunosmódulos por defecto: caché, autenti-cación, autorización y manejo de roles.

El orden en que se coloquen los ele-mentos de esta sección es esencial parael funcionamiento de SharePoint (laautenticación tiene que ocurrir antesque la autorización, y ésta última antesde poder asignar roles), y debe sermantenido, a riesgo de alterar el fun-cionamiento interno de SharePoint.Normalmente, un módulo propio sedebe registrar al final de la sección,pero no es una regla obligatoria: en elcaso de la página de mantenimiento,es posible que se decida que la auten-ticación y autorización no son necesa-rias, pues el sistema de todas formasno estará en funcionamiento, y por lotanto el módulo HTTP se podría colo-car al principio de la sección.

Otra aplicación típica de los módu-los es utilizar el evento A fterRequest paramodificar la respuesta que SharePointenvía al usuario para mostrar ciertainformación en todas las páginas delportal (un pie de página o un texto mos-trando las condiciones de uso), comose muestra en el listado 4.

En este ejemplo, se está agregandoun manejador al evento EndRequest delmódulo para modificar el códigoHTML que SharePoint ya ha genera-do. El método TerminarSolicitud a su

using System;using System.Web;namespace HttpModulo_01{

public class Class1 : IHttpModule{

public void Init(HttpA pplication context){

context.BeginRequest += new EventHandler(EmpezarSolicitud);}

private void EmpezarSolicitud(object sender, EventA rgs e){

HttpContext.Current.Server.Transfer(“/_layouts/mantenimiento.html”, false);

}

public void Dispose(){}

}}

<add name=”HttpModulo_01” type=”HttpModulo_01.Class1, HttpModulo_01,Version=1.0.0.0, Culture=neutral, PublicKeyToken=97bc1af85e70ceb9” />

Listado 2

Listado 3

El orden de los elementos dela sección HttpModules de

web.config es esencial para elcorrecto funcionamiento de

SharePoint

Page 23: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

23

dnm.servidores.sharepoint<<

vez suministra, mediante HttpRespon-se.WriteSubstitution, un delegado aso-ciado al método EscribirTexto, que esquien genera el texto necesario. Elresultado se puede ver en la figura 1.

Con respecto al funcionamiento delmódulo, hay que señalar que el pie depágina estará situado detrás de las eti-quetas </BODY></HTML> del códigoHTML generado. Para el objetivo de

un pie de página, el resultado es el espe-rado; pero aunque los navegadoresmodernos podrán mostrar el texto sinproblemas, este código no es conformea las especificaciones de w3.org. Proba-blemente la mejor solución sea obte-ner toda la respuesta HTML a travésde un flujo, modificarla por medio deuna concatenación o una expresiónregular y enviar la respuesta modifica-da. El propósito del ejemplo es mos-trar cómo utilizar un módulo en Sha-rePoint; los detalles de implementaciónpueden ser especificados de acuerdocon las necesidades particulares. Tam-bién hay que tener en cuenta que el tex-to del pie de página debería ser alma-cenado fuera del módulo, de manera deque cuando se desee modificar el textono sea necesario recompilar el código.

Aunque los eventos BeginRequest yEndRequest sean los más “populares”,hay otros eventos que pueden ser uti-lizados, y a veces es obligatorio usarlos.Es el caso de que se quiera cambiardinámicamente la página maestra: enesta situación, es imprescindible utili-zar el evento PreRequestHandlerExecute,que se dispara precisamente antes deque ASP.NET empiece a generar lapágina; si se utiliza otro evento, la pági-na maestra ya habrá sido mezclada conel contenido y no será posible cam-biarla. Un ejemplo de esto se presentaen el listado 5.

Note que las posibilidades de estemódulo son realmente extensas: en unainstalación por defecto, SharePoint per-mite definir una sola página maestra porcolección de sitios, y dicha página es con-figurada para todos los usuarios de lacolección. Los temas son una forma decrear alguna personalización de páginasdentro de la colección, y permiten per-sonalizar la configuración por cada usua-rio; pero los cambios que se pueden hacercon los temas están limitados a las modi-ficaciones a realizar mediante estilos deCSS. Con un módulo HTTP de estetipo, se puede modificar radicalmente laspáginas en base a grupos de usuarios oinclusive usuarios individuales, permi-tiendo que cada grupo tenga una inter-faz completamente diferente, no solovisual, sino también funcionalmente.

using System;using System.Web;

namespace HttpModulo_02{

public class Class1 : IHttpModule{

public void Init(HttpA pplication context){

context.EndRequest += new EventHandler(TerminarSolicitud);}

private void TerminarSolicitud(object sender, EventA rgs e){

HttpA pplication miHttp = (HttpA pplication) sender;miHttp.Context.Response.WriteSubstitution(

new HttpResponseSubstitutionCallback(EscribirTexto));}

private static string EscribirTexto(HttpContext context){

return “Este es un pie de página”;}

public void Dispose(){}

}}

Listado 4

Figura 1: Texto de pie de página en todas las páginas del portal

Page 24: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

24

dnm.servidores.sharepoint<<

Continuando con los eventos quepueden ser utilizados, otro ejemplo demódulo HTTP que puede mejorar elfuncionamiento de SharePoint es unoque permita generar una página conmejor información para el usuariocuando ocurre un error en el sistema.SharePoint muestra por defecto unapágina que indica solamente que haocurrido un error, sin dar mayor infor-mación al respecto. Un módulo, por elhecho de ejecutarse en todas las con-sultas que pasan a través de IIS, está encapacidad de interceptar cualquiererror que pueda ocurrir y actuar enconsecuencia, como se muestra en ellistado 6.

En el manejador de eventos MiErrordel módulo se recorren una por unatodas las excepciones que se han pro-ducido, creando entradas en el Visorde sucesos de Windows. Luego se eli-minan los errores en el contexto y seredirige a una página especial. Estapágina puede mostrar los mensajes deerror, por ejemplo, e indicar que accióna realizar, si es necesario. Para el regis-tro se generan aquí entradas muy sen-cillas, pero por supuesto en la vida realse debe incluir toda la informaciónsobre el error para facilitar su repro-

ducción y corrección. Igualmente, loserrores se podrían almacenar en unabase de datos u otro sistema de archi-vo (inclusive dentro de una lista de Sha-rePoint), y se podría ejecutar otrasacciones, como enviar un e-mail aladministrador del sistema.

ConclusiónLos manejadores HTTP y los módu-los HTTP nos permiten aumentar laflexibilidad y manejabilidad de Share-Point 2007. Desafortunadamente, has-ta el presente han sido relativamentemuy poco explotados, pero por su faci-lidad de programación y por la canti-dad de situaciones en las que puedenser aplicados, constituyen dos herra-mientas que siempre hay que tener enmente cuando se esté trabajando pro-gramáticamente con SharePoint.

using System;using System.Web;using System.Web.UI;namespace HttpModulo_03{

public class Class1 : IHttpModule{

public void Init(HttpA pplication context){context.PreRequestHandlerExecute += new EventHandler(CambiarSolicitud);

}

private void CambiarSolicitud(object sender, EventA rgs e){

Page Page miPagina = HttpContext.Current.CurrentHandler as Page;if (miPagina != null)

miPagina.MasterPageFile = “~/Master1.master”;}

public void Dispose(){}

}}

Listado 5

using System;using System.Diagnostics;using System.Web;

namespace HttpModulo_04{

public class Class1 : IHttpModule{

public void Init(HttpA pplication context){

context.Error += new EventHandler(MiError);}

private void MiError(object sender, EventA rgs e){

Exception[] todosMisErrores = HttpContext.Current.A llErrors;foreach (Exception ex in todosMisErrores){

EventLog miLog = new EventLog ();miLog.Log = “A pplication”;miLog.Source = “Mi HttpModule”;miLog.WriteEntry(“Ha ocurrido un error: “ + ex.Message);

}HttpContext.Current.Server.ClearError();HttpContext.Current.Server.Transfer(

“/_layouts/MiPaginaDeErrores.aspx”);}

public void Dispose(){}

}}

Listado 6

Page 25: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 26: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Un buen día llega uno de los comerciales de laempresa y te dice que uno de los nuevos clien-tes desea integrar sus sistemas con los nuestros.La idea del cliente es automatizar todos sus pro-cesos, teniendo en cuenta que en parte de ellosintervendrá nuestra empresa como proveedorade algún tipo de servicio. En estos días, la solu-ción más acertada para hacer frente a escena-rios como éste pasaría por proveer de una capade servicios Web, de tal forma que expongamosa nuestros clientes parte o todos los servicios denuestra empresa.

Pero claro, aquí empiezan nuestros dolores decabeza y nos tenemos que plantear algunas cosas:¿Cómo y con qué lo hago? ¿Cómo gestiono laseguridad de la capa de servicios Web (autentica-ción, autorización, confidencialidad, integridad)?¿Cómo puedo dar mejor soporte al cliente? Algu-nas de estas preguntas tienen fácil y rápida res-puesta. Por ejemplo, el “cómo y con qué lo hago”.Está claro, con ASP.NET. Con respecto a la con-fidencialidad y a la integridad de la información,podemos resolverlo utilizando SSL en nuestrascomunicaciones (o haciendo uso del estándar WS-Security), algo que hoy en día, tanto por costecomo por facilidad de implementación, es acon-sejable en todos los proyectos de este tipo. En laspróximas líneas veremos cómo podemos resolveralgunas de las otras cuestiones.

¿Qué vamos a desarrollar?

El proyecto que vamos a llevar a cabo nos ser-virá como base para afrontar nuevos desarrollosde servicios Web. Nos permitirá:• Controlar los accesos: decidir quién puede

acceder y desde dónde a nuestra plataforma deservicios Web, mediante el uso de login y pass-word más validación de IP (sin depender delservidor IIS).

• Controlar qué servicios Web y métodos pue-den usar los clientes (autorización).

• Controlar el número de accesos a nuestra pla-taforma: para evitar abusos, o simplemente paratener diferentes niveles de servicio en funciónde la importancia del cliente.

• Tener la capacidad para decidir si las peticionesque recibamos son correctas o no, y denegar elacceso en caso de que no lo sean (para reducirla posibilidad de ciertos tipos de ataques).

• Tener mecanismos de logging para poder darmejor soporte a nuestros clientes en caso de quesea necesario.

Y todo ello, sin necesidad de tener el controlabsoluto del servidor Web donde se alojen los servi-cios Web, puesto que nos basaremos únicamente enun modelo de datos gestionado por SQL Server paracontrolar todo lo anterior.

Autenticación y autorización enservicios Web

con cabeceras y extensiones SOAP

plataforma.net

Juan Luis Ceada es Ingeniero en

Informática. Actual-mente trabaja en

Arrakis Servicios yComunicaciones

(Grupo BT) comoJefe de proyectos yanalista, estando acargo de múltiples

desarrollos y sistemasWeb que usan tecno-logías Microsoft. Tam-bién es autor de múl-

tiples artículos enrevistas del sector.

En ocasiones es necesario tener un control exhaustivo de los accesos que seproducen a nuestros servicios Web (quién accede, a dónde y cuántas veces),tanto por seguridad como para mantener la calidad del servicio. En este artí-culo veremos cómo podemos cumplir estos requisitos interceptando las lla-madas realizadas por los clientes a nuestra plataforma de servicios Web.

Juan Luis Ceada

Page 27: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dnm.plataforma.net<<

Como herramienta de desarrollo seha optado por Visual Studio 2008 WebDeveloper Express Edition, y como basede datos, SQL Server 2005 Express Edi-tion. No se utilizan las características nove-dosas de VS 2008, por lo que VS 20005podría servir también.

El modelo de datosPara poder llevar a cabo nuestro proyec-to, tendremos que apoyarnos en un mode-lo de datos, cuyo diagrama podéis ver enla figura 1. Veamos para qué sirve cadatabla. En primer lugar, la tabla ws_usuariosalmacena los logins y passwords de todos losusuarios que podrán acceder a nuestra pla-taforma de servicios Web. En la tablaws_ipsautorizadas almacenaremos lasdirecciones IP desde donde podrán acce-der dichos usuarios a la plataforma. Seadmite el formato IP/máscara, con lo quecon 192.168.0.0/255.255.0.0 (por ejemplo)estaríamos permitiendo el acceso desdecualquier máquina de la intranet a unusuario en particular.

Las tablas ws_webservices y ws_meto-doswebservice alojan, respectivamente,los nombres de cada uno de los servi-cios Web que vayamos a proporcionara los clientes, junto con sus respectivosmétodos. Todos y cada uno de los ser-vicios Web que creemos, así como todosy cada uno de los métodos que estosposean, deberán estar registrados enestas tablas, o de lo contrario no sere-mos capaces de utilizarlos (ni siquieranosotros: el sistema de seguridad nos loimpedirá). Ambas tablas contienen uncampo llamado permisopordefecto que nospermitirá decidir si un servicioWeb/método está disponible para todoel mundo (“P” de permitido) o paranadie (“D” de denegado) por defecto.Por ejemplo, un método para enviar une-mail masivo a todos nuestros clientespuede estar desactivado por defecto porsu “peligrosidad”, pero otro para con-sultar el nombre de un cliente a partirdel NIF debería estar disponible pordefecto, por ser algo “básico”.

Además, en ws_metodoswebservice tene-mos un campo llamado tamanomaximoxml.Este campo contendrá el tamaño aproxi-mado en kilobytes del mensaje SOAPesperado para este método. El valor de estecampo deberemos calcularlo en funciónde los parámetros que cada método pue-da recibir. Por ejemplo, el mensaje SOAPde un método que reciba únicamente unentero como parámetro no debería supe-rar el kilobyte de tamaño. Cualquier cosaque recibamos de más tamaño sin dudaserá una petición errónea como mínimo,pudiendo tratarse de un ataque de dene-gación de servicio (basado en el uso de unXML recursivo de gran tamaño, por ejem-plo), que podremos parar o mitigar sim-plemente rechazando la petición antes deque sea procesada por el parser XML delservidor. En los casos de métodos para losque nos sea imposible prever el tamaño delos mensajes, podemos utilizar el valor 0que equivale a “no verificar el tamaño”(cosa que deberíamos evitar siempre quesea posible).

Las tablas ws_permisosusuario4webser-vice y ws_permisosusuario4metodo sirvenpara modificar los permisos por defectode acceso a un servicio Web completo, oa métodos particulares de determinadosservicios Web. Por ejemplo, podemoshacer que un supuesto método para

enviar correos masivos (permiso dene-gado por defecto) del servicio clientesesté disponible para el usuario ws_admin.Para ello, bastará con añadir un registroen ws_permisosusuario4metodo con los valo-res ('ws_admin', 'clientes', 'mandarmailmasi-vo', 'P'), que se impondría al valor pordefecto que se almacena en ws_metodos-webservice.

La tabla ws_controlanchobanda nosayudará a decidir cuándo un usuarioestá abusando del servicio, o simple-mente si un usuario ha superado el lími-te de llamadas permitidas. En este caso,se ha decidido simplificar, de tal formaque podemos controlar únicamentecuántas llamadas a la plataforma se pue-den hacen por unidad de tiempo. Valo-res válidos son “5 llamadas por segun-do”, “20 al día” o “1000 al mes”. Aquípodríamos haber complicado aún másel esquema, haciéndolo más granular.Por ejemplo, “20 llamadas al día al ser-vicio Web XXX”, “3 llamadas porsegundo al método YYY del servicioWeb XXX”, pero a efectos de este artí-culo es suficiente con algo más genéri-co. El campo unidaddetiempo debe con-tener dos caracteres, cuyos valores coin-ciden con los que admite la funcióndateadd de Transact-SQL (“dd” paradías, “hh” para horas, etc.)

dotN

etM

anía

<<

27

Figura 1. Modelo de datos

Page 28: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Evidentemente, para poder saber siun usuario supera el límite de llamadas,necesitamos un log donde registrar cuán-tas llamadas se han hecho. Para eso tene-mos la tabla ws_estadisticas, donde alma-cenamos, entre otras cosas, la IP de ori-gen, servicio Web y método accedido, asícomo la fecha y hora del acceso.

Es importante recalcar que estemodelo de datos va a ser accedido conmuchísima frecuencia, por lo que con-viene que sea supervisado por un admi-nistrador de bases de datos que puedaaportar su experiencia a la hora de opti-mizar el rendimiento del servidor.

Procedimientos almacenados

Para trabajar con el modelo de datos,usaremos procedimientos almacenadosdesarrollados en Transact-SQL. Enconcreto, dispondremos de cinco:• ws_validarusuario: valida las creden-

ciales del usuario, a partir de login ypassword.

• ws_validartamanomensaje: comprue-ba si para un servicio Web y méto-do en particular se está superandoel tamaño de mensaje XML espe-rado.

• ws_validaracceso: comprueba si unusuario está autorizado para accedera un determinado servicio Web/méto-do, teniendo en cuenta los permisosdel mismo y si ha superado el anchode banda asignado o no.

• ws_obteneripsusuarios: devuelve unconjunto de datos con todas las IPdesde las que el usuario puede acce-der a la plataforma.

• ws_guardarestadistica: almacena losaccesos que los usuarios van hacien-do a la plataforma.

De todos ellos, el que tiene mayorcomplejidad (nada del otro mundo) esws_validaracceso, del que podéis ver unaparte en la figura 2.

Para poder utilizar estos procedi-mientos, hemos desarrollado un par declases auxiliares (fichero WSA uxiliar.cs).La clase IPMask nos ayudará a la hora decomprobar si la IP desde la que accede elusuario coincide con alguna de las quetenemos almacenadas en la base de datos(teniendo en cuenta la máscara). Otra cla-se, llamada WSA uxiliar (dividida en capade negocios y capa de acceso a datos) nospermitirá utilizar los procedimientos antesdescritos. El único método que contienealgo de código adicional es ValidarA cce-so, y solo porque además de llamar al pro-

dnm.plataforma.net<<

dotN

etM

anía

<<

28

Figura 2. Procedimiento almacenado

Al hilo de este artículo, me gustaría comentaros mi experiencia con la integración de nues-tros clientes. Llevo ya algunos años ayudando a terceros a integrarse con nuestra platafor-ma, y he visto casi de todo: gente que no ha tenido el más mínimo problema, otros a los queles ha costado algo más, y algunos con los que durante algunos momentos he llegado a pen-sar en tirar la toalla. Pero al final todo han sido finales felices. Poder interceptar lo que losclientes envían (el XML en bruto), así como llevar un registro de las excepciones produci-das ayuda (y no sabéis cuanto, sobre todo cuando aparecen los temidos problemas de inte-roperabilidad).

Tener la mente abierta ayuda también: no os cerréis a dar soporte solo a la integración entredeterminadas plataformas. Algunos clientes usarán .NET, y por tanto el soporte a la integracióndebería ser total. Otros usarán Java, que tampoco debería dar problemas. Pero otros usarán PHP,Ruby, C++ (o cualquier otra cosa), y a lo mejor no tenéis personal con el conocimiento necesa-rio para dar soporte. En este caso, no os neguéis a ayudar. En todo caso, advertid que no es vues-tro campo, pero siempre intentad ayudar (aunque tengáis que aprender sobre la marcha, siemprees más fácil para el “servidor” encontrar y depurar los problemas que para el “cliente”). Al final,habréis aprendido cosas nuevas, y tendréis una base de datos de ejemplos en diferentes lenguajesde programación que ayudarán a futuros nuevos clientes.

Otra cosa: no os olvides nunca que una vez la integración se produce, ya no hay marchaatrás, y que cualquier problema repercutirá inmediatamente en los clientes. Por tanto la dis-ponibilidad del servicio se vuelve importantísima, y habrá que prever con la antelación nece-saria los cambios en la plataforma, manteniendo a los clientes informados, y realizando mul-titud de pruebas antes del paso a producción, siendo imprescindible en este caso contar conuna plataforma de integración previa al paso a producción y distinta de la plataforma de desa-rrollo. Y un último consejo: la comunicación por e-mail está bien, pero de vez en cuando losclientes agradecen una llamada, aunque sólo sea para preguntar “¿cómo vais?”.

Page 29: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dnm.plataforma.net<<

dotN

etM

anía

<<

29

cedimiento ws_ValidarA cceso también lla-ma a ws_ObtenerIpsUsuario para obtener lalista de IP validadas y verificar si algunacoincide con la de origen (ver listado 1).

El servicio Web WSBaseUna vez analizado el modelo de datos,pasemos a ver cómo lo utilizaremosen nuestra plataforma de serviciosWeb. En primer lugar, hemos creadoun servicio Web que hereda directa-mente de System.Web.Services.WebSer-vice, y al que hemos llamado WSBase.Como su nombre indica, este servi-cio Web será la base de toda nuestraplataforma. Por tanto, todos y cadauno del resto de los servicios Webdeberán descender de WSBase; esto esimprescindible para el correcto fun-cionamiento del sistema.

Pero, ¿qué hace tan especial a WSBa-se? Pues varias cosas, en realidad. Enprimer lugar, en él se definen ciertasestructuras de datos que heredarán/uti-lizarán el resto de servicios Web. Porejemplo, un objeto de la clase WSRe-questHeader, que define el formato de las

credenciales de usuario. O las clases A ut-hExtension y A uthExtensionA ttribute, queson la base de todo el sistema. Perovamos por partes.

La propiedad Credenciales

Como hemos comentado, todos losservicios Web, al descender de WSBase,heredan la propiedad Credenciales detipo WSRequestHeader, que a su vez des-ciende de SoapHeader [1]. Al hacerla des-cender de SoapHeader, lo que estamosdefiniendo es una clase que usaremoscomo cabecera SOAP, y que será obli-gatorio proporcionar en todas y cadauna de las llamadas a nuestra platafor-ma para poder realizar la validacióndel usuario. Afortunadamente, si sedesarrolla la aplicación cliente tambiénen .NET , bastará con asociar una úni-ca vez la cabecera SOAP en el códigopara que esta sea enviada en cada lla-mada automáticamente (en otros len-guajes es necesario pasar explícita-mente dicha cabecera en cada una delas llamadas a métodos como un pará-metro más).

Frente a esta forma de proceder,en la que se comprueban las creden-ciales en cada petición, tenemos laposibilidad de validar las credencia-les una única vez, de tal forma que nosea necesario pasar de nuevo por esteproceso en sucesivas peticiones,ahorrándonos accesos a la base dedatos. El problema es que esto nosobligaría a guardar cierta informaciónen variables de sesión, y en el caso deque optemos por sesiones in-processesto significaría que el balanceo decarga (si existe) no sería tan eficien-te, por tener que ligar cada sesión aun servidor particular. Y si se decideusar sesiones out-off-process, basadasen SQL Server, pues simplementeestaríamos trasladando los accesos auna base de datos distinta.

La clase WSRequestHeader contienesolamente dos propiedades: login ypassword. Por tanto, en cada llamada aun método el cliente nos debe propor-cionar estos datos dentro de la cabece-ra SOAP del mensaje. Una vez recibi-dos, buscaremos en la base de datos sidichos login/password están registrados

public static void ValidarA cceso(string ip, string webservice, string metodo, string login){System.Collections.Generic.List<IPMask> lipm = WSA uxiliarDA L.ObtenerIpsUsuario(login);bool encontradaip = false;if (lipm != null){

foreach (IPMask ipm in lipm){

if (!encontradaip) encontradaip = IPMask.ValidaIP(ip, ipm);}

}if (!encontradaip){

throw new Exception(“No se puede acceder a la plataforma de WS desde la IP “ + ip);}

// una vez analizada la IP, vemos si le concedemos o no acceso al WS, teniendo // en cuenta factores como los permisos o las últimas estadísticas de accesoWSA uxiliarDA L.ValidarA cceso(webservice, metodo, login);

Listado 1: Código del método WSAuxiliar.ValidarAcceso

Page 30: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dnm.plataforma.net<<

dotN

etM

anía

<<

30

y son válidos. Como toda clase, WSRe-questHeader podría admitir muchas máspropiedades. Por ejemplo, podríaincluir algún tipo de token pre-genera-do, número de licencia, o cualquier otroliteral que sirva para garantizar la auten-ticación, y que los clientes nos deberánproporcionar.

Pero, ¿cómo indicamos a las apli-caciones clientes de nuestro servicioWeb que deben enviar una cabecera concredenciales al llamar a todos (o soloalgunos) de los métodos existentes?Veamos el servicio Web Clientes (que,por supuesto, hereda de WSBase), imple-mentado en Clientes.cs. Contiene dosmétodos bastante simples: Consultar yBorrar. El código del método Consultarse presenta en el listado 2.

Como se puede apreciar, medianteatributos del método estamos indicandoque éste se va a exponer a través de Web(WebMethod) y que va a llevar asociada unacabecera de nombre “Credenciales”. Esta

información se incluye en el ficheroWSDL, lo que permite a los entornos dedesarrollo conocer las necesidades delservidor para poder generar el proxy clien-te adecuado. Podríamos perfectamentetener varios tipos de cabeceras (unas mássimples, otras más complejas), y hacer quecada una se asocie a un método distintoen función de nuestras necesidades.

La clase AuthExtension

La clase A uthExtension desciende deSoapExtension [2], y nos permitirá teneracceso a los mensajes SOAP que se inter-cambian entre cliente y servidor antes deque éstos lleguen a su destino final. Podre-mos analizarlos, y si es necesario, modi-ficarlos. Y por supuesto, es posible recha-

zar peticiones si lo que estamos recibien-do desde el cliente “no nos gusta”. Estaclase, así como la clase A uthExtensionA t-tribute que veremos a continuación, sehan definido dentro de WSBase por sim-

plificar, pero nada nos impide extraer estecódigo a una DLL independiente quepodríamos reutilizar en otros proyectos.

Al heredar de SOA PExtension tenemosque sobrescribir cuatro métodos, aunquesólo el código de uno de ellos no es tri-vial: el del método ProcessMessage. Estemétodo es llamado en cuatro ocasionesdistintas por el framework ASP.NET:

• Antes de deserializar el mensajeSOAP XML recibido en un objetoen el servidor (SoapMessageStage.Befo-reDeserialize).

• Después de deserializar el mensajeSOAP XML recibido en un objeto enel servidor (SoapMessageStage.A fterDe-serialize). Para analizar las cabece-ras hay que actuar en este punto.

• Antes de serializar la respuesta en unmensaje XML SOAP para su envíoal cliente (SoapMessageStage.BeforeSe-rialize).

• Después de serializar la respuesta enun mensaje XML SOAP para su envíoal cliente (SoapMessageStage.A fterSe-rialize).

Como a nosotros en principio solonos interesa analizar los mensajes queel cliente envía al servidor, nuestro códi-go únicamente actuará en los dos pri-meros casos, tal y como se puede apre-ciar en el listado 3.

Cada vez que el método Process-Message sea llamado, tenemos que com-probar el estado en el que se encuen-tra el mensaje. Cuando estemos en elpaso BeforeDeserialize, que es el pri-mero en producirse, poco podremoshacer, puesto que el mensaje por aho-ra no es más que un flujo de bytes. Peroen este momento podemos comprobaral menos a qué método y servicio Webse dirige la petición y, usando el méto-do ValidarTamanoMensaje de la clase WSA u-xiliar, validar el tamaño del mensajeque estamos recibiendo. Si es exagera-do para lo que se esperaba, lanzaremosuna excepción que abortará el resto delproceso, ahorrando así al servidor latarea de deserializar el mensaje XML.

[WebMethod, A uthExtension(), SoapHeader(“Credenciales”)]public string Consultar(string dni) {

return “Obtenidos los datos del cliente con dni “ + dni;

Listado 2. El método Consultar del servicio Clientes

El uso de cabeceras SOAP para la autenticación tiene ventajas frente al método tradicional, puesto que podemos

“exigir” datos adicionales como números de licencia sin tener que complicar la interfaz de los métodos

Page 31: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 32: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Además de lanzar la excepción, regis-traremos el acceso en la tabla deestadísticas. En este caso, como aún nose ha procesado el mensaje SOAP, notendremos acceso al contenido de lacabecera, y por tanto no podremossaber qué usuario está realizando lapetición, de ahí que se registre comologin “info no disponible”.

Cuando estemos en el paso A fter-Deserialize (el segundo del proceso),lo primero que tendremos que haceres recorrer todas las cabeceras delmensaje SOAP (podría haber más deuna), buscando aquella que tenga elformato de nuestra clase WSRequestHe-ader. Si encontramos alguna, extrae-mos de ella tanto el login como la pass-word del usuario, y procedemos a vali-darlos. En caso de que la validaciónno se lleve a cabo con éxito, o si no sehan recibido las credenciales, se lan-zará una excepción que abortará eltratamiento del resto de la petición,y se registrará el acceso “denegado”en el log.

Una vez verificadas las credencia-les, tendremos que ver si el usuario estáautorizado para utilizar el método/ser-vicio Web al que se está llamando(información que podemos obtener através de la propiedad MethodInfo de lavariable message que recibimos comoparámetro). Además, también seránecesario verificar si se supera el núme-ro de peticiones por unidad de tiempocontratadas. De todo eso se encarga elmétodo ValidarA cceso de la clase WSA u-xiliar, como vimos con anterioridad.Si todo es correcto, permitiremos elacceso, y anotaremos el acceso “permi-tido” en las estadísticas.

La clase AuthExtensionAttribute

Para poder hacer uso de la clase A ut-hExtension, tendremos que crear nues-tro propio atributo de método, crean-do una nueva clase que herede de Soa-pExtensionA ttribute a la que llamaremosA uthExtensionA ttribute (ver listado 4). En

dnm.plataforma.net<<

dotN

etM

anía

<<

32

public override void ProcessMessage(SoapMessage message){WSRequestHeader h;bool credencialesrecibidas = false;string loginrecibido = “”;

// acciones que podemos realizar antes de deserializar el mensaje recibidoif (message.Stage == SoapMessageStage.BeforeDeserialize){// comprobamos que el tamaño en KBytes del mensaje recibido no supera // el máximo permitido para un métodotry{WSA uxiliar.ValidarTamanoMensaje(message.MethodInfo.DeclaringType.Name,message.MethodInfo.Name,message.Stream.Length / 1024);

}catch (Exception ex){WSA uxiliar.GuardarEstadistica(message.MethodInfo.DeclaringType.Name, message.MethodInfo.Name,“info no disponible”, ‘D’, HttpContext.Current.Request.ServerVariables[“REMOTE_A DDR”].ToString(), ex.Message);

throw;}

}

// actuamos justo después de obtener el mensaje XML SOA P y deserializarlo // en un objeto,imprescindible para poder tratar la cabeceraif (message.Stage == SoapMessageStage.A fterDeserialize){foreach (SoapHeader header in message.Headers){if (header is WSRequestHeader){credencialesrecibidas = true;h = (WSRequestHeader)header;// validamos la peticióntry{loginrecibido = h.login;WSA uxiliar.ValidarUsuario(h.login, h.password);

// el usuario parece ok, vamos a comprobar si tiene acceso // al método y servicio Web deseado.WSA uxiliar.ValidarA cceso(HttpContext.Current.Request.ServerVariables[“REMOTE_A DDR”].ToString(),message.MethodInfo.DeclaringType.Name, message.MethodInfo.Name, h.login);

// lo tiene, guardamos estadísticasWSA uxiliar.GuardarEstadistica(message.MethodInfo.DeclaringType.Name,message.MethodInfo.Name,h.login, ‘P’, HttpContext.Current.Request.ServerVariables[“REMOTE_A DDR”].ToString(),“”);

}catch (Exception ex){

Page 33: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

ella solo tendremos que sobrescribir dospropiedades. La primera indica la prio-ridad de la “extensión”, y se utiliza cuan-do se usan simultáneamente varios atri-butos de tipo SoapExtensionA ttribute,para decidir con qué prioridad se pro-cesan. La segunda simplemente hemosde modificarla para que devuelva el tipode la clase que se encargará de procesarlos mensajes SOAP, en nuestro caso A ut-hExtension.

El servicio Web ClientesComo hemos comentado con anteriori-dad, se trata de un servicio Web desarro-llado a modo de ejemplo para poder pro-bar el mecanismo de control de accesoque hemos creado. Contiene dos méto-dos muy sencillos en su implementación.Por supuesto, ambos métodos, así comoel servicio Web que los aloja, han sidodados de alta en la base de datos, quecomo hemos visto es el primer paso aafrontar a la hora de poder definir los con-troles de acceso. La única particularidada destacar es que el método Borrar lo con-sideramos especialmente peligroso, y poreso por defecto todos los usuarios tienenel permiso de acceso a él denegado, sien-do necesario establecer explícitamenteque un usuario determinado tiene acce-so al mismo.

Como último señalamiento, volva-mos a estudiar el método Consultar (verlistado 2). Como se puede apreciar, hayun tercer atributo en la definición delmétodo que antes pasamos por alto: A ut-hExtension. Como habréis podido dedu-cir, este atributo indica que toda lla-mada que se haga a dicho método va aser "supervisada" por la clase A uthExten-sion, tal y como vimos con anteriori-dad. Si no se especificasen estos tresatributos, todo nuestro trabajo no ser-viría para nada. Por tanto, es muyimportante no olvidar añadir a cadamétodo de cada servicio Web los tresatributos (salvo que por algún motivoqueramos que alguno de nuestros méto-dos no esté supervisado).

dnm.plataforma.net<<

// guardamos en log el acceso denegado al método/servicio WSA uxiliar.GuardarEstadistica(message.MethodInfo.DeclaringType.Name,message.MethodInfo.Name,h.login, ‘D’,HttpContext.Current.Request.ServerVariables[“REMOTE_A DDR”].ToString(),ex.Message);

throw;}

}}

if (!credencialesrecibidas){string msg = “Toda llamada a método de servicio debe llevar las credenciales de usuario”;

WSA uxiliar.GuardarEstadistica(message.MethodInfo.DeclaringType.Name, message.MethodInfo.Name,loginrecibido, ‘D’,HttpContext.Current.Request.ServerVariables[“REMOTE_A DDR”].ToString(),msg);

throw new Exception(msg);}

// aquí podríamos hacer otras cosas, como guardar el mensaje recibido // a modo de log para su futuro estudio

}

// antes de mandar el mensaje de vuelta al clienteif (message.Stage == SoapMessageStage.BeforeSerialize){// aquí podríamos por ejemplo guardar en un log cualquier excepción// que haya ocurrido antes de devolvérsela al cliente,// útil para ayudar en el soporte

}}

Listado 3: Código del método ProcessMessage.

dotN

etM

anía

<<

33

[A ttributeUsage(A ttributeTargets.Method)]public class A uthExtensionA ttribute : SoapExtensionA ttribute{

int _priority = 1;

public override int Priority{

get { return _priority; }set { _priority = value; }

}

public override Type ExtensionType{

get { return typeof(A uthExtension); }}

}

Listado 4: Clase AuthExtensionAttribute

Page 34: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Las pruebasUna vez presentados los principiosgenerales del desarrollo, pasemos arealizar algunas pruebas. Para ello seincluye en el proyecto una páginaWeb muy simple que hace uso del ser-vicio Clientes. La interfaz de usuarioes muy sencilla y tan solo contienetres botones (ver figura 3). Uno deellos servirá para invocar al método

Consultar y otro al método Borrar,mientras que el tercero llamará almétodo Consultar, pero con una pecu-liaridad: construiremos a mano elmensaje XML, al que le meteremosmucha “morralla” y lo enviaremosmediante una petición HTTP POST,ignorando por tanto el proxy queVisual Studio ha generado a partir delWSDL. La idea es simular un supues-to ataque de un usuario malintencio-nado.

El código que se ejecuta al pulsarsobre el primer botón se muestra enel listado 5. En él se aprecia en pri-mer lugar como se crean sendos obje-tos que representan al proxy creado apartir del WSDL y a las credencialesde usuario. A continuación, rellena-mos las credenciales, que son asigna-das a la propiedad WSRequestHeaderVa-lue del proxy. Y por último, llamamosal método Consultar. Puesto que lascredenciales se asignan al proxy, estosignifica que solo tenemos que pro-porcionarlas una vez, pudiendo hacertantas llamadas a los métodos comoqueramos, ya que en todas y cada unade las peticiones se incluirá automá-ticamente la cabecera en los mensa-jes SOAP.

El código que se ejecuta al pulsarel botón "Borrar" es análogo al del lis-tado 5, mientras que el código delbotón "Enviar mensaje XML gigante"es algo más complejo, pero tampoconada del otro mundo. En la figura 4 semuestra la situación de error que se

dnm.plataforma.net<<

dotN

etM

anía

<<

34

WSClientes.Clientes ws = new WSClientes.Clientes();WSClientes.WSRequestHeader credenciales = new WSClientes.WSRequestHeader();credenciales.login = “ejemplo”;credenciales.password = “ejemplo1”;ws.WSRequestHeaderValue = credenciales;Label1.Text = ws.Consultar(“12345678z”)

Listado 5: Ejemplo de llamada al servicio Web

Figura 3. Página de ejemplo

Figura 4. Excepción por falta de permisos

Page 35: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

produce por falta de permisos. De for-ma similar, nuestro sistema reaccio-nará ante la falta de credenciales, unmensaje XML de tamaño excesivo o lasuperación del límite de 5 peticionespor hora que hemos establecido.

ConclusiónCon poco esfuerzo, hemos creado unsistema que nos permitirá tener mayorcontrol sobre quién y cómo accede anuestra plataforma de servicios Web.Además, como el sistema está basadoúnicamente en base de datos, no esnecesario tener el control del servidorpara poder utilizarlo, lo que puede venirmuy bien de cara a instalaciones en hos-tings compartidos.

Por supuesto, el sistema admitemúltiples ampliaciones. Por ejemplo,podríamos guardar un log de todos losmensajes SOAP que nos llegan parapoder ayudar a nuestros clientes consus desarrollos (no todo el mundo usaherramientas avanzadas, y a veces esde gran ayuda ver qué datos estamosrecibiendo en “bruto”). O podríamosalmacenar en la base de datos todaslas excepciones que se produzcan enla plataforma, junto con informaciónadicional que nos permita depurarerrores. En fin, que hay muchas posi-bilidades a explorar, para las que tansolo se necesita tener algo de tiempoy de imaginación.

dnm.plataforma.net<<

dotN

etM

anía

<<

35

Figura 5. Excepción si no se introducen credenciales

Figura 6. Excepción por tamaño máximo superado

Figura 7. Excepción por ancho de banda

Bibliografíahttp://msdn.microsoft.com/es-es/library/system.web.services.protocols.soapheader(VS.80).aspx

http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapextension.aspx

Prosise, Jeff. “Build Secure WebServices With SOAP Headers andExtensions”, en http://www.develo-per.com/net/net/article.php/11087_2192901_1.

[1]

[2]

[3]

Page 36: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

El sitio oficial de descarga de los nuevos con-troles y herramientas para Silverlight es Code-plex (www.codeplex.com/silverlight), y es ahí don-de el lector podrá encontrar el último paquetede herramientas y controles que complementaa las ya incluidas con el SDK del producto, yque se distribuyen bajo licencia pública deMicrosoft (Ms-PL). Todo el código fuente estádisponible en uno de los paquetes descargables,junto con ejemplos de cada elemento y carac-terística soportada, y un ejemplo genérico “Sam-ple Explorer”, que muestra en una sola páginatodos los elementos nuevos. En resumen, elpaquete de diciembre de 2008 ofrece las siguien-tes novedades:

• Controles: nuevos controles de IU que pode-mos dividir en dos clases, dependiendo de sugrado de madurez: los que están consideradoscomo estables (stable), y los que están a un pasode esa calificación (preview).

o En el primer grupo se encuentran A uto-CompleteBox, DockPanel, HeaderedContent-Control, HeaderedItemsControl, Label, Nume-ricUpDown, TreeView y WrapPanel.

o Y en el segundo: Expander, ImplicitStyle-Manager y ViewBox.

• Charting: control para la visualización gráfi-ca de conjuntos de datos. Aunque se trata igual-mente de un control, su complejidad y posibi-lidades hacen que merezca un estudio aparte.

• Temas: soporte para temas (themes) al estilo deASP.NET, donde se incluye media docena detemas de ejemplo. La clase ImplicitStyleMana-ger se relaciona directamente con esta funcio-nalidad.

• Automatización (Automation Peer): soportepara automatización de elementos de la inter-faz de usuario. Especialmente interesante parala construcción de sitios accesibles.

Desafortunadamente (en palabras del divulga-dor oficial de la tecnología, Jesse Liberty), la cali-dad del contenido de este kit de herramientas nocorre pareja con los materiales didácticos que nospermitan aprender su funcionamiento e incorpo-rarlo con rapidez a nuestras aplicaciones. Apartedel fichero .chm de ayuda del SDK, lo más intere-sante que se incorporó en esta versión fue la solu-ción global con ejemplos que muestran todos loscontroles, junto a características de visualizaciónde datos y soporte de temas en una sola aplicación,con acceso directo al código fuente en XAML/C#.

Silverlight 2.0 Toolkit Controles, visualización de datos y mucho más (I)

Silverlight

Marino Posadas es redac-tor jefe de ddotNetMania y

Software Arquitect deAlhambra-Eidos. Es MCP,

MCSD, MCAD, MCT yMVP en Visual C#.

Puede consultar su páginaWeb en

www.elavefenix.net

En paralelo con la presentación de la versión final de Silverlight 2.0, se anunciabaen las webs “oficiales” de la plataforma la intención de mejorar el desarrollomediante la publicación paulatina de nuevos controles y herramientas que poten-cien las posibilidades de creación de aplicaciones RIA con Silverlight, al tiempoque se anticipaban algunas características de la versión 3.0, que según Scott Guth-rie estará disponible a finales de 2009. Vamos a revisar aquí algunas de las posi-bilidades que ofrece el último paquete de herramientas, publicado a primeros delpasado mes de diciembre.

Marino Posadas

Page 37: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

El propio Liberty, no obstante reconocer esta situa-ción, ha publicado ya dos vídeos explicativos del kit ycontinuará con la labor de divulgación de estas nove-dades (ver el sitio http://silverlight.net/blogs/jesseliberty/archive/2008/12/08/a-complex-home-for-very-some-simple-toollkit-examples.aspx).Nosotros vamos a presentar los fundamentos del fun-cionamiento de este kit y sus herramientas asociadas,centrándonos solamente en el código fundamental delos elementos estables, y explicando las bases del char-ting y el uso de temas.

Controles Antes de nada, hay que decir que si el lector quiereprobar este kit tal y como se hace con el resto de con-troles, desde Visual Studio, recuerde que deberá hacerreferencia a la librería que los contiene (Micro-soft.Windows.Controls.dll), que encontrará en eldirectorio /binaries del paquete descargable, una vezdescomprimido éste. Nótese la diferencia de nomen-clatura de la DLL con respecto a la del paquete “están-dar” (System.Windows.Controls). Además, la libreríaMicrosoft.Windows.Controls.Input contiene el ele-mento NumericUpDown, así como clases base para laconstrucción de elementos similares. Una vez hechoesto, en el Cuadro de herramientas de Visual Studio2008 aparecerán 10 elementos nuevos, tal y como seve en la figura 1.

En realidad, esto es solo una pequeña parte delpaquete; un vistazo al Examinador de objetos nos mos-trará que hay otros controles que no aparecen en lalista, bien porque sirven para la construcción de otros,bien porque no tienen una interfaz visual propia,debiendo ser ésta definida por el usuario (como But-tonSpinner).

La recomendación oficial es que no se utilicen másque los controles de categoría estable para labores deproducción (y, según qué escenarios, habría que espe-rar a que alcanzaran la categoría de “maduros”).

Controles en estado preview

Comenzamos presentando los controles actual-mente en estado preview, citando simplemente su fun-cionalidad (sin ejemplos de código).

Expander

Ya presente en Win-dows Presentation Foun-dation, es un control quemuestra una cabecera con(o sin) un rótulo descripti-vo, y un glifo que permitedesplegar y colapsar una

ventana en su parte inferior. Se debe tener cuidado enel diseño para controlar la superficie que se muestrarespecto a otros controles de la interfaz.

ViewBox

Define un decorador de contenido,que puede cambiar el tamaño y escalarun único elemento interno hasta relle-nar el espacio disponible. También estádisponible en WPF.

ImplicitStyleManager

No es un control propiamente dicho, sino una clasesin interfaz de usuario propia que permite encapsular uncomportamiento visual que propaga sus estilos a un con-junto de controles. Está vinculado con el funcionamien-to de los temas, y una de sus enormes ventajas es la posi-bilidad de almacenar separadamente conjuntos de esti-los (en una DLL, por ejemplo), y poder aplicarla despuésa distintos elementos de una interfaz dada. Hablaremoscon detalle de su funcionamiento y programación en elpróximo artículo, dedicado a los gráficos empresariales.

Controles (en estado stable)

A utoCompleteBox

Representa un control similaral ComboBox, pero que permite labúsqueda incremental en los ele-mentos de la lista desplegable

dotN

etM

anía

<<

37

dnm.dnm.plataforma.net<<

Figura 1

Page 38: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

38

dnm.plataforma.net<<

según se van introduciendo datos en el control. Lapropiedad que activa/desactiva las características debúsqueda es IsTextCompletionEnabled, de tipo bool, acti-vada de forma predeterminada. Para el ejemplo de lafigura, el código sería el siguiente:

HeaderedContentControl

Representa la clase base paratodos los controles que tienenuna propiedad Content y unacabecera (contrapartida de Hea-deredItemsControl, que veremosa continuación). Es muy senci-

llo de utilizar y programar. Para ver su esencia, bas-ta con el siguiente código XAML, que produce porpantalla la imagen que acompaña estas líneas:

HeaderedItemsControl

Representa la clase base paratodos los controles que tienenuna propiedad ItemsControl yuna cabecera. En este ejemplo,la propiedad utilizada para mos-trar los contenidos simplemen-te define una plantilla para cadaítem de la lista (propiedad Item-

Template). Esa plantilla va necesariamente dentro deun elemento <DataTemplate>, que admite cualquierconjunto válido de controles. La asociación de losdatos a mostrar se realiza mediante databinding, comopuede verse en el código adjunto:

Label

En principio, este controlestá pensado para completar lasposibilidades de TextBlock, res-pecto a la inclusión de otros ele-mentos. Podemos construir eti-quetas de texto con bordes, fon-dos, figuras laterales o en back-

ground, etc. Muy útil para utilizar como ítem de otroselementos colectivos como cuadros combinados (com-bo boxes) y similares. Por ejemplo:

NumericUpDown

Es la versión de su homóni-mo de Windows Forms y WPF,solo que permite una gran canti-

dad de configuraciones visuales, y además soporta la con-fección de estilos personalizados a través de su atributoSpinnerStyle, al que se le puede asignar cualquier esti-

XA ML<controls:HeaderedContentControl>

<controls:HeaderedContentControl.Header><Image Source=”Imagenes/s18.jpg” />

</controls:HeaderedContentControl.Header><controls:HeaderedContentControl.Content>

<TextBlock Text=”Figura 1: Tablero clásico”FontFamily=”A rial” FontSize=”18” />

</controls:HeaderedContentControl.Content></controls:HeaderedContentControl>

XA ML<controls:A utoCompleteBox Width=”120” Height=”25”

x:Name=”CajaA utoCompletar” />C#

CajaA utoCompletar.ItemsSource = new String[] { { “Pedro”, “Perico”, “Petronio”, “Patricio” };

XA ML<controls:HeaderedItemsControl

x:Name=”CajaHeaderItems”><controls:HeaderedItemsControl.Header>

<Image Source=”Imagenes/s18.jpg” /></controls:HeaderedItemsControl.Header><controls:HeaderedItemsControl.ItemTemplate>

<DataTemplate><Border Background=”Beige” Width=”200”

HorizontalA lignment=”Left”><TextBlock Text=”{Binding}“

Margin=”10,0,0,0” /></Border>

</DataTemplate></controls:HeaderedItemsControl.ItemTemplate>

</controls:HeaderedItemsControl>

C#CajaHeaderItems.ItemsSource = new String[]

{“1. d4, d6”,“2. Cf3, Cc6”, “3. A b5, A d2”, “4. ...”};

<controls:LabelBorderBrush=”Navy” BorderThickness=”5”Foreground=”Maroon” Background=”A quamarine” VerticalA lignment=”Center” Width=”150”HorizontalA lignment=”Center”><StackPanel>

<Image Source=”Imagenes/s18.jpg” /><TextBlock Text=”Partidas famosas” />

</StackPanel></controls:Label>

Page 39: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

lo definido por el usuario. El código siguiente ejempli-fica su utilización:

TreeView

Situación similar a laanterior, en cuanto a la fun-cionalidad, la capacidad deconfiguración visual y laposibilidad de persona -lización del control. Admi-te innumerables niveles deanidación, y cada elementoTreeViewItem puede con-tener cualquier otro, con lo

que es posible la personalización a cualquier nivel,modificando el atributo predeterminado ItemTem-plate. Dispone igualmente de las propiedades de enla-ce a datos DataContext e ItemsSource. La figuraadjunta se corresponde con el código siguiente:

DockPanel y WrapPanel

Se trata de los dos controles contenedores que fal-taban con respecto a la oferta de WPF. El primero deellos (recuérdese la propiedad con objetivo similar en

los controles de Windows Forms) permite ubicar con-tenidos ligándolos a uno de los bordes (o todos) de sucontenedor. El segundo va situando los contenidos enuna secuencia mientras caben en pantalla, y continúa enfilaso columnas sucesivas si el contenido no cabe en elcontenedor. En el ejemplo de la siguiente figura, todoslos elementos están contenidos en un DockPanel, pero elTreeView superior tiene asignada su propiedad adjuntade anclaje a Top, por lo que permanece en la parte supe-rior. Por su parte, los tres Label de la parte inferior (elúltimo, truncado en su salida) están incluidos dentro deun elemento WrapPanel con valores predeterminados desus propiedades.

El código significativo que produce esta salida es:

ConclusiónUna vez presentados los controles, en la siguien-

te entrega de este repaso sobre Silverlight Toolkitrevisaremos los controles de charting para la repre-sentación de gráficos empresariales, el funcionamientode los temas y algunas peculiaridades de los procesosde depuración y automatización.

dotN

etM

anía

<<

39

dnm.dnm.plataforma.net<<

<input:NumericUpDownBorderBrush=”Navy” BorderThickness=”3”Foreground=”Red” Height=”27”FontSize=”18” FontWeight=”Bold”Maximum=”12” Minimum=”1” DecimalPlaces=”1”UseLayoutRounding=”True“ Value=”3” />

<controls:TreeView Background=”A ntiqueWhite”> <controls:TreeViewItem IsExpanded=”True”Header=”A pertura española”><controls:TreeViewItem IsExpanded=”True”

Header=”Variante Ruy López”><controls:TreeViewItem

Header=”1. d4, d6” /></controls:TreeViewItem>

</controls:TreeViewItem><controls:TreeViewItem IsExpanded=”False”Header=”Defensa siciliana”><controls:TreeViewItem Header=”1. d4, Cf6” />

</controls:TreeViewItem><controls:TreeViewItem IsExpanded=”True”Header=”Defensa Grünfeld”><controls:TreeViewItem Header=”1. d4, Cf6” /><controls:TreeViewItem Header=”1. c4, g6”

Background=”Navy”Foreground=”Yellow” />

</controls:TreeViewItem></controls:TreeView>

<controls:DockPanel Width=”300” Height=”350” Background=”Blue”><controls:TreeView controls:DockPanel.Dock=”Top”

Background=”A ntiqueWhite” Width=”170” Height=”180” ><controls:TreeViewItem [...]> </controls:TreeViewItem><controls:TreeViewItem [...]> </controls:TreeViewItem><controls:TreeViewItem [...]> </controls:TreeViewItem>

</controls:TreeView><controls:WrapPanel>

<controls:Label [...]> </controls:Label><controls:Label [...]> </controls:Label><controls:Label [...]> </controls:Label>

</controls:WrapPanel></controls:DockPanel>

Page 40: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dnm.servidores.sql

La minería de datos es la ciencia de extraer infor-mación no trivial de conjuntos de datos; éstos pue-den ocupar desde varios “megas” hasta varios “teras”.Dependiendo de la técnica que usemos, necesitare-mos que el conjunto sea mayor o menor, aunque enmuchos de los casos no es tan importante el tamañocomo que los datos sean lo suficientemente repre-sentativos de lo que queremos analizar para podermás tarde realizar predicciones.

Básicamente, cuando realizamos minería dedatos lo primero que tenemos que hacer es limpiarlos datos, para que éstos no tengan errores y nohaya ambigüedades en códigos y demás. Una veztenemos listos los datos, creamos una estructuradonde elegimos el algoritmo de minería que vamosa utilizar, los atributos que seleccionamos para gene-rar el modelo y los atributos que queremos prede-cir. Una vez construida la estructura, la procesa-mos junto con los datos, obteniendo un modelo.Un modelo es un conjunto de reglas que nos per-miten realizar predicciones. Una vez que tenemosel modelo generado, podemos hacer consultas adicho modelo mediante el lenguaje de consultas deminería de datos de SQL Server. Este lenguaje sedenomina Data Mining Extensions (DMX). Através de ADODM (esto es, ADO para Minería dedatos), podemos conectarnos al servidor de Analy-sis Services donde se encuentran alojados los

modelos y ejecutar consultas expresadas en dicholenguaje; normalmente, éstas las realizamos ya des-de nuestras aplicaciones o portales Web, imple-mentadas en código C# o Visual Basic.

El hecho de que haya elegido un portal de unatienda en Internet no es casualidad. Tenemos quepensar que cuando utilizamos minería de datos esta-mos realizando predicciones, y éstas se basan enmodelos estadísticos que en la mayoría de los casosdarán resultados correctos, pero en otros no. Esdecir, cuando hacemos predicciones estamos inven-

Agregando inteligencia a mis aplicaciones mediante

SQL Server Data Mining

SQL Server

Francisco González eses Data Platform

Architect del área deBusiness Intelligence

en Solid Quality Men-tors. Francisco es

ponente habitual eneventos como BI

Conference o Tech-EdUSA y un enamora-do de la minería de

datos.

La minería de datos se puede utilizar para analizar información y realizarpredicciones. En este artículo voy a ilustrar el uso de la minería de datosen una aplicación Web. Vamos a tomar los datos de venta de un portal Weby cierta información de nuestros clientes para analizar qué productos ofre-cer a determinados perfiles de clientes, realizar campañas publicitarias uofrecer productos que sean comprados conjuntamente cuando un clien-te agrega un producto a la cesta de la compra.

Francisco González

Figura 1. Proceso de minería de datos

Page 41: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

41

dnm.servidores.sql<<

tando, estamos tratando de deducir cuálva a ser la conducta de un usuario, oqué tipo de clientes compran determi-nados productos; esto significa que elresultado de una predicción puede sererróneo.

En un modelo de minería de datos,llamamos fiabilidad al grado de seguri-dad en que las predicciones van a sercorrectas. Una de las técnicas que utili-zamos para saber cuál es la fiabilidad deun modelo generado es probarlo condatos que no han sido utilizados paragenerar dicho modelo. Un ejemplo deesta técnica es el siguiente: utilizamos el80% de los datos para generar el mode-lo; una vez generado éste, usamos el 20%restante para realizar predicciones ycomprobamos si cada predicción ha sidorealizada con éxito o no. Teniendo elnúmero de veces que el modelo ha acer-tado y el número total de casos, pode-mos sacar un porcentaje; en este caso,hemos supuesto que los datos contienenel resultado del valor que vamos a pre-decir. Los datos para este ejemplopodrían haber sido el perfil de clientesy si compraron un determinado pro-ducto o no, de forma que, utilizando elmodelo, podríamos predecir si el pro-ducto será comprado en base a atribu-tos como edad, sexo, número de hijos,número de coches, sueldo, distancia altrabajo, localización, etc.

Minería en nuestra tienda on-lineA través de una serie de ejemplos,vamos a explorar qué nos ofrece laminería de datos mediante SQL Ser-ver para mejorar las ventas de nuestroportal Web. Es conocido por todos queun buen diseño de una página Webhace que los clientes vuelvan una y otravez; mediante minería, vamos a sercapaces de ofrecer a nuestros clientesesos productos que están predispuestosa comprar, o quizás justo al revés, esosproductos que nunca buscarían y quizássi se los mostramos en un primer pla-no accedan a comprar, puesto que losproductos que el cliente está predis-puesto a comprar van a ser buscadospor él inmediatamente.

Minería para nuestros ban-ners o anunciosUn banner es un medio publicitario den-tro de nuestra Web que se ofrece alcliente en las propias páginas. ¿Cómoseleccionamos el banner a utilizar encada página? Pues por lo general cam-biamos los banners en el tiempo siguien-do reglas de marketing, o exponiendolos nuevos productos o los productosestrella de nuestra tienda. Ahora, gra-cias a la minería de datos, podemos irmás allá. Cuando un usuario se conec-ta a nuestra Web, en muchos casos seidentifica; una vez que el usuario se haregistrado, ya sabemos quién es, puesquizás cuando se dio de alta nos facilitódatos como edad, sexo, ciudad, salario,número de hijos, número de coches,intereses, etc. Además, quizás haya com-prado en nuestro portal anteriormente,con lo que ya tenemos suficiente infor-mación para ofrecer a nuestros clientesuna campaña publicitaria eficiente.Podemos utilizar algoritmos como el deárboles de decisión para analizar quéproductos son comprados por el perfilque acaba de entrar en la Web. De estaforma, si un tipo de cliente suele com-prar ciertos productos, lo que hacemoses utilizar la información que tenemosdel cliente para determinar qué pro-ductos ofrecer en nuestros banners. Asícuando el cliente se registra en el por-tal ya le aparecen banners con los pro-

ductos que el modelo ha estimado quepodría comprar. Además, podemos ele-gir que solo se le ofrezcan productosque no ha comprado todavía, gracias aque tenemos su historial de compras.

Para ofrecer esta solución, reali-zaríamos los siguientes pasos: utilizaría-mos los datos de compra de todos nues-tros clientes para crear un modelomediante el algoritmo de reglas dedecisión que nos estime la probabilidadde compra, con respecto a los atributosdel cliente y de los productos de nues-tro catálogo. Una vez que tenemos elmodelo generado, debemos realizar unaconsulta desde la página Web al mode-lo, para que nos ofrezca los productoscon mayor probabilidad de compra parael cliente que está accediendo a nuestraWeb. Descartamos los productos que yahan sido comprados por el cliente; enalgunos casos es lógico que no vuelva acomprar un determinado producto queya ha comprado anteriormente. Cuan-do sabemos el producto que queremospublicitar, accedemos a la base de datosde banners para obtener el banner y mos-trarlo en pantalla.

En la figura 2 se muestra la red dedependencia de los atributos de unmodelo construido para predecir si uncliente es comprador de bicicletas o no.Este diagrama nos indica qué atribu-tos son más determinantes a la hora deque un cliente compre una determina-da bicicleta.

Figura 2. Diagrama de dependencia de atributos

Page 42: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

42

dnm.servidores.sql<<

El código del listado 1 ilustra el len-guaje DMX para realizar consultas a unmodelo. Éste es el código que utili-zaríamos para realizar una prediccióncuando un determinado cliente seconecta a nuestra tienda online. Lasiguiente consulta nos devuelve una pro-babilidad ajustada acerca de si el clien-te en particular, para el cual hemosintroducido los datos en este ejemplo,compraría una bicicleta o no.

Minería para nuestra campañade publicidad postal

Imaginemos ahora que acaba de entrarun producto nuevo en nuestro stock ydisponemos de un presupuesto ajusta-do para realizar una campaña publici-taria, en la que vamos a enviar correopostal con información sobre dichoproducto. En nuestra base de datostenemos registrados 100.000 clientes,pero solo podemos enviar cartas a25.000. ¿A cuáles de nuestros clientesenviamos las cartas publicitarias? Paracontestar esta pregunta, vamos a utili-zar minería de datos. Lo primero quevamos a hacer es preguntar a nuestrosclientes acerca de si comprarían eseproducto o no. Para ello, realizamosuna encuesta donde básicamente obte-nemos de nuevo la información quetenemos en el registro de clientes, más

una última pregunta que es si com-prarían este nuevo producto. Nuestroobjetivo, en este primer paso, es obte-ner una población representativa detodos nuestros tipos de clientes paraofrecerles la encuesta; para ello, utili-zamos el algoritmo de clusters que nosdefine distintos grupos de clientes. Deesta forma, elegimos clientes de cadagrupo para realizar el sondeo, tenien-do entonces clientes de cada uno de los

grupos de perfiles de nuestros clientes.En la figura 3 se muestra el diagramade clusters que genera la ejecución delmodelo.

Una vez que hemos realizado laencuesta, tenemos una fuente de datosque nos sugiere qué clientes compraríandicho producto. Estos datos los utiliza-mos para crear un nuevo modelo don-de lo que hacemos es predecir si el pro-ducto va a ser comprado o no de acuer-do a los atributos del cliente; generadodicho modelo, podemos ejecutarlo paracada uno de nuestros clientes en la basede datos, seleccionando los 25.000 quetienen una probabilidad mayor de com-pra. De esta manera, enviamos nuestrapublicidad a aquellos clientes con unamayor predisposición de compra, obte-niendo quizás (pues no olvidemos quenos estamos basando en predicciones)un mayor retorno de la inversión.

Minería para cesta conjuntaCuando un cliente inserta un productoen el carrito de la compra, podemosofrecerle productos relacionados o quesuelen comprarse conjuntamente con elya elegido. Es muy probable que si com-pramos cuchillas de afeitar, compremostambién espuma y bálsamo. Vamos ailustrar aún más este ejemplo: una cono-cida cadena de productos alimenticioshizo un estudio, en el cual concluyó queen un alto porcentaje de casos cuandose compraban pañales también se com-praba cerveza. Sin entrar en detalles de

Figura 3. Diagrama de clusters

SELECT[v Target Mail].[Bike Buyer],PredictA djustedProbability([v Target Mail].[Bike Buyer])

FROM[v Target Mail]

NA TURA L PREDICTION JOIN(SELECT 25 A S [A ge],‘02/02/1978 0:00:00’ A S [Birth Date],‘2-5 Miles’ A S [Commute Distance],‘High School’ A S [English Education],‘S’ A S [Marital Status],2 A S [Number Cars Owned],3 A S [Number Children A t Home],30000 A S [Yearly Income]) A S t

Listado 1. Ejemplo de consulta DMX

Page 43: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

43

dnm.servidores.sql<<

por qué esto sucede, lo que sí es cierto es que algu-nos productos se compran frecuentemente de mane-ra conjunta, por lo que ofrecer al cliente, justo des-pués de introducir un producto en la cesta de la com-pra, productos que suelen comprarse conjuntamen-te con éste, mejora la experiencia del comprador eincrementa las ventas de nuestro portal. Vamos a uti-lizar minería de datos para realizar dicha tarea. Enprimer lugar, disponemos del historial de compra decada cliente cada vez que ha visitado nuestra tienda,por lo que disponemos de listas de productos que sehan comprado a la vez. Ésta va a ser nuestra fuentede datos. Para obtener un modelo de estas carac-terísticas, utilizamos el algoritmo de reglas de aso-ciación. Este algoritmo recibe como entrada una lis-ta de productos y nos devuelve la probabilidad decada uno de los productos que son comprados con-juntamente. De forma que, cuando un producto esañadido a la cesta de la compra, hacemos una con-sulta al modelo para que nos devuelva, por ejemplo,los dos productos que tienen una probabilidad mayorde ser comprados conjuntamente con ése, y se losofrecemos al cliente. Cuando el cliente añade otroproducto a la cesta, volvemos a consultar el modelo;pero esta vez le pasamos los dos productos que aca-ba de añadir, de manera que el modelo nos devuelvaproductos que se han comprado conjuntamente conrespecto a la lista total de productos en el carrito dela compra.

En la figura 4 podemos observar el conjunto dereglas que el algoritmo de reglas de asociación gene-ra. Como vemos, las reglas contienen listas de pro-

ductos que ya han sido añadidos a la cesta de la com-pra y la probabilidad de que un producto nuevo seacomprado conjuntamente con ellos.

Ciclo de vida de un desarrollo de mineríade datosDebido a que continuamente podemos estar agre-gando nuevos productos a la tienda y en nuestra Webse están procesando compras continuamente, nues-tros modelos pueden fácilmente quedar desactuali-zados en poco tiempo. Por ello, es necesario queapliquemos una política de actualización de los mode-los en el tiempo. Una de las formas más elegantes yproductivas de realizar dicho proceso es medianteSQL Server Integration Services. Gracias a SSIS,podemos generar un proceso que reprocese losmodelos cada cierto intervalo de tiempo. SSIS nosprovee con tareas específicas de minería de datos.De esta forma, podemos planificar mediante elAgente de SQL Server la actualización de nuestrosmodelos en el tiempo, obteniendo así prediccionesajustadas a los datos actuales y no quedando nues-tros modelos desfasados.

ConclusiónLos portales Web son uno de los tipos de negociosque mejor están acogiendo la minería de datos. Estoes debido a que, por ejemplo, en la gestión “tradi-cional” de publicidad no había ninguna forma de ele-gir un mejor banner para un determinado cliente.Simplemente se elegía uno al azar de entre el con-junto de banners disponibles. Al utilizar minería dedatos, podemos enfocar la publicidad al cliente; peroademás, no incurrimos en riesgo alguno si nuestromodelo falla, pues lo que teníamos sin minería erauna elección arbitraria. SQL Server nos provee unaplataforma robusta para el desarrollo de aplicacio-nes inteligentes.

Figura 4. Probabilidades de compra conjunta mediante elalgoritmo de reglas de asociación

SQL Server nos provee una plataforma robusta para el desarrollo de aplicaciones

inteligentes

Page 44: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

A diferencia de otros productos, Microsoft TeamFoundation Server (TFS) permite una amplia con-figuración para la personalización y adecuación anuestro proceso de desarrollo. Este artículo noslleva a las entrañas mismas de Team FoundationBuild (puedes consultar información más detalla-da en http://tinyurl.com/66w39v). Team FoundationBuild (a partir de ahora, TFB) es una extensión deTFS que se instala como un servicio. Se utilizapara la compilación de aplicaciones e infinidad detareas relacionadas con la generación de una ver-sión de una o varias soluciones. Algunas de las tare-as que permite realizar son la generación de uninforme de la compilación, la revisión del código,la publicación en servidores, entre otras.

Supongo que ya habréis leído el buen artículo deLuis Fraile sobre TFB del ejemplar nº 50 de dot-NetManía, y ya sabéis un poco como funciona.

La base de TFB es el fichero TFSBuild.proj. Estefichero está en formato XML y contiene toda lainformación necesaria para realizar el proceso degeneración (build). Por si alguien conoce el mun-do del código abierto, viene a ser lo mismo que elfichero build.xml de ANT. TFB ejecuta MSBuild,que interpreta las tareas definidas en el fichero TFS-Build.proj. Microsoft Build Engine (MSBuild) esla plataforma que utiliza Visual Studio para gene-rar las soluciones (más información en http://tin-

yurl.com/6og6bo). Cuando TFB recibe una peticiónde build, descarga el código definido en el entor-no de trabajo (o workspace) y también el script debuild, para interpretarlo y ejecutar todas las tare-as definidas.

Personalizando nuestras builds

ALManía

Enric Forn es MCTSTeam Foundation Ser-ver. Actualmente, Enric

es consultor de TeamSystem en Raona.

En muchas ocasiones, en el momento en que generamos la versión denuestra aplicación nos dejamos el último ensamblado añadido, la modi-ficación del fichero de configuración, o los PDB generados se encuen-tran en modo Debug. Team Foundation Build nos ayuda a simplificarestas tareas, mejorando el versionado de nuestros proyectos.

Enric Forn

Figura 1. Edición del fichero TFSBuild.proj con Team Foundation Sidekicks

Page 45: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

45

dnm.ALManía<<

Para modificar las tareas a ejecutar deuna build, es necesario modificar el fiche-ro TFSBuild.proj asociado a ella. En la ver-sión 2005 de TFB, este fichero se encuen-tra ubicado en $/TeamBuildTypesdentro delrepositorio de control de código. En laversión 2008, la ubicación deTFSBuild.proj puede ser cualquiera; porsupuesto, siempre dentro del repositoriodel control de código fuente.

Antes de editar este fichero, es nece-sario desprotegerlo manualmente desdeel Explorador de control de código fuen-te (lo que se conoce como check-out). Sieditamos este fichero desde Visual Stu-dio 2008 con SP1 instalado, el check-outes automático. Una vez hemos modifi-cado y validado el script de build, esimprescindible proteger el fichero en elrepositorio de control de código fuente(o lo que es lo mismo, hacer el check-in).

Para facilitar la edición de estefichero, existen las Team FoundationSidekicks (puedes descargarlas enhttp://tinyurl.com/623kf9). Son un con-junto de herramientas que, una vez ins-taladas, facilitan la administración deun servidor de TFS. Entre las herra-mientas hay una nueva opción de menúcontextual, que aparece al hacer clic conel botón derecho sobre nuestra defini-ción de build (figura 1).

Como he comentado en el párrafoanterior, siempre que queráis realizarun cambio en el fichero TFSBuild.projdebéis subirlo al control de código fuen-te de nuestro repositorio (check-in). Estohace que probar nuestras modificacio-nes sobre los scripts de build sea un pocolento.

Estructura básica de TFSBuild.projComo ya he dicho anteriormente, en elarchivo TFSBuild.proj se recogen todaslas tareas a realizar para la construcciónde nuestra versión. Para conocerlo conmás detalle, vamos a dividirlo en trespartes y comentar un poco las funcio-nes de cada una de ellas:

• Definición general del build. Enesta sección encontramos la confi-

guración global, es decir, los pará-metros que afectan a la ejecucióngeneral del build: en qué agente seejecuta (un agente es la máquina don-de se encuentra instalado el serviciode TFB), los directorios de desplie-gue, si se ejecutan tests con su fiche-ro de configuración, si se activa laejecución de análisis de código, entreotros. Un ejemplo básico se presen-ta en el listado 1.

• Configuración de la compilación.Aquí se definen cuáles son las solu-ciones que vamos a compilar y tam-bién las configuraciones. Se puededar el caso de que queramos generaruna versión “Release” para poderdesplegarla y realizar sobre ella prue-

bas funcionales, y una versión“Debug” específica para el desarro-llo (listado 2).

• Destinos (targets). En esta parte esdonde se exprime realmente lapotencia de TFB, pues se puedenrealizar infinidad de tareas concre-tas para cubrir las necesidades denuestra compilación o despliegue.MSBuild define un conjunto de tar-gets que realizan un conjunto de

tareas predefinidas (encontraréismás información sobre la bibliote-ca de tareas predefinidas enhttp://tinyurl.com/6acftf), y ademáspodemos definir nuestros propiosdestinos. Un destino define elmomento en que él se ejecuta, y

<Import Project=”$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets” />

<ProjectExtensions><Description></Description><BuildMachine>TEA MBUILD</BuildMachine>

</ProjectExtensions><PropertyGroup>

<TeamProject>Phoenix</TeamProject><BuildDirectoryPath>D:\Deploy</BuildDirectoryPath><DropLocation>\\TEA MBUILD\Deploy</DropLocation><RunTest>true</RunTest><RunCodeA nalysis>Never</RunCodeA nalysis><UpdateA ssociatedWorkItems>false</UpdateA ssociatedWorkItem><RunConfigFile>$(SolutionRoot)\Development\raona.teambuild.testrunconfig</RunConfigFile>

</PropertyGroup>

Listado 1. Definición general del build

<ItemGroup><SolutionToBuild Include=”$(SolutionRoot)\Raona\project1.sln” /><SolutionToBuild Include=”$(SolutionRoot)\Raona\project2.sln” />

</ItemGroup>

<ItemGroup><ConfigurationToBuild Include=”Release|A ny CPU”>

<FlavorToBuild>Release</FlavorToBuild><PlatformToBuild>A ny CPU</PlatformToBuild>

</ConfigurationToBuild></ItemGroup>

Listado 2. Configuración de la compilación

Page 46: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

46

dnm.ALManía<<

puede contener múltiples tareas.Todos los targets posibles se encuen-tran definidos en un fichero .tar-gets ubicado en la máquina que hos-peda el servicio de TFB. No esaconsejable modificar este fichero,ya que cualquier cambio afectaría atodos los scripts de build que tenga-mos implementados (a no ser queseamos usuarios muy experimenta-dos). Para que podáis verlo de unmodo más gráfico, se presenta unejemplo en el listado 3.

En el fragmento que se muestra en ellistado 3, extraído de un script de build,podemos ver que éste se está ejecutandoen el destino A fterDropBuild, es decir, des-pués de que TFB haya copiado todos losficheros de la compilación en el directo-rio de destino. En este momento, se rea-lizan tres tareas: la primera es la creacióndel directorio Development, mediante latarea MakeDir. La segunda tarea copia losficheros del destino definidos en el pri-mer elemento y copia todo su contenidoen el directorio de destino. Además, rea-liza una copia recursiva de todos los fiche-ros y subdirectorios contenidos en la raíz.Si eliminamos los “**” de la definición deldirectorio de origen y también la parte“%(RecursiveDir)” del directorio de desti-no, entonces solamente serían copiadoslos ficheros. Por último, en la tercera tarease ejecuta un comando de consola. Estatarea es muy interesante, ya que si noencontramos ninguna tarea predefinidacon la que llevar a cabo la acción que nosinteresa, seguramente encontraremos laforma de ejecutarlo a través de la línea decomandos.

Existen muchos targets que permitenejecutar tareas en cualquier momento de

la ejecución del build: justo antes o des-pués de descargar el código (BeforeGet yA fterGet), antes y después de compilar(BeforeCompile, A fterCompile). Los targetsmenos críticos para sobrescribir son Befo-re* o A fter*, ya que no afectan a las tare-as imprescindibles de ejecución de unabuild. En cambio, es más crítico sobres-cribir destinos como tareas como CoreGeto CoreDropBuild, ya que puede afectarnegativamente a la ejecución de nuestrobuild. Podéis consultar todos los targetsdisponibles en http://tinyurl.com/6kczfg.

Se puede dar el caso de que que-ramos modificar las acciones prede-finidas de un destino. Por ejemplo, esposible que queráis ejecutar un buildcon una versión concreta de códigofuente. Una posibilidad de modificarun target sin modificar el fichero .tar-gets de la máquina de build es ponerel código en el propio script de build.En el caso de la descarga del códigoque acompaña a este artículo, se defi-

ne el destino CoreGet (listado 4). Coneste ejemplo, el build ejecutado nodescarga la última versión de código,sino la versión etiquetada como“MiBuild_20080419.7”. Aún así, para rea-lizar este tipo de modificaciones, enprimer lugar, si podemos evitar sobres-cribir targets nos evitaremos proble-mas. Pero si nuestras necesidadesrequieren hacerlo, es importante tenerclaro si ello afecta solamente a nues-tro script de build o a todas las buildsejecutadas en el servidor donde modi-fiquemos el target.

<ItemGroup><SourceFiles Include=”$(SolutionRoot)\Development\**” />

</ItemGroup><Target Name=”A fterDropBuild”>

<MakeDir Directories=”D:\TCompilacio\Development” /><Copy SourceFiles=”@(SourceFiles)”

DestinationFolder=”D:\TCompilacio\%(RecursiveDir)” /><Exec Command=”NET USE T: \\TEA MBUILD\TCompilacio “ />

</Target>

Listado 3. Destinos del build

<Target Name=”CoreGet”Condition=” ‘$(IsDesktopBuild)’!=’true’ “DependsOnTargets=”$(CoreGetDependsOn)” >

<Get Condition=” ‘$(SkipGet)’!=’true’ “Workspace=”$(WorkspaceName)”Recursive=”$(RecursiveGet)”Force=”$(ForceGet)”Version=”$(VersionToGet)” />

</Target><PropertyGroup>

<VersionToGet>LMiBuild_20080419.7</VersionToGet></PropertyGroup>

Listado 4. Modificación de un target en el script de build

Un destino define elmomento en el que él se

ejecuta dentro del procesode build y puede contener

múltiples tareas

Page 47: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

47

dnm.ALManía<<

Crea tu propia tarea personalizadaPero si todavía no encontráis la formade llevar a cabo la tarea que queréis rea-lizar con las tareas predefinidas deMSBuild, es posible implementar vues-tra propia tarea personalizada en .NET(podéis consultar MSDN en http://tin-yurl.com/67d2yq). Vamos a crear una tareapersonalizada que simplemente nece-sita un parámetro que es la ruta de unfichero plano. La tarea escribe un tex-to en el fichero y lo almacena. Tenemosdos opciones:

• Implementar directamente la interfazITask sobre nuestra clase. ITask estáimplementada en Microsoft.Build.Fra-mework.dll.

• Derivar nuestra clase de la clase auxi-liar Task (que encontraréis en Micro-soft.Build.Utilities.dll). Esta claseimplementa la interfaz anterior, yademás proporciona implementa-ciones por defecto de algunos de losmétodos de ITask.

En el método Execute, que tendre-mos que sobrescribir, es donde se imple-menta el código que queremos ejecutar.Este método no necesita parámetros, ydebe devolver true si la tarea se ejecutacorrectamente, o false en caso contra-rio. En nuestro ejemplo (listado 5), y porcomodidad, utilizamos la clase Task.

Una vez hemos implementado elcódigo, será necesario configurar nues-tro script de build como se muestra enel listado 6, para que se realice correc-tamente la llamada. En la primera par-te registramos la tarea de modo que elscript de build sea capaz de encontrarla clase a ejecutar. Fijaros que no tie-

ne ruta; la razón es que la DLL com-pilada se encuentra en el control decódigo fuente de nuestro repositorio,justo en la misma carpeta donde seencuentra nuestro script de build. Siqueréis probar este ejemplo, deberéisañadir la DLL y realizar el check-in enla carpeta donde se encuentra el fiche-ro TFSBuild.proj. En la segunda parte,solamente nos queda llamar la tarea enel destino que nos interese, en este casojusto después de compilar las solucio-nes. Este destino tiene la particulari-

dad de que solamente se ejecuta si lacompilación de las soluciones se harealizado satisfactoriamente. Unapequeña observación a hacer sobre lallamada a la tarea es el paso por pará-metro de la ruta del fichero. En unatarea se pueden definir n parámetros,eso sí, siempre como cadenas de carac-teres. También comentar que la rutadel fichero es relativa a la ubicaciónde los ficheros compilados, lo queindica la variable BinariesRoot. Ademásde esta variable, existen muchas otrasque podéis encontrar en http://tin-yurl.com/5l9947.

Compilación de proyectos deVisual Basic 6.0En algunos de nuestros proyectos convi-ven aplicaciones desarrolladas en distin-tos lenguajes. Es por esta razón que en elscript de build implementado para nues-

using Microsoft.Build.Framework;using Microsoft.Build.Utilities;using System.IO;using System.Diagnostics;

namespace CustomTasks{

public class HelloWorldTask : Task{

private StreamWriter sw;

[Required]protected string filename;public string FileName{

get { return filename; }set { filename = value; }

}public override bool Execute(){

sw = new StreamWriter(Path.Combine(filename), true);sw.WriteLine(“Hello World !!”);sw.Flush();sw.Close();

return true;}

}

}

Listado 5. Código de la tarea personalizada

<UsingTask TaskName=”CustomTasks.HelloWorkdTask”A ssemblyFile=”HelloWorldTask.dll” />

<Target Name=”A fterCompile”><!—Deploy Phoenix Version—><HelloWorldTask FileName=” $(BinariesRoot)\HelloWorldFile.txt” />

</Target>

Listado 6. Llamada a la tarea personalizada

Page 48: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

48

dnm.ALManía<<

tro proyecto se compilan varios proyec-tos de lenguajes diferentes: C#, C++ yVisual Basic 6.0. Los proyectos de los dosprimeros lenguajes no tienen ningún pro-blema en ser compilados por TFB. Sinembargo, al intentar compilar Visual Basic6.0, la compilación fallará. Es cierto quepodríamos compilar el proyecto directa-mente mediante un elemento <Exec>:

En mis scripts de build utilizomucho el comando Exec. Lo utilizopara mapear unidades de red, regis-trar librerías DLL de COM, o ejecu-tar cualquier comando de la míticaplataforma MS-DOS.

Otro método para compilar proyec-tos de Visual Basic 6.0 consiste en utili-zar un target definido por FreeToDev (loencontraréis en la URL http://tin-yurl.com/5t57jm). Con este target se pue-den agrupar todos los proyectos de VB6.0 a compilar. También es posible asig-nar una ruta de destino de los nuevos eje-cutables. Primero, es necesario instalar eltarget en la máquina que ejecuta TFB. Acontinuación, añadimos la importacióndel nuevo target, mediante el elemento<Import> (listado 8). Finalmente, es nece-sario indicar los proyectos de Visual Basica compilar, definir el target Execute y eje-cutarlo después de la compilación.

Ejecución de tests sin utilizarlos ficheros .vsmdiOtra tarea muy importante es la eje-cución de los tests unitarios para vali-dar la compilación de nuestros pro-yectos. Solamente daremos como rea-lizado satisfactoriamente el build si seejecutan correctamente los tests uni-

tarios. Una pequeña personalizaciónque tenemos a nuestra disposiciónconsisten en ejecutarlos prescindien-do de los engorrosos ficheros .vsmdi(más información en http://tin-yurl.com/5uvgen). En la configuraciónde las propiedades de la build, es nece-sario indicar la ruta del fichero Tes-tRunConfig (listado 9). Y para indicarcuál es la DLL que contiene los tests,es necesario indicarlo al final delscript.

Si observáis con atención el códigodel listado 9, veréis que existe una con-dición, ya que si compilas múltiplessoluciones en un mismo script, y cadasolución tiene su DLL con sus respec-tivos tests, TFB ejecutará todos los testspara todas las DLL. De esta forma, con-seguimos ejecutar los tests exactos paracada solución.

ConclusiónEn definitiva, si conocemos bien laherramienta y tenemos claro cómo esnuestro proceso de despliegue de lasaplicaciones, TFB nos ahorra tiempotanto en la construcción del paquetede distribución de la aplicación, comotambién en la supervisión de la cali-dad del código, ya sea con la ejecu-ción de test unitarios o el análisis decódigo. Cada vez más, la figura delgestor de la configuración tomamayor importancia en un equipo dedesarrolladores, ayudando a aumen-tar la velocidad y fiabilidad de des-pliegue de las aplicaciones, y tambiénmejorando la calidad del código des-plegado.

<Exec Command=”C:\Program Files\Microsoft Visual Studio\VB98\VB6.exe /MA KE &quot;C:\LogFile.vbp.log&quot; &quot;C:\Project.vbp&quot;” />

<RunConfigFile>$(SolutionRoot)\Common\Teambuild.testrunconfig</RunConfigFile><ItemGroup>

<TestContainerInOutput Condition=”’$(SolutionToBuild)’==’Raona’ “Include=”Raona.UnitTest.dll” />

<TestContainer Include=”$(BinariesRoot)\Release\Raona.UnitTest.dll” /></ItemGroup>

Listado 9. Ejecución de tests unitarios

<Import Project=”$(MSBuildExtensionsPath)\BuildVB6\FreeToDev.MSBuildTasks.tasks” /><ItemGroup>

<ProjectsToBuildInclude=”$(SolutionRoot)\Core\DevelopmentCore\ComPhoenix\ComPhoenix.vbp”>

<OutDir>$(BinariesRoot)\Release</OutDir></ProjectsToBuild>

</ItemGroup>

<Target Name=”Execute”><BuildVB6 Projects=”@(ProjectsToBuild)” />

</Target><Target Name=”A fterCompile”>

<CallTarget Targets=”Execute” /></Target>

Listado 8. Compilación de VB6 con FreeToDev

Listado 7

Otra tarea muy importantees la ejecución de los

tests unitarios para validar la compilación de nuestros

proyectos

Page 49: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 50: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Dinámico, estático, ¿cuál es la diferencia?

En el contexto de este artículo, dinámico y estáticose puede aplicar de dos formas, uno haciendo refe-rencia a los tipos de datos y otro a los lenguajes.

Cuando se habla de dinámico y estático haciendoreferencia a los tipos de datos, estático significa quelos tipos de datos solo soportan los elementos que ellosdefinen; es decir, solamente podemos acceder a losmétodos, propiedades, etc., que estén definidos en eltipo. Por otro lado, dinámico significa que sin nece-sidad de conocer de antemano el tipo de datos queestamos usando, podamos acceder a cualquiera de losmiembros (métodos, propiedades, etc.) que ese tipodefina (no confundamos esto con el polimorfismo, quesi bien se puede parecer no es exactamente lo mismo).Aunque otra interpretación puede ser que esos tipos

dinámicos no son específicos, sino que un mismo tipo(que en realidad ni es un tipo) soporta cualquier valor,algo parecido al tipo Variant de COM (o de VB6). Ypor último, si ese tipo dinámico es producido por unlenguaje orientado a objetos, posiblemente sea unareferencia a un objeto de un tipo que se ha inferidosegún el valor asignado, algo parecido a lo que hacenVB.NET y C# con la inferencia de tipos; la diferen-cia estará que los lenguajes estáticos habrán definidoesas variables con un tipo de datos, mientras que loslenguajes dinámicos no suelen tener la necesidad (nila obligación) de definir las variables.

Cuando dinámico y estático se aplican a los len-guajes (para simplificar), estático significa que el len-guaje utiliza tipos estáticos, es decir especificacionesconcretas para cada tipo de datos, mientras que los len-guajes dinámicos no necesitan definir esos tipos de datos,ya que suelen inferirse y el intérprete (los lenguajes diná-micos suelen tratarse como los lenguajes de script, y éstossuelen ser interpretados en lugar de compilados) infe-rirá el tipo según el valor asignado.

En el resto del artículo nos centraremos en lostipos de datos más que a los lenguajes.

Visual Basic y los tipos dinámicosA los lectores que conozcan o hayan usado alguna ver-sión de Visual Basic (da igual si es para .NET o no),todo lo comentado seguramente les sonará de algo.Simplificando, podríamos decir que el acceso dinámi-co a los miembros de un objeto es lo que llaman en

Isla VB

Guillermo “Guille”Som

Es Microsoft MVP deVisual Basic desde 1997.Es redactor de dotNet-Manía, mentor de SolidQuality Mentors, tutor

de campusMVP, oradorde Ineta Latam y autor

de los libros “ManualImprescindible de Visual

Basic .NET”, “Visual Basic2005”, "Novedades de

Visual Basic 9.0" y“Aprenda C# 3.0 desde0.0 - Parte 3, lo nuevo”.

http://www.elguille.info.

En la próxima versión de .NET Framework (la 4.0) se incluirá lo que se cono-ce como DLR (Dynamic Language Runtime), que viene a ser el motor de eje-cución de los lenguajes dinámicos de .NET. De esa forma, se permitirá al CLR(y por extensión a los lenguajes como VB y C#) el acceso de forma dinámi-ca a los miembros de los objetos que haya en memoria, algo parecido a loque siempre se ha conocido como late binding... o casi...

Guillermo «Guille» Som

Visual Basic¿lenguaje dinámico?

Guillermo Som ingresará los derechos de autor deeste artículo en la cuenta de Ayuda a Juanma a vivir.Desde aquí, invita a los lectores de esta isla solida-ria para que hagan sus aportaciones o participen enlas subastas que se realizan desde la Web de Juan-ma para recaudar fondos con el fin de ayudar en lainvestigación de una cura para la enfermedad deAlexander. http://www.ayudajuanma.es.

Isla solidaria

Page 51: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

51

dnm.isla.vb<<

inglés late binding (enlace tardío) y el acceso estático loque se conoce como early binding (enlace temprano),algo que en Visual Basic siempre ha existido.

El enlace estático (o temprano) solo permite acce-der a los miembros “conocidos” del tipo, es decir, losmiembros que esa clase (o tipo) defina; esto está bien yes lo que siempre nos han recomendado (cuando los queahora lo recomendamos estábamos aprendiendo), entreotras cosas porque la ejecución es más rápida y sobretodo menos propensa a errores. Incluso hay lenguajescomo C# que solo permiten esta forma de enlace, almenos hasta ahora, ya que su próxima versión (la 4.0) síque soportará el enlace dinámico además del estático.

Por otra parte, el enlace dinámico (o tardío) nospermite hacer referencia a miembros que no existen enel tipo de datos que estamos usando. Para que esto seaposible, el tipo debe ser de uso general (en .NET detipo Object, ya que todos los tipos de .NET se derivande ese tipo básico). Es decir, el compilador aceptará elacceso a ese miembro que no está definido en el tipode datos y será en tiempo de ejecución cuando se com-pruebe si ese miembro está realmente definido; por esolo de “enlace tardío”, ya que hasta que no se ejecuteese código no se podrá comprobar el tipo de datos querealmente tiene ese “objeto”. Aclarar que actualmen-te este tipo de enlace tardío en los lenguajes de .NETsolo se permite en Visual Basic, pero no en C#, aun-que esto cambiará en la próxima versión.

En el listado 1 podemos ver cómo acceder a un méto-do inexistente en la clase Object, pero que en realidad elobjeto referenciado por la variable obj1 sí que define, ypor tanto este código funcionará perfectamente. La sal-vedad es que si estamos usando Visual Basic 2008, ademásde usar Option Strict Off, también deberíamos desac-tivar la inferencia automática de tipos, con idea de quepor defecto las cosas se hagan como se deben hacer (defi-niendo expresamente la variable del tipo de datos queva a contener); por tanto, lo mejor es definir expresa-mente la variable obj1 como de tipo Object. El métodoMostrar usado desde la variable obj1 está definido en laclase MiClase, por tanto la llamada a ese método fun-cionará cuando se ejecute la aplicación.

Si el lector piensa que lo correcto hubiera sido decla-rar la variable obj1 del tipo MiClase, decirle que estaríaen lo cierto, pero aquí he usado esa clase para que lavariable tuviera algo, ya que lo habitual es que ese valorse obtuviera de alguna forma en la que no tengamos for-ma de comprobar que en realidad tiene ese valor, comopodría ser si esa variable se asignara mediante una lla-mada a CreateObject, tal como vemos en el listado 2.

La desventaja de usar el enlace tardío radica en elhecho de que el compilador no hace ninguna compro-bación de que ese miembro realmente esté definido enel tipo de datos, y por tanto es posible que el código falleen tiempo de ejecución, y ya sabemos que no hay nadapeor que nuestra aplicación falle cuando esté ejecután-dose en el equipo de nuestros clientes.

Dim obj1 A s Object

‘ A signamos a la variable un nuevo objeto ‘ del tipo MiClaseobj1 = New MiClase With {.Nombre = “Mi clase 1”}

‘ El tipo MiClase define el método Mostrar‘ por tanto es correcto hacer esta llamadaobj1.Mostrar(“Esta es”)

Listado 1. Debemos tener desactivado Option Strict paraque este código funcione

Dim obj2 A s Object

‘ Creamos un objeto del tipo Word.A pplicationobj2 = CreateObject(“Word.A pplication”)

‘ A ntes de acceder al objeto,‘ debemos asegurarnos de que Word está disponibleIf obj2 IsNot Nothing Then

Console.WriteLine(obj2.A ctivePrinter)

‘ Si llamamos a un método inexistente, ‘ dará error obj2.Mostrar(“Hola”)

End If

Listado 2. Ejemplo de enlace tardío usando CreateObject

El DLR (principalmente la forma de gestionar los tipos de los lenguajes dinámicos y los de loslenguajes estáticos) permitirá que los lenguajes “clásicos” (y estáticos) de .NET como VB.NETy C# puedan interactuar con otros lenguajes (los llamados dinámicos) como Python, Ruby(ambos nombrados con el prefijo Iron, al menos en las versiones implementadas por Micro-soft) e incluso JavaScript (la versión dinámica), y precisamente la necesidad de permitir usarlos tipos dinámicos está justificada por la dificultad (o complicación) que supone el uso de obje-tos creados con los lenguajes dinámicos desde lenguajes estáticos.

[ ]NOTA

Page 52: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

52

Por otro lado, hay situaciones en las que puedeser útil usar ese enlace dinámico, normalmente cuan-do usamos otros objetos que no proceden del propio.NET Framework, por ejemplo si usamos objetosCOM procedentes de aplicaciones como Office, talcomo acabamos de ver en el listado 2.

Visual Basic puede ser no estricto, perono es dinámicoTal como están las cosas actualmente, y de forma pre-determinada (algunos seguimos lamentando que estosea así), Visual Basic no es estricto a la hora de hacerconversiones o de acceder a los miembros de un obje-to; es decir, se puede utilizar el enlace tardío a la horade acceder a los miembros que no estén definidosexpresamente (estáticamente) en un tipo en particu-lar. Pero esto no significa que Visual Basic sea diná-mico en el aspecto de permitir acceder dinámicamentea los miembros de un objeto, sino que lo simula y ala larga se obtienen los mismos resultados.

La única forma de permitir que Visual Basic simu-le ser un lenguaje dinámico (en lo referente a acce-der dinámicamente a los miembros de un objeto) esdesactivando Option Strict. El problema es que estoes algo que muchos no recomendamos que se haga,y esperemos que no se justifique el hacerlo por lanecesidad de acceder dinámicamente a los miembrosde un tipo del que no tenemos la información de losmiembros que expone públicamente.

Ámbitos de Option Strict

Afortunadamente, Visual Basic nos permite usarOption Strict (ya sea activado o desactivado) a dosniveles, y el nivel más bajo (o reducido) en el que sepuede utilizar es a nivel de fichero de código; es decir,podemos restringir la comprobación no estricta soloen el código que esté definido dentro de un ficherode código. Esto, unido a que podemos definir clasesparciales, nos permite definir en esos ficheros de códi-go solo aquellas partes de nuestros tipos que necesi-ten que la comprobación estricta del código no estéactivada, ya que es esa comprobación estricta que sehace al tener activado Option Strict la que no nos per-mite acceder a miembros de un objeto que no esténdefinidos en el tipo de ese objeto, o sea cuando usa-mos lo que ahora se llama acceso dinámico.

El otro ámbito de Option Strict es a nivel de pro-yecto, ya que podemos indicar que, por ejemplo, cier-to estado esté activado en todo el proyecto. De estaforma, si no indicamos expresamente el estado de estaopción de comprobación estricta, siempre estará acti-vado o desactivado, dependiendo del valor que haya-

mos dado en las opciones del proyecto. Tal y comohemos visto en el párrafo anterior, cuando necesite-mos desactivar esa comprobación estricta lo podre-mos hacer a nivel de fichero de código; de esa forma,solamente en ese fichero se dejará de hacer las com-probaciones que el compilador hace cuando asigna-mos el valor On a Option Strict.

Recapitulando sobre Option Strict

A título de recordatorio (así valdrá para aquelloslectores que no suelen utilizar Visual Basic y por tan-to puede que no sepan para qué sirve esta instrucción)activando Option Strict el compilador nos obligará adefinir todas las variables con un tipo de datos ade-cuado; además, a la hora de asignar un valor a esasvariables se comprobará que el tipo de datos asigna-do es el mismo que el de la variable que recibe el valoro se puede convertir de forma implícita (automática-mente). Y cuando estamos asignando valores entrevariables de distintos tipos de datos, también se com-probará si se puede hacer de forma implícita o se nece-sita hacer una conversión explícita (cast); en este últi-mo caso, la presencia en el código de esa conversiónexplícita nos pondrá en alerta de que es posible quedicha conversión falle y por tanto tengamos cuidadocon ese código, ya que según la Ley de Murphy, sialgo puede fallar, seguro que fallará.

Cuando instalamos Visual Studio (o Visual BasicExpress) el valor predeterminado de Option Strict esOff, es decir, desactivado; por tanto, todas estas com-probaciones que he comentado antes no se hacen. Deesa forma, podemos declarar variables sin necesidad deindicar de qué tipo son y asignarles valores de cualquiertipo. Esto es posible ya que esas variables en realidadson de tipo Object y este tipo de datos acepta cualquiervalor; por tanto, podremos asignar cualquier valor a unavariable que sea de tipo Object.

dnm.isla.vb<<

El enlace dinámico puede ser útilcuando usamos objetos que no

proceden del propio .NET Framework, como los objetos

COM de Office

Page 53: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

¿Qué problema hay al usar OptionStrict Off?

Problema, lo que se dice problema,no hay ninguno. De hecho, mucha gen-te piensa que incluso es mejor tener des-conectada esa opción, ya que así no tene-mos que preocuparnos en hacer con-versiones entre tipos ni tener que decla-rar las variables con un tipo de datosdeterminado. Pero no nos engañemos:está demostrado que una programacióncon tipos de datos concretos es más efi-ciente que una que utilice tipos de datosmás generalizados (por no decir “gené-ricos”, que se podría confundir con lostipos generic), y todo el trabajo que nosdará tener que hacer las conversionesde forma explícita nos ayudará a saberqué es lo que estamos haciendo y (comodije antes) alertarnos de que algo pue-de ir mal al hacer la conversión. Y es queel compilador de Visual Basic a la horade hacer las conversiones entre tiposdiferentes de datos lo hará casi de la mis-ma forma que lo haremos nosotros, peroserá más difícil de saber que se puedeproducir un fallo al convertir entre esosdos valores si no vemos que ahí se estáhaciendo una conversión.

Los tipos dinámicos en .NETFramework 4.0Aunque aún está en una fase muy tem-prana de desarrollo (a la hora de escri-bir este artículo solo está disponible laprimera CTP), .NET Framework 4.0incluirá soporte para los tipos dinámi-cos, ya que también permite medianteel DLR la integración con lenguajesdinámicos y por tanto, se podrá inter-cambiar información entre esos len-guajes y los denominados estáticos.

Para permitir la utilización de lostipos dinámicos en lenguajes como C#(que son muy estrictos), se ha tenidoque hacer uso de una nueva forma dedefinir esos tipos dinámicos, ya que elcompilador no debe comprobar si losmiembros que se aplican a ese objetoestán definidos o no; al menos, esa com-probación no se hará en tiempo de com-pilación, si no que será en tiempo de

ejecución cuando se compruebe si real-mente el objeto asignado a esa variabledinámica soporta ese método o pro-piedad que se está usando. En C# 4.0se definirá un tipo dinámico con la pala-bra clave dynamic; en cuanto el compi-lador se encuentre con esa declaración,sabrá que debe aplicar late binding a esavariable, y por tanto no hacer ningúntipo de comprobación hasta que se estéejecutando el código.

En el listado 3 vemos un ejemploparecido al del listado 1, solo que enesta ocasión estamos usando código deC# 4.0 y particularmente de la instruc-ción dynamic y lo que el uso de esa ins-trucción supone: enlace tardío.

En Visual Basic no se ha añadidoninguna nueva instrucción para definireste tipo de variables dinámicas, ya queVisual Basic permite usar ese modo“retardado” de comprobación si se uti-liza Option Strict Off.

Pero no nos confundamos: eso no esun tratamiento dinámico de los tipos dedatos, ya que en realidad, para permitirque todo esto sea posible, se ha agregadouna nueva interfaz para definir estos tiposdinámicos; esa interfaz es IDynamicObject,que está definida en el espacio de nom-bres System.Scripting.Actions, y VisualBasic no utiliza esta interfaz, sino que sim-plemente hace lo que ha estado hacien-do durante muchos años: esperar a quellegue el momento de la ejecución delcódigo, y en ese preciso momento escuando comprueba si el objeto define ono ese método (o cualquier otro miem-bro al que queramos acceder). Si lo defi-ne, bien; si no lo define, mal y de regalouna excepción.

¿Será Visual Basic un lenguajedinámico?

Tal como están las cosas, la respuestaes no. Al menos en lo que se refiere alos tipos dinámicos, ya que la intenciónes que llegue a serlo, es decir, que vuel-va a ser un lenguaje de script o casi, yaque ahora a ese tipo de lenguajes se lesllama dinámicos. Pero todo esto lo com-probaremos más adelante, cuando lapróxima versión de Visual Basic (y de.NET Framework) esté más madura.Mientras tanto, contentémonos con loque tenemos y aprovechémoslo; en estaisla seguiré explicando cosas para apro-vechar mejor este lenguaje.

Conclusiones

En este artículo hemos hablado sobrealgo que en los próximos meses (oaños) seguramente será algo más habi-tual: los tipos y lenguajes dinámicos.Pero como hay que estar en la reali-dad, también hemos visto (aprove-chando la coyuntura del tema) cómoVisual Basic puede ser dinámico o loque es lo mismo, menos estricto conlos tipos de datos que utilizamos ennuestras aplicaciones. Confío en queel lector sepa con más certeza que esaforma de dinamismo no es la másrecomendable, salvo que realmentesepamos qué es lo que estamoshaciendo, y en que después de estalectura el lector sabrá qué es lo quehace en cada momento, o al menossabrá cómo ser estricto a la hora deescribir el código o no serlo, si así loconsidera oportuno.

dotN

etM

anía

<<

53

dnm.isla.vb<<

dynamic obj1;

// A signamos a la variable un nuevo objeto del tipo MiClaseobj1 = new MiClase { Nombre = “Mi clase 1” };

// El tipo MiClase define el método Mostrar// por tanto es seguro hacer esta llamadaobj1.Mostrar(“Esta es”);

Listado 3. Código equivalente del listado 1 para usar con C# 4.0

Page 54: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Personalmente, he estado un tanto remiso a empe-zar con Entity Framework, y he comenzado aestudiarlo sólo un poco antes de la salida de suversión 1.0. Por el contrario, he estado haciendoun montón de cosas con LINQ to SQL, a plenasatisfacción, desde el comienzo. Hay que decirque cambié de opinión repetidamente respecto aLINQ to SQL. Al principio, me parecía como unADO.NET, pero muy mejorado. Concretamen-te, me parecía una especie de ADO.NET capazde trabajar con objetos fuertemente tipados enlugar de las clásicas colecciones de filas y colum-nas (débilmente tipadas).

Según esto, comencé por abordar el trabajo conLINQ to SQL en la parte donde normalmente tra-tamos con los datos físicos. Simplemente, sustituíla persistencia de ADO.NET por la de LINQ toSQL. Inmediatamente, me di cuenta de que ambosno eran intercambiables sin más. Una capa deLINQ to SQL dialoga con su contrapartida utili-zando su propio modelo de objetos. Para desco-nectar uno e insertar el otro necesitas un trabajode adaptación entre los tipos de datos que se inter-

cambian. Si la capa intermedia está basada en Data-Sets, hay que convertir los objetos LINQ to SQLa éstos últimos, lo que puede resultar sorprenden-te, ya que la maquinaria de LINQ to SQL carga abajo nivel streams de ADO.NET directamente enel modelo de objetos.

Por otra parte, no parece una buena idea cam-biar toda la capa de datos de un sistema existen-te solo por que exista una nueva tecnología dis-ponible. Si, en lugar de eso, evalúas LINQ to SQLpara un nuevo proyecto, verás que -más bien- separece mucho a una herramienta ORM(Object/Relational Mapper). LINQ to SQL sumi-nistra un modelo de objetos e implementa unnúmero de patrones comunes en su contexto dedatos, tales como la carga diferida, unidades detrabajo, mapas de identidades, bloqueo optimis-ta, etc. y suministra una correspondencia de obje-tos para la persistencia de la información. Real-mente, te da objetos de negocio con datos y com-portamiento. Así pues, puede considerársele unaherramienta ORM con todos los derechos. Así desimple.

Un vistazo a Entity Framework

Dino Esposito

Arquitecto en IDesign,Dino Esposito es una delas autoridades mundia-les reconocidas en tec-nologías Web y arqui-

tectura de software. Suslibros más recientes son"Programming ASP.NET3.5-Core Reference" e"Introducing Microsoft

ASP.NET AJAX" (Micro-soft Press). Es ponente

regular en eventos de laindustria de ámbito

mundial, como Tech-Edo DevConnections, y

europeos, como Dev-Week y Basta.

He comenzado con Entity Framework, con la idea de que tenía que ser muy superior aLINQ to SQL y centrado en el modelado de domain spaces a través de entidades yrelaciones. Sin embargo, me parece muy similar a LINQ to SQL, y muy centrado endatos. ¿En qué es diferente de LINQ to SQL?

todonet@qa

Este mes exploramos algunas características relacionadas con Entity Framework y el desarrollocon la primera versión de una herramienta que tiene todavía mucho que decir y hacer en el futu-ro. Entity Framework se ha lanzado en su versión 1.0 este pasado verano, junto al SP1 de .NETFramework 3.5. Como muchos otros productos de Microsoft en versión 1.0, no es perfecto, y, talcomo se ha visto en el pasado PDC, mejorará de forma muy significativa en su próxima versión.En este artículo responderé a algunas preguntas que surgen frecuentemente tras un primer acer-camiento a Entity Framework.

tod

otN

et.q

a@

dot

netm

ania

.com

Page 55: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Entity Framework no parece real-mente un producto muy distinto desde elpunto de vista de su arquitectura. La simi-litud no es una leyenda urbana, pues huboque escalar bastante alto en las estructu-ras del software de Microsoft para deci-dirla. Podría decirse que ambos son elmismo tipo de producto, aunque conimplementaciones distintas de algunascaracterísticas. Cada producto fue desa-rrollado por equipos independientes, quevivían desconectados del resto del uni-verso. Hoy, el mismo equipo está a car-go de ambos productos, y no les va a resul-tar fácil averiguar cómo diferenciarlos.La solución más probable parece dejarLINQ to SQL tal como está y mejorarsolamente Entity Framework. Sin embar-go, no va a salir nada antes de la próximaactualización significativa de .NET Fra-mework a finales de 2009, si no en 2010.

Después de todo, creo que la dife-rencia más grande entre ambos es elconjunto de bases de datos soportadas.LINQ to SQL se limita a SQL Server,mientras que Entity Framework es inde-pendiente de la base de datos y soportaun modelo abierto y extensible para pro-veedores de bases de datos de terceros(aunque la mayor parte de ellos estátodavía en desarrollo, lo que vinculaEntity Framework casi de forma exclu-siva a la plataforma SQL Server).

La capacidad de relaciones entre enti-dades de LINQ to SQL está limitadaesencialmente a las del tipo 1:1 entre cla-ses y tablas de la base de datos. Además,LINQ to SQL solo soporta una manerade implementar la herencia, conocidacomo Tabla por jerarquía. Este mode-lo usa una única tabla para mantenertodos los tipos de una jerarquía de heren-cia (por ej. ClienteBase, ClienteRegis-trado y ClienteDesconocido), y utiliza una

columna en la base de datos como dis-criminador para distinguirlos. El valor deldiscriminador se usa para especificar dequé tipo de registro se trata. En otras pala-bras, esto quiere decir que se necesitatener una columna ad-hoc si se quierecrear y mantener una jerarquía en elmodelo de objetos.

Entity Framework soporta otros tiposde correspondencias. En particular, el tipoTabla por tipo concreto, que utiliza unatabla separada por cada tipo en la jerar-quía, y el tipo Tabla por subclase, untipo híbrido que usa una tabla comparti-da para la información común acerca deltipo base y tablas separadas para los tiposderivados.

Entity Framework también soportalos tipos complejos, tipos que se anidandentro de otros más grandes y que no hansido pensados para constituir una enti-dad. El ejemplo canónico es el tipo Direc-

ción, que recoge las propiedades Calle,Ciudad, Provincia y País. LINQ to SQLno soporta los tipos complejos, pero hediseñado un sistema alternativo que fun-ciona sin romper el diseñador. Puedes leerel artículo completo en: http://dotnets-lackers.com/articles/csharp/Complex-

Types-in-LINQ-to-SQL-Reloaded.aspx.Curiosamente, aunque Entity Frameworksoporta totalmente los tipos complejos,el diseñador de Visual Studio 2008 no lohace (ver figura 1). Esto significa que esnecesario editar manualmente el códigofuente del modelo de entidades paraintroducir tipos complejos. Sin embargo,si esto se hace, el modelo de datos nopodrá ser vuelto a cargar en el diseñador.Esto se resolverá en la versión 2.0 deEntity Framework. Por último, podemosencontrar otras diferencias en la formaen que ambos soportan la carga diferiday los planes de consulta.

dotN

etM

anía

<<

55

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

dnm.todonet@qa<<

Figura 1: El diseñador de Visual Studio 2008 no soporta tipos complejos en Entity Framework

Respecto a la carga de datos, existen algu-nas diferencias entre LINQ to SQL yEntity Framework. Veamos los detalles.Lo primero, la carga perezosa (lazy loa-

ding) y la carga diferida (deferred loading)son equivalentes y se refieren a la mismafuncionalidad básica: la capacidad de car-gar automáticamente objetos bajo

demanda. La carga perezosa es el nom-bre asignado en los libros de patrones dediseño para denominar una forma decodificar: el código es perezoso en el sen-

¿Cómo puedo especificar un query fetch plan con Entity Framework? ¿Está habilitada por defecto la cargadiferida como en LINQ to SQL?

Page 56: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

Esto es correcto y, nuevamente, es así por diseño. Lasrelaciones son bidireccionales. Lo sorprendente esque se acabe obteniendo una relación bidireccional,dado que las relaciones se crean a partir de restric-

ciones (constraints) de las bases de datos, basándose enlas claves ajenas.

No hay un camino alternativo en esta versión; esalgo que se arreglará en la versión 2.0.

tido de que los objetos solo se cargan en memoria en elmomento en que son requeridos explícitamente. Cargadiferida es el término que utiliza Microsoft en LINQ toSQL para hacer mención a un comportamiento obser-vable: la carga se difiere hasta que los datos resultan abso-lutamente imprescindibles.

En LINQ to SQL, la carga diferida está soportada yhabilitada por defecto, lo que significa que si se hace unaconsulta de un pedido y más tarde se trata de leer la infor-mación del cliente relacionado, se lanza una nueva con-sulta. En las aplicaciones modernas basadas en dominios,la carga perezosa es una característica imperativa. Pre-serva el modelo de objetos de procedimientos prescrip-tivos de carga de datos que de otra forma tendrían queser insertados en cada lugar donde se requiriera el acce-so a datos. Consecuentemente, la lógica de negocio deuna aplicación basada en dominios se "contaminaría" concódigo propio del acceso a datos.

La carga perezosa puede tener ciertos efectos indesea-bles en el código (por ejemplo, demasiadas peticiones a labase de datos) si no se comprende y gestiona adecuada-mente por los desarrolladores. Probablemente por estarazón, Entity Framework no soporta la carga perezosa enabsoluto. Por diseño. La política es que ninguna llamada ala base de datos suceda sin el consentimiento explícito deldesarrollador. Eche un vistazo al siguiente código:

En Entity Framework, para forzar a una entidad rela-cionada a que se cargue en memoria se precisa una lla-mada explícita. En LINQ to SQL también se puede des-habilitar la carga diferida, pero si se hace esto, solo sepodrán recuperar los datos que falten mediante otra lla-mada. No se suministra ninguna otra contrapartida almétodo Load.

El query fetch plan es el mecanismo que se usa paradecidir qué relaciones deben resolverse automáticamente.Aquí tiene un ejemplo del funcionamiento en Entity Fra-mework:

El método Include indica a la entidad que se rellenecon datos provenientes de una relación existente entreentidades. Por otra parte, en LINQ to SQL se utiliza elmétodo LoadWith para especificar qué relaciones debenresolverse. Aquí va un ejemplo:

Como puede verse, aquí se hace evidente otra dife-rencia entre ambos sistemas: en Entity Framework, elfetch plan se especifica a nivel de consulta; en LINQ toSQL, se define a nivel de contexto.

dotN

etM

anía

<<

56

dnm.todonet@qa<<T

odot

Net.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

Traducido al castellano por Marino Posadas

Tengo que crear una relación entre una entidad Cliente y una entidad País. Quiero que la relación sea uni-direccional. En otras palabras, quiero una relación 1:1 del tipo Cliente->País. Parece que no se puede con-seguir esto sin tener igualmente una relación 1:n inversa entre País y Cliente.

var orders = from o in context.Orderswhere o.Status == “Completed”select o;

foreach (Order o in orders){

// A cceso al cliente relacionado if (!o.Customer.IsLoaded){

o.Customer.Load();}// Trabajo con datos del cliente

}

Order order = context.Orders.Include(“OrderDetails”).Include(“Product”).First();

DataLoadOptions options = new DataLoadOptions();options.LoadWith<Customer>(c => c.Order);options.LoadWith<Order>(o => o.OrderDetails);context.LoadOptions = options;

Page 57: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

ADO.NET Entity FrameworkAplicaciones y servicios centrados en datos Unai Zorrilla, Octavio Hernández y Eduardo QuintásEditorial: Krasis PressPáginas: 414Publicado: octubre de 2008ISBN: 978-8493548995Idioma: castellano

Es un placer comentar la última obra de tres colaboradores de dotNetManía sobra-damente conocidos por los lectores. Entity Framework es el nuevo marco para acceso adatos propuesto por Microsoft, disponible desde la aparición del SP1 de Visual Studio2008, y propone un modelo de acceso y manipulación de datos muy novedoso. Por eso,un libro de este tipo era fundamental plantearlo –como así se ha hecho- desde el puntode vista de un desarrollador que conoce los fundamentos de ADO.NET pero no ha mane-jado aún los recursos de LINQ con todas sus variantes.

El libro avanza desde la introducción y los conceptos de modelado que propone elmarco EF hasta la puesta en práctica de soluciones reales mediante esta tecnología, y conesto queremos decir soluciones que están funcionando en empresas españolas en estemomento. Ese es otro de sus valores, aparte del indudable tono didáctico que los tres hansabido imprimir a esta obra. Si la pregunta es ¿pero esto funciona en aplicaciones del díaa día?, la respuesta es que sí, y la forma de aprenderlo…ya saben.

Application Architecture Guide 2.0: Designing Applications on the.NET PlatformJ.D. Meier, Alex Homer, David Hill, Jason Taylor, Prashant Bansode, Lonnie Wall, RobBoucher Jr. y Akshay BogawatEditorial: MicrosoftPáginas: 381Publicado: diciembre de 2008Idioma: inglés

Con prólogos de Soma Somasegar y Scott Guthrie comienza esta obra digital (probable-mente se imprimirá en papel igualmente), gratuita y totalmente recomendable para cualquierdesarrollador o jefe de proyecto que quiera estar al día en la arquitectura de aplicaciones .NETsiguiendo las buenas prácticas aplicadas a todas las fases del ciclo de vida de las aplicaciones.El libro está disponible para descarga en formato PDF desde la dirección de CodePlexhttp://www.codeplex.com/AppArchGuide (y ha tenido 20.000 descargas en una semana).

Además, es una revisión de todos los conceptos nuevos que incorporan las nuevas tec-nologías, como Entity Framework, aplicaciones R.I.A (Silverlight), aplicaciones móviles,OBA, SharePoint LOB, etc. Y no se queda en el mero diseño arquitectónico, sino querecorre casi todo lo que hay que tener en cuenta al planear y construir una aplicación concualquier tecnología .NET hoy en día, con especial énfasis en la construcción de las capaso las recomendaciones de implantación y mantenimiento. Imprescindible.

biblioteca.net

nove

dad

es Professional ADO.NET 3.5 with LINQ and the Entity Framework

Robert Jennings. Editorial: Wrox. Páginas: 672. ISBN: 978-0470182611. Fecha de publica-

ción: febrero de 2009. Idioma: inglés.

Pro SQL Server 2008 Entity FrameworkJim Wightman. Editorial: APress. Páginas: 550. ISBN: 978-1590599907. Fecha de publica-

ción: octubre de 2009. Idioma: inglés.

TEXTO: MARINO POSADAS

Page 58: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro

dotN

etM

anía

<<

58

desván

ASP.NET Patterns every developershould know. Artículo publicado enDeveloper Fusion por el conocidodivulgador de tecnologías de Micro-soft, Alex Homer. El artículo va acompañado de un ejemplo descar-gable muy descriptivo. Accesible en la página: http://www.developer-fusion.com/article/8307/aspnet-patterns-every-developer-should-know.

YouTube API: Try before you buyes un artículo de John Musser publi-cado en ProgrammableWeb sobreuna página expuesta por YouTube conel fin de que los desarrolladores puedan probar la API de desarrollo deYouTube sin necesidad de descargarse el SDK correspondiente. Pue-de verse la explicación y el enlace en: http://blog.programmableweb.com/2008/12/09/youtube-api-try-before-you-buy.

Microsoft Web Platform Installer. Más que interesantepaquete que permitemontar en un equipomediante un procesoúnico todas las herra-mientas gratuitasnecesarias para eldesarrollo Web contecnologías de lacompañía: IIS, VisualWeb Developer 2008Express Edition, SQL Server 2008 Express Editiony .NET Framework 3.5, pudiendo seleccionar lasque se desea si no se necesitan todas. Para informa-ción y descargas: http://www.microsoft.com/web/chan-nel/products/WebPlatformInstaller.aspx.

documentos en la redutilidades del mes

Web 2.0, Web semántica y Web implícita

El notable avance de la participación social enInternet ha desembocado en cotas de comuni-cación y creación de recursos compartidos queexceden las previsiones de los más optimistas.En 2004 nacía un nuevo concepto: la Web 2.0,definida como la tendencia que propicia el usode la red como herramienta de colaboración,creatividad e información compartidas y nuevafuncionalidad remota. No conlleva –en su ini-cio– ninguna nueva especificación técnica, sóloun nuevo uso de la web como herramienta social.Tim Berners-Lee, de hecho, la definía como“una revolución empresarial, basada en el usode Internet como plataforma, que requiere –esosí– comprender las reglas del éxito que esa plata-forma implica”. En realidad, se trata de nuevasformas de usar la Web, en parte propiciadas porlas –para la mayoría, más supuestas que reales–mejoras en las prestaciones de los servicios deconexión de banda ancha.

¿Y dónde quedan las promesas? ¿Para cuán-do un sistema inteligente de búsquedas en la red?Casi nadie va más allá de las 3 primeras páginasde enlaces devueltas por los buscadores, y todavíason muchas las ocasiones en que nos quedamoscon la duda de si lo que estamos buscando exis-te o no. No se trata de estar en la Web, se tratade que te puedan encontrar. Muchos protesta-ban por el “monopolio” de Microsoft, y hanabrazado amorosamente el de Google como unmal necesario. Si no estás en Google, no estás.Ya, ya sé que podemos usar otros: Live Search,Yahoo, etc., y que algunos comenzamos a explo-rar otras posibilidades, pero los usuarios del pri-

mero son legión. Y los motores de búsqueda sebasan en algoritmos que pueden fallar o que noson perfectos.

La solución prometida era es la de la Websemántica. Se basa (disculpe el lector que ya loconozca) en la idea de añadir metadatos semán-ticos a las páginas, de forma que –al igual quehacen las etiquetas XML con sus datos conte-nidos– describan lo que hay allí, su significadoy sus relaciones, y lo hagan de una manera for-mal, de tal suerte que sea posible más tarde pro-cesar esos datos mediante un software y conse-guir que los resultados de una búsqueda tenganese “factor de inteligencia” del que ahora care-cen. El propio Berners-Lee lo intentó desde elprincipio, pero no fue posible, según reconocíaen una charla ante el MIT Technology ReviewEmerging Technologies (ver http://www.digi-taldivide.net/articles/view.php?ArticleID=20). Perose necesitaría que las nuevas páginas creadas(parece muy difícil revisar las existentes) utiliza-ran las tecnologías de descripción de los conte-nidos, como RDF y OWL.

No obstante, se están haciendo esfuerzos enese sentido, pero son más académicos que cor-porativos, y mucho menos, particulares. El equi-

po de Carmen Costilla en la UniversidadPolitécnica de Madrid, o Pablo Castells en laAutónoma, son ejemplos de ello, junto a otrasiniciativas similares en centros de Calaluña, Bale-ares, Andalucía, etc. Y también existen propues-tas interesantes a nivel gubernamental, como laRed Temática de la Web Semántica, promo-cionada por el Ministerio de Educación y Cien-cia (http://www.redwebsemantica.es/SemWeb/sew-View/frames.jsp), pero no es menos cierto que lainmensa mayoría de los desarrolladores no incor-poran estas características en sus trabajos.

Y además, en 2007, apareció un nuevo térmi-no: la Web implícita, vocablo acuñado para desig-nar las Web especializadas en la síntesis de infor-mación personal recopilada de Internet aportan-do una imagen coherente y lo más completa posi-ble del individuo (o grupos de individuos). Hayempresas que ya han hecho de esto su objetivo pri-mario (ver http://www.orch8.net), y pueden encon-trarse explicaciones más detalladas de esta idea enhttp://blog.eturner.net/?p=14, http://blogs.zdnet.com/web2explorer/?p=413 y http://www.avc.com/a_vc/2006/12/2007_the_implic.html. Esta informaciónpuede incluir vínculos visitados con más frecuen-cia, hábitos de navegación, prácticas de búsquedade información o cualquier otro dato generado sinla intervención explícita del usuario, y la informa-ción así obtenida podría utilizarse en muchos con-textos diversos. Sería un complemento a las visio-nes y usos prometidos por las dos anteriores como–quizá– un anticipo de la próxima versión (sí, ya sehabla de la siguiente, la Web 3.0), que tendría comoobjetivo la descentralización del yo. Pero tiempohabrá de volver a este tema…

Marino Posadas

Page 59: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro
Page 60: dotNetManía - sergiogonzalezc.files.wordpress.com · Bienvenido al número 55, de enero de 2009, de dotNetManía. Con el ejemplar que tiene ahora en sus manos, terminamos nuestro