Entrevista a Jim Gray Entrevista a Jim Gray
Transcripción
Entrevista a Jim Gray Entrevista a Jim Gray
nº12 febrero 2005 • 6,00 € (España) Visual Basic.NET • C# • Delphi • ASP.NET • ADO.NET • .NET Framework • Windows Server System dotNetManía www.dotnetmania.com Dedicada a los profesionales de la plataforma .NET Entrevista a Jim Gray Investigador de Microsoft Research y premio A.M. Turing Subclasificación de ventanas Ampliando la capacidad de los controles y ventanas mediante técnicas de subclasificación Creación y utilización de servicios Web desde ASP.NET • Redes de mensajería y .NET (y II) • Sistemas distribuidos en .NET con Remoting (I) • SQL Server Analysis Services. ¡Hola cubo! (III) • Interoperabilidad no administrada y migración (I) • Acceso a datos en Delphi 2005 ToDotNet Q&A ¿Está seguro con ASP.NET? Laboratorio Raptier, rápido por naturaleza opinión Cine y desarrollo de software dnm.editorial dotNetManía Dedicada a los profesionales de la plataforma .NET Vol. II •Número 12 • Febrero 2005 Precio: 6€ (España) dotNetManía CD Vol. 1 Editor Paco Marín ([email protected]) Asesor Técnico/Coordinación Marino Posadas ([email protected]) Redactores Antonio Quirós, Dino Esposito, Guillermo 'guille' Som, Jorge Serrano, José Manuel Alarcón, Luis Miguel Blanco, Manuel Imaz y Pedro Pozo. Colaboradores habituales Ángel Esteban, Braulio Díez, Eladio Rincón, Erich Bühler, Fernando Nogueras, Jorge Crespo Cano, José Miguel Torres, Miguel Egea, Miguel Katrib Mora (Grupo Weboo), Octavio Hernández, Pablo Abbate, Pepe Hevia y Salvador Ramos. Además colabora en este número Rodrigo Corral Edición y Suscripciones .netalia c/ Robledal, 135 28529 Rivas-Vaciamadrid (Madrid) Tf. (34) 91 666 74 77 Fax (34) 91 499 13 64 Publicidad Mediadev Sophie Mancini ([email protected]) Tf. 93 426 22 57 - 670 99 74 64 Fax. 93 423 11 40 Imprime Gráficas Vallehermoso www.graficasvallehermoso.com ISSN 1698-5451 Depósito Legal M-3.075-2004 << dotNetManía ha cumplido un año, un difícil año en el que hemos apostado por contenidos técnicos enfocados claramente a los profesionales o a los estudiosos de la plataforma .NET. Es momento de agradecimientos: a vosotros, los lectores, por estar ahí (fueron muchos los que dijeron que no estaríais); a las personas de Microsoft por facilitarnos continuamente la labor, dejándonos trabajar con independencia en una muestra de respeto a vosotros, los lectores; a los autores, por su impagable esfuerzo y por las muchas horas dedicadas para elaborar contenidos que estuviesen a la altura de nuestros lectores y por dejar que fuésemos nosotros quienes los trasmitiésemos; y por último, a los patrocinadores, pocos pero fieles, quienes han apostado especialmente por vosotros. Todo este esfuerzo se recopila en el primer dotNetManía CD Volumen 1, un CD con los primeros 11 números en formato PDF de alta calidad, organizado por documentos con las revistas completas y también separados por artículos para una mejor localización de la información. Todos los suscriptores tendrán la posibilidad de llevárselo gratuitamente al renovar su suscripción. En cuanto a las noticias de este mes, si hay una que realmente atañe directamente a los desarrolladores de .NET, ésa es el lanzamiento de la campaña de formación y certificación de MCAD de Microsoft, por la cual regalarán una XBox más 2 juegos y una suscripción a dotNetManía por 3 números (si ya está sus- crito, su suscripción se incrementará en 3 números) a todos los que se certifiquen como MCAD entre el 15 de enero y el 30 de abril. Si estaba pensando en certificarse, éste puede ser el momento idóneo. Y en cuanto al contenido de este mes, tenemos una estupenda entrevista con Jim Gray, investigador de Microsoft Research y nada menos que premio A.M. Turing (algo así como el Nobel de Informática). Todo un ilustre que nos recibió con la sencillez propia de los más grandes. En nuestro nombre y en el de nuestros lectores, muchas gracias señor Gray. Y estrenamos una nueva columna, ToDotNet Q&A, que escribirá nada más y nada menos que el gran Dino Esposito, quien recibirá y contestará vuestras dudas sobre la plataforma .NET. Dino es de esas personas que explica de forma sencilla los temas más difíciles, que sabe dar con los problemas clave y con las soluciones más elegantes. Es para nosotros todo un lujo contar con él, por lo que quiero mostrar mi público agradecimiento a Dino por colaborar con nosotros. Quisiera, por último, dar la bienvenida a Rodrigo Corral como colaborador de dotNetManía. Comienza con una serie de 3 artículos bien fundamentados sobre aplicaciones distribuidas con .NET Remoting. Después de esto, lo demás parece poca cosa (no todos los días se entrevista a todo un Premio Turing o se inaugura una columna que dirijirá uno de los mejores comunicadores del mundo), pero hay más, mucho más... <<dotNetManía Administración Pilar Pérez ([email protected]) 3 12 dnm.sumario Cine y desarrollo de software 8-9 Eran los turbios años de la mafia en América. La familia Corleone copaba una buena parte del control sobre determinados negocios. Alguien ofrece a Don Vito Corleone entrar en el mundo de la droga. Pero es un caballero de la mafia, un idealista que aún no quiere bajar a pozos tan profundos. Se niega… y ahí se desencadena la historia. Entrevista a Jim Gray 10-12 Entrevista con Jim Gray, premio A.M. Turing por sus trabajos sobre sistemas de almacenamiento de información. Como suele suceder con los auténticamente grandes, Jim Gray nos recibió de forma sencilla en el pasado Tech-Ed de Ámsterdam. Creación y utilización de servicios Web desde ASP.NET 13-16 En este artículo lo que se pretende es mostrar paso a paso, y de forma práctica, el proceso de creación y utilización de un servicio Web desde una aplicación Web de ASP .NET utilizando para ello el lenguaje Visual Basic .NET y la herramienta de desarrollo Visual Studio .NET. Redes de mensajería y .NET (y II) 18-22 En la primera parte de esta serie, vimos cómo iniciar una sesión con Messenger (autentificándonos con éxito) y chequear nuestra lista de contactos. En esta segunda parte vamos a ver como “chatear” con ellos. dnm.sumario Ampliando la capacidad de los controles y ventanas mediante técnicas de subclasificación 23-28 La subclasificación de ventanas es una técnica específica de la plataforma Windows que permite ampliar las capacidades de la mayoría de los controles y formularios de Windows Forms. Con su uso se consiguen características poco frecuentes pero muy útiles. Veremos en este artículo cómo sacarle partido. Sistemas distribuidos en .NET con Remoting (I) 29-35 En esta serie de tres artículos veremos como .NET Remoting permite desarrollar, desplegar y configurar con facilidad aplicaciones distribuidas sin los quebraderos de cabeza y las limitaciones que presentaban anteriores soluciones. SQL Server Analysis Services. ¡Hola Cubo! (III) 36-39 Con este artículo concluiremos la creación de nuestra primera base de datos multidimensional, en la que tendremos un cubo compuesto por dos medidas y cinco dimensiones, que ya quedará listo para su explotación con las herramientas cliente. Interoperabilidad no administrada y migración (I) 40-45 Esta serie de tres artículos nos ayudará a conocer las ventajas y posibilidades tanto de COM Interop como de la interoperabilidad con código no adminsitrado en general, lo que nos permitirá no sólo extender el alcance de nuestras apliciones sino replantearnos los escenarios de migración. Acceso a datos en Delphi 2005 46-50 Delphi 2005 ofrece la posibilidad de desarrollar para la plataforma .NET utilizando dos vías diferentes para el acceso a datos: a través de los recursos que ofrece la VCL.NET, una librería de compatibilidad desarrollada por Borland; o a través de ADO.NET, la tecnología de acceso a datos “nativa” de la plataforma .NET. dnm.todotnet.qa 52-53 ¿Está seguro con ASP.NET? dnm.laboratorio 54-55 Raptier, rápido por naturaleza dnm.biblioteca.net 57 OOP: Building Reusable Components with Microsoft® Visual Basic® .NET (Ken Spencer, Tom Eberhard, y John Alexander). C# for Java Developers (Allen Jones y Adam Freeman). dnm.desvan 58 dnm.noticias 6 noticias.noticias.noticias.noticias.noticias.noticias << dotNetManía << dnm.noticias Campaña de formación y certificación de MCAD sobre Visual Studio .NET Microsoft Ibérica,conjuntamente con los CPLS (Certified Partner for Learning solutions),lanza esta campaña con el objetivo de animar a los desarrolladores MCAD (Microsoft Certified Application Developer) es la certificación para avalar los conocimientos de los desarrolladores de aplicaciones Windows y aplicaciones Web y servicios de Web en la plataforma .NET. Es también el primer paso para conseguir la certificación MCSD (Microsoft Certified Solution Developer) que es la certificación que además avala sus habilidades como diseñador de software. Todas aquellas personas que consigan la certificación MCAD entre el 15 de enero y el 30 de abril, aparte de poseer una de las certificaciones en desarrollo de aplicaciones más demandadas del mercado, recibirán completamente gratis: • Consola Xbox + 2 juegos1 • Suscripción gratuita por 3 meses a a dotNetManía2 Tan solo existen 3 condiciones para poder beneficiarse de todos estos regalos: IV Jornadas del Programador Madrid, 7, 8 y 9 de febrero Enfocadas a Visual Studio 2005 y SQL Server 2005. Recomendaciones para la escritura de código seguro Implementación de seguridad en las aplicaciones con Microsoft .NET Framework Madrid y Barcelona, 15 de febrero Recomendaciones de seguridad para todas las etapas del desarrollo. MSDN Talleres:WSE 2.0 Madrid, 18 de febrero Introducción a las nuevas especificaciones estándares WS-* recogidas en Microsoft WSE 2.0. ASP.NET 2.0 Tour Madrid, 21 de febrero Para los desarrolladores profesionales de ASP.NET. Este even- • Obtener la certificación MCAD completa antes del 30 de abril de 2005, es decir, tener superados los 3 exámenes de certificación requeridos (70-305, 70-306 y 70-310). • Asistir al menos a 1 curso presencial MOC en cualquiera de los centros que están adheridos a la campaña. • Registrarse en la página web que se indica para poder hacer el envío de los regalos. Para más información: www.microsoft.com/spain/ formacion/oferta/formacion.mspx o en www.alhambraeidos.com ([email protected]) Además, las 15 primeras personas que se certifiquen, recibirán la Xbox junto con 2 meses gratis de conexión a Xbox live 2 Si ya es suscriptor a esta revista,su suscripción se incrementará en 3 ejemplares más. 1 to es parte de un tour europeo de Microsoft que contará con ponentes de primer nivel. Puede ver más información en http://www.microsoft.com/emea/ms dn/aspontour para el tour europeo o en http://www.microsoft.com /spanish/msdn/Spain/eventos/talleres/asptour_2005.asp para el evento español. ¡Recomendable! TechNet Security Day Cómo tener más segura la información de sus servidores Barcelona, 17 de febrero Madrid, 21 de febrero Se tratarán los temas más pedidos por los usuarios: Fortificación de servidores, gestion de políticas de seguridad y seguridad wireless. Una pena que en Madrid coincida con el ASP.NET 2.0 Tour. Más información en www.microsoft.com/spain/tec hnet/SecurityDay. Gira TechNet de Seguridad Protección contra Hackers. Seguridad en VPNs. Gira por once ciudades españolas que comienza el 25 de enero. Más información en http://www.microsoft.com/spain/technet/jornadas/gira. SQL Server Reporting Services Madrid, 1 de febrero Barcelona, 3 de febrero Webcast, 16 de febrero Parte de una serie de jornadas tecnológícas genéricamente llamadas “Potencia tu SQL”, en la que se están estudiando diferentes escenarios técnicos de uso de SQL Server 2000 y algunas de las nuevas características de SQL Server 2005. Más información en: http://www.microsoft.com/spain/technet/potenciatusql/sql_200502.mspx. eventos.microsoft www.microsoft.com/spain/eventos << dnm.noticias Compuware lanza nuevos productos DevPartner Noticias breves DevPartner Fault Simulator y DevPartner SecurityChecker analizan y asesoran en las emergentes áreas de la calidad del software Altova DiffDog™ 2005 es una herramienta de sincronización que facilita la comparación y fusión de ficheros, carpetas y directorios para desarrolladores de aplicaciones y usuarios avanzados. DiffDog™ 2005 simplifica los procesos de reconcilicación a través de su sencillo entorno visual, de modo que incrementa la productividad y maximiza los resultados. Permite a los usuarios comparar rápidamente ficheros de código fuente, ficheros HTM L y es capaz de fusionar los cambios de cualquier fichero de texto con un solo clic. Más información en: www.altova.com. Compuware DevPartner Fault Simulator 1.0 DevPartner Fault Simulator chequea y depura el código de gestión de errores en código administrado .NET y en código nativo, sin desestabilizar el entorno de operación o depuración de la aplicación, a través de la inyección segura de fallos simulados dentro del código de la aplicación. El simulador “engaña” a la aplicación destinataria en la creencia de que un fallo ha ocurrido de modo que la reacción puede ser monitorizada sin afectar a otras aplicaciones que se estén ejecutando o a un proceso del sistema operativo. Compuware DevPartner SecurityChecker 1.0 DevPartner SecurityChecker es una potente herramienta de análisis que permite a los desarrolladores localizar y reparar rápidamente vulnerabilidades de seguridad en aplicaciones ASP.NET. DevPartner SecurityChecker usa tres modelos distintos para proveer al desarrollador con un análisis profundo sin par en la industria actualmente: • Análisis en tiempo de compilación. DevPartner SecurityChecker inspecciona los ensamblados de .NET y determina si existen asuntos de seguridad a través del examen de los metadatos, código IL, archivos ASPX y el WEB.CONFIG. Ejemplos de vulnerabilidades detectables a través del análisis en tiempo de compilación incluyen amenazas heredadas, depuración activada, seguridad débil en las passwords y constructores estáticos desprotegidos. • Análisis en tiempo de ejecución. Gracias a la capacidad para mirar dentro de la aplicación mientra se ejecuta, DevPartner SecurityChecker puede detectar errores de seguridad tal como ocurren. Ejemplos de vulnerabilidades detectables a través del análisis en tiempo de ejecución incluyen el uso del API con privilegios, uso de cuentas con privilegios, excesivos accesos a ficheros y al registro, excepciones no manejadas y fallos de suplantación. • Análisis de integridad. DevPartner SecurityChecker puede simular un ataque externo a través de la ejecución de una sesión basada en HTTP y modificar algunas de las entradas para chequear vulnerabilidades. Los análisis de integridad chequean vulnerabilidades a ataques de scripting, ataques de injección de código SQL, buffer overflows, inyección de comandos y falsificación de parámetros. DevPartner SecurityChecker es el único producto del mercado que llama a cada uno de estos tipos de análisis para encontrar vulnerabilidades de seguridad, dando como resultado aplicaciones más seguras que pueden ser creadas a través de la integridad de análisis aislados. Puede encontrar más información sobre seguridad en ASP.NET en la sección ToDotNet Q&A de este mes. Más información sobre estos productos en: www.compuware.com/products/devpartner/default.htm ComponentOne® lanza Studio EnterpriseTM 2005 v1 ComponentOne, uno de los más importantes fabricantes de herramientas de terceros, ha anunciado Studio Enterprise 2005 v1. La nueva versión añade alrededor de 45 actualizaciones de las herramientas de .NET y ASP.NET. Si es usted suscriptor a las actualizaciones de Studio Enterprise con esta entrega obtendrá ya acceso a componentes para las versiones Alpha y Beta de Visual Studio 2005. Más información en: www.componentone.com. Nuevas versiones CTP de Visual Studio 2005 e Indigo para febrero Según Ford McKinstry (Indigo Program Manager), Microsoft lanzará una versión CTP de Indigo después del VSLive de San Francisco, no en el 8 de febrero, en el Indigo Day como se preveía. Igualmente en febrero se presentará la última versión CTP de Visual Studio 2005, según él mismo comentaba (microsoft.public.windows.developer.winfx.indigo) antes de la aparición de la Beta 2, que según indicaba Somasegar, vicepresidente de Microsoft Corp. de Developer Division en su weblog estará a finales del primer cuarto de este año (weblogs.asp.net/somasegar/archive/2004/12/22/ 329673.aspx#343547). MVP Global Summit El evento anual más importante para MVPs ya tiene fecha. Tendrá lugar entre el 28 de septiembre y el 1 de octubre en Redmond. Contará con ponentes de la talla de Steve Ballmer, Jim Allchin y Kevin Johnson. dnm.noticias << dotNetManía Compuware ha anunciado –antes de o esperado– la disponibilidad de dos nuevos productos DevPartner: Compuware Fault Simulator y Compuware DePartner SecurityChecker. Compuware comunicó en noviembre del año pasado su estrategia para el entorno de desarrollo de Microsoft (ver número 9). Dentro de dicha estrategia estaba la aparición de estos dos productos, si bien las informaciones eran que aparecerían inmediatamente después de que Visual Studio 2005 estuviese disponible. Estos nuevos productos extienden significativamente la capacidad de asesorameinto de los productos de DevPartner, para dar una amplia y profunda visión en materia de calidad de las aplicaciones, permitiendo a los equipos de proyectos establecer las mejores prácticas para construir software de calidad a lo largo de todo el ciclo de vida del desarrollo de aplicaciones. Nuevo Altova DiffDog 2005 7 dnm.opinion Antonio Quirós Cine y desarrollo de software Eran los turbios años de la mafia en América. La familia Corleone copaba una buena parte del control sobre determinados negocios.Alguien ofrece a Don Vito Corleone entrar en el mundo de la droga. Pero es un caballero de la mafia, un idealista que aún no quiere bajar a pozos tan profundos. Se niega… y ahí se desencadena la historia. << Entonces el Don sufre un atentado que casi le hace per- <<dotNetManía Antonio Quirós es redactor de dotNetManía. Co-fundador de las revistas clippeRManía, FOXManía y Algoritmo.Actualmente es General Area Manager en Alhambra-Eidos 8 der la vida. Su hijo mayor, Santino Corleone, deseaba derramar un mar de sangre con las familias enemigas que habían intentado matar a su padre. Sin embargo, es Michele, el hijo pequeño, mucho más frío y, en principio, menos aficionado a las cosas de la mafia, quien termina vengando el intento de matar a su padre. Para ocultarse y evitar la vendetta opuesta marcha a la vieja, soleada y romántica Sicilia. Es entonces cuando la mano maestra de Ford Coppola comienza a mostrarnos las bucólicas escenas del campo siciliano mientras la magistral música de Nino Rotta pone en nuestros oídos esa fantástica melodía que todos conocemos. Michele se enamora de la joven Appolonia que muere en un nuevo atentado y marca ya el futuro del gángster, que pasa de ser el joven vástago, alejado del asunto mafioso, a convertirse en el frío criminal que conducirá a la familia Corleone tras la muerte del viejo Vito. La suerte está echada y la tragedia va labrando el destino de sus personajes. Es el cine, el fantástico cine, que es capaz de presentarnos la épica de algo tan deleznable como la mafia; que saca poesía hasta de lo más turbiamente humano. Pero ¿y qué hay de los desarrolladores de software? Hay que tener en cuenta que, en nuestro mundo, el cine contribuye de un modo insólito a fijar la imagen que la sociedad tiene de los distintos colectivos que la componen. Tenemos excelentes películas sobre médicos, policías, mafiosos, soldados, políticos, revolucionarios, etc. Pero ¿qué tenemos sobre desarrolladores de software? El resumen no es demasiado bueno y, por tanto, la imagen que la sociedad tiene de los desarrolladores tampoco lo es. Veamos algunos ejemplos. ¿Quién no recuerda, por ejemplo, al gordinflón desarrollador del sistema informático que controlaba el parque en “Parque Jurásico” de Steven Spielberg?. El típico zampabollos aprovechado y sin escrúpulos que no dudaba en cargarse todo el sistema con tal de ganar unos cuantos duros. Qué decir de la alucinada Angela Bennet - Sandra Bullock en “La Red” de Irwin Winkler, sin amigos, sólo relacionándose a través de Internet y con habilidades supremas a la hora de descerrajar sistemas informáticos. La perspectiva de negocio podemos obtenerla, por ejemplo, en “Acoso” de Barry Levinson, donde una ejecutiva come hombres (Demi Moore) le siega la hierba bajo los pies a un Michael Douglas, experto en software, pero que no transmite más que la típica imagen del triunfador americano medio que se sobrepone a la adversidad y triunfa en ese mundo idílico donde los buenos (rubios, coloradotes y sanos) siempre vencen a los malos (morenos, pálidos y delgaduchos). Y vayamos a lo hispano. No quiero ya recordar cuando en “Laberinto de Pasiones” de Almodóvar, una de las protagonistas le dice a su novio Usebio (Eusebio pronunciado a la manchega) que lo que tiene que hacer es dejar la música para estudiar informática que es lo que tiene futuro realmente. Esto, por supuesto, salvando las distancias de nuestro estupendo Almodóvar con los directores mencionados en el párrafo que no sirven ni para atarle los zapatos a nuestro manchego universal. Mención aparte merece la trilogía “Matrix” de los hermanos Wachowski que, aunque no tienen desarrolladores de software en su entramado narrativo, nos presenta un mundo creado y mantenido por un sistema de software y por un gran arquitecto que no deja de representar al dios-creador-desarrollador del mundo. Al fin y al cabo ¿quién es dios sino el desarrollador que liberó la versión del mundo que hoy conocemos?. Por cierto que este dios es casi tan malo como la mayoría de nosotros, ya que dejó un sistema lleno de agujeros de seguridad << dnm.opinion que la toque otra vez, sino que revise el programa de seguridad de la puerta que la ha dejado pasar? Tenemos excelentes películas sobre médicos, policías, mafiosos, soldados, políticos, revolucionarios, etc. Pero ¿qué tenemos sobre desarrolladores de software? Marginados sociales con carencias hasta en el don de la palabra, piratas, ejecutivos arribistas, etc. Estos son los caracteres principales que el cine ha tratado hasta ahora de los desarrolladores de software y, sin embargo, no somos así. Entre nosotros hay grandezas y miserias al igual que entre cualquier otra profesión las hay. Habrá que esperar esa novela, esa genial obra cinematográfica que eleve al rango del arte la figura de algún protagonista, de profesión desarrollador, que sin acartonamientos ni falsos clichés busque la identificación del lector o del espectador. Cuando eso suceda, nuestra autoimagen y aquella que los demás tienen de nosotros habrá Nuestra imagen sólo ha sido tratada en el cine actual a la moda americana, carente de poesía, de compromiso que no busca identificarse con el espectador sino alienarlo un poco más de lo que ya está. de lo que ya está. La diferencia entre “El padrino” y “La red”, por ejemplo, es obvia. ¿Busca el Padrino fijar roles sociales que puedan ser seguidos por la juventud? ¡No, claro que no! ¡Quien va a querer ser como Michele Corleone, frío asesino inmisericorde! No, claro que no, el buen cine busca el arte, la transmisión de sensaciones y sentimientos. En “La red”, como prototipo de película donde aparecen desarrolladores de software, como mucho hay adocenamiento intelectual. Todo el arte de dicha película se centra en la belleza y simpatía de Sandra Bullock que esa sí que no es de menospreciar ni mucho menos Esperaremos, pues, esperanzados. Esperaremos a nuestro Scorsese, a nuestro Coppola, a nuestro Amenábar para que vengan a sacarnos del fango en que nos hallamos, para que escriban y/o dirijan esa obra magistral que nos muestre tal como somos; con eso será suficiente para que podamos ingresar en el universo del cine que hasta ahora sólo nos ha maltratado. Michele Corleone y Yehuda Ben Hur nos esperan en su universo intemporal y proteico, no debemos tardar en llegar a la cita. <<dotNetManía por los que se cuelan tsunamis, guerras, odio, destrucción y una buena colección de bugs adicionales. Que me perdonen los creyentes, no tengo ni la más mínima animadversión hacia ellos, pero hay que reconocer que a dios le falló el control de calidad en la versión del universo donde nos ha tocado movernos. Quizá en otras dimensiones, en otras eras, con otro despliegue diferente de nuestros sistemas, la cosa esté yendo un poco mejor. En fin, fantasías aparte, lo que podemos concluir es que apenas si hay ni épica ni lírica alrededor de nuestra profesión. Esto hace que al mundo en general le caiga mejor que nosotros un taxista, el dependiente de un Seven Eleven o un sexador de pollos. Falta la obra que enfatice las virtudes del creador de sistemas informáticos, que escarbe en la poesía de las noches sin sueño buscando la solución a una rutina inacabada, que muestre el placer de sentirse autor de complicadas soluciones que facilitan la vida a millones de ciudadanos en nuestro sofisticado mundo actual. ¿Dónde está nuestro Michele Corleone? ¿Vivirá ya en la cabeza de algún guionista ese Rick, sorprendido por la visita de Ingrid Bergman en su café del norte de África, mientras le dice a Sam, no cambiado notoriamente y ello contribuirá a mejorar tanto nuestra autosatisfacción, como la consideración social que sobre nosotros tenga la media de los mortales. En definitiva, nosotros nos sentiremos mejor, trabajaremos más cómodos y, por tanto, nuestros sistemas serán mucho más eficaces. Y es que quizá aún no se ha realizado esa obra genial que tiene entre sus protagonistas a un desarrollador de software. Casi todas las mencionadas son mediocres, vulgares. Nuestra imagen sólo ha sido tratada en el cine actual a la moda americana, carente de poesía, de compromiso, que no busca identificarse con el espectador sino alienarlo un poco más 9 dnm.directo.entrevistas Marino Posadas Entrevista a Jim Gray Como suele suceder con los auténticamente grandes, Jim Gray nos recibió de forma sencilla en el pasado Tech-Ed 2004 en Ámsterdam, en esta entrevista que contó también con la presencia de Iván González, de la Universidade de A Coruña. << La Informática es, <<dotNetManía Marino Posadas es asesor técnico y redactor de dotNetManía, MVP de C# y formador de Alhambra-Eidos 10 junto a las Matemáticas, una de las disciplinas científicas en las que los méritos de sus practicantes nunca podrán recompensarse con un Premio Nobel. Afortunadamente, y para paliar esta situación, algunas instituciones crearon sus equivalentes, tanto en lo económico como en lo prestigioso. En el primer caso, la Medalla Fields, establecida por John Charles Fields en 1932 (curiosamente, para matemáticos menores de 40 años) y de la que han sido receptores hombres de la talla de René Thom, Michael Francis Atiyah, o Edward Witten. En el segundo, el Premio A.M. Turing, en honor a al padre de la informática, Alan Mathison Turing, de la que han sido perceptores figuras de la talla de Marvin Minsky (el padre de la Robótica actual) Herbert Simon (también Premio Nobel de Economía), Ken Thompson y Dennis M. Ritchie (creadores del S.O. Unix), y nuestro entrevistado de hoy, James Gray, por sus trabajos sobre sistemas de almacenamiento de información. En la actualidad trabaja sobre grandes sistemas de almacenamiento y transferencia de información en Microsoft Research. Gracias por recibirnos, ante todo. A lo largo de este año Microsoft ha estado implicado en una serie de actividades de divulgación académica por todas las universidades españolas. ¿Crees que es una de las mejores formas de popularizar lo que se hace en los distintos departamentos de investigación en Microsoft? Sí. Nosotros normalmente presentamos los resultados de nuestras investigaciones en conferencias internacionales. Y en realidad, no sólo nosotros sino otras compañías como Oracle o IBM hacen lo mismo. Hay otra forma de divulgación, por ejemplo, yendo a España dentro del entorno de las grandes corporaciones a participar en eventos como el que hace dos años tuvo lugar en Barcelona. Precisamente en el ambiente universitario, a priori hostil a Microsoft, he podido comprobar que –una vez que se conoce la tecnología y sus valores– lo de menos es su procedencia. ¿Tienes tú la misma sensación? Absolutamente. Eso sucede también en EE.UU, tanto en las grandes corporaciones como en las universidades. Pero la tecnología triunfa finalmente, a pesar de todo. Y cuando nos conocen, esa hostilidad se convierte en interés por lo que estás presentando. Tú perteneces al Scaleable Servers Research Group. ¿Puedes explicarnos algo más acerca de tu << dnm.directo.entrevistas mente almacenamos tantas cosas que no recordamos siquiera que están en nuestro equipo. Así que –en este sentido– esas innovaciones son beneficiosas para todo el mundo. Tenemos, sin embargo otras líneas de trabajo que van más encaminadas a lo que genéricamente llamamos “Sociedad Digital”. Aquí la labor de los servicios Web será más y más crítica, permitiendo producir y compartir información con los demás. Hasta ahora transferimos sin mucho conocimiento previo, ni seguridad de la información. Pero, en el futuro, la gente va a querer que el almacenamiento y la transferencia de información conlleven un significado asociado con ellos, unos metadatos, en suma ¿Y qué sucede con la transferencia misma de la información y su recuperación, en términos de rendimiento? ¿Piensas que el futuro será algo similar a Internet-2? No creo que el futuro se quede –sólo– en la mejora de la velocidad. Hasta ahora transferimos sin mucho conocimiento previo, ni seguridad de la información. Pero, en el futuro, la gente va a querer que el almacenamiento y la transferencia de información conlleven un significado asociado con ellos, unos metadatos, en suma. Metadatos que incluirán firmas digitales que garanticen la identidad, y cosas más básicas, en realidad, las que buscamos para ese estándar: por ejemplo, cada mensaje debería contener una cabecera y un cuerpo. Y una vez que esto se establezca o incluso hasta que eso ocurra, ¿cuál es el principal problema de esta arquitectura: almacenamiento, transmisión o acceso a la información? Acceso a la información. Porque el acceso es el beneficio que obtenemos de la información almacenada. La transmisión no es un problema en absoluto, la tecnología está ya ahí. Y el almacenamiento, no es un proble- <<dotNetManía trabajo y líneas de investigación actual que estás siguiendo? Nuestro interés principal son las aplicaciones a gran escala. Aplicaciones como TerraServer o SkyServer. Los proyectos han seguido evolucionando de formas a veces inesperadas. Por ejemplo, TerraServer ha reducido su tamaño a unos pocos Terabytes (sic), gracias a los adelantos en sistemas de almacenamiento. En el otro grupo, en el que trabajo en la actualidad, el Media Presence Group, intentamos facilitar el almacenaje y la operatividad con la cada vez mayor cantidad de información que almacenamos en nuestros ordenadores personales, para que pueda ser organizada de forma que sea fácil su acceso y su búsqueda, aportando la mayor utilidad posible a la propia información. De tal forma que el software hace el seguimiento de las llamadas que has realizado o recibido, de tus correos, de las películas que has visto, de los documentos que has leído, de modo que, la próxima vez que quieras buscar algo, la aplicación –de forma preactiva– pueda ser capaz de anticiparse de alguna forma a tus deseos minimizando las necesidades de búsqueda, por ejemplo. ¿Piensas, por tanto, que esa labor de investigación que realizáis tiene consecuencias inmediatas para el común de los usuarios? Por supuesto, especialmente, el proyecto llamado MyLifeBits (ver www.research.microsoft.com/barc/Media Presence/MyLifeBits.aspx) , que he comentado anteriormente. Todo el mundo se beneficia de estas innovaciones, en especial las personas con problemas de memoria o que simple- estoy hablando de la vida cotidiana, desde una comunicación de un padre al profesor de su hijo, hasta una transferencia bancaria. Eso significa que das una gran importancia a los estándares, y en especial a los estándares desarrollados en torno a los servicios Web… Por supuesto, a todos ellos. En la actualidad estamos también trabajando en lo que sería una definición estándar de lo que un documento debería de contener. Es sorprendente que, a pesar de todos los documentos que circulan y se manejan digitalmente, los intentos de estandarizar, como PDF, RTF y otros no han conseguido aún el consenso universal que buscamos. Lo mismo sucede con las otras gramáticas universalmente aceptadas en el mundo de los servicios Web, que siguen evolucionando en busca de la especificación final (nunca definitiva, pero sí aceptada por la inmensa mayoría). Son 11 << dnm.directo.entrevistas ma en términos de bytes, pero si pensamos en términos de organización de la información, de la comprensión de lo que la información es (desde el punto de vista de sus esquemas) entonces es un gran problema. Al objeto de suministrar un buen acceso, tienes que haber organizado previamente la información. En el futuro la mayor parte de la información no será vista por seres humanos, sino por ordenadores. Eso sucede ya en muchos ámbitos. La gente sólo quiere la información que le interesa, y no toda. El reto, en el futuro, es la capacidad de resumir la información mostrando sólo la que es interesante, y en el nivel de detalle que se necesite. Lo que probablemente necesitará el usuario es poder preguntar cosas inteligentes, y obtener respuestas inteligentes. Eso no sucede en la actualidad con lenguajes como SQL. No hay resumen, no hay más que lo que se le pide exactamente. ve el papel. Siempre obtienen la información de Internet, porque la obtienen antes y les permite comunicarse. Por supuesto en el caso de las tesis, hace falta ese trozo de papel, para firmarlo, y pasarlo al tribunal, pero probablemente, ese tribunal ya ha leído la tesis en formato digital. Lo único que resulta crítico, es la calidad de la fuente de información. Y esto nos lleva de nuevo al tema del almacenamiento a gran escala. Hace 3 años leí unos trabajos de Bruster Khale, un informático millonario (creador de Alexa) que está haciendo literalmente copias de seguridad de Internet. ¿Es ése el nuevo almacén de la historia? ¿Podemos considerar esas copias como improntas de cómo era la humanidad en un instante dado? Conozco su trabajo. En la actualidad, está llevando copias de Internet a muy distintos países (acaba de depositar copias en Egipto y aquí en Áms- <<dotNetManía En esencia, se pretende incluir inteligencia en cualquier dispositivo, desde los teclados o los ratones hasta las pantallas, o los dispositivos de red 12 ¿Eso quiere decir que la red va a albergar más y más información y de mayor calidad cada vez, y que por lo tanto, sería de esperar que, utilizando los filtros adecuados, por poner un ejemplo- una universidad pudiese aceptar una tesis doctoral cuya única fuente de información fuese la red? Veamos. Pensemos en la investigación en el campo de la Astronomía. Los astrónomos obtienen toda la información de Internet. Muchos de los que están haciendo investigaciones, jamás ven el telescopio. Su entrada de datos es Internet. Mucha de la información que manejan viene de astro-ph que es un sitio Web. Nadie va ya a las librerías, ni terdam). Porque la historia y las librerías pueden ser destruidas por los gobiernos. De esa forma garantiza que existan copias en países con sistemas políticos totalmente distintos, y siempre podamos estar seguros de que hay copias sin manipular. De forma que el nuevo paradigma pasa por la información selectiva y la manera que podemos acceder y filtrar esa información… Hasta tal punto que, por ejemplo, en EE.UU. tenemos un sistema llamado TiVo , que consiste en un montón de ordenadores que se dedican a ver televisión. El servicio permite que los usuarios seleccionen previamente o a posteriori cualquier cosa que se haya emitido en las últimas 3 semanas o vaya a emitirse, y solicite su grabación para una visión posterior, pudiendo almacenarlo en disco o DVD directamente. Estamos ante una avalancha de información, y necesitamos algo que filtre y condense esa información, y la presente a nuestra conveniencia. ¿Tiene esto que ver con algo que he leído acerca de los dispositivos inteligentes de almacenamiento? ¿Cómo serían esos dispositivos? Si te fijas en el interior de uno de los discos duros actuales, verás que disponen de circuitos integrados y puertos de comunicación. Y llevan un procesador y su propia memoria y una interfaz con el exterior. Pero algún día, ese procesador será un superordenador. De hecho, ahora mismo tienen más potencia que los “mainframes” de 1960. Y en unos pocos años, tendrá más potencia que la máquina más potente que podemos tener hoy. Los modelos de hoy ya disponen de 8/16 Mb de memoria y procesadores de 100/200 Mhz. Esas características superan con creces lo que teníamos hace 10 años, y son parte de un simple disco duro. En 10 años serán capaces que ejecutar lo que un ordenador actual: una base de datos o un servidor Web. Y el propio disco tendrá una imponente capacidad de almacenamiento, probablemente, entre 2 y 10 Terabytes. Por tanto, optimización de acceso e inclusión de inteligencia en el dispositivo, serán dos factores clave para suministrar esto que estamos hablando: acceso inteligente a la información, y capacidad de síntesis de esa información. En esencia, se pretende incluir inteligencia en cualquier dispositivo, desde los teclados o los ratones hasta las pantallas, o los dispositivos de red. Eso minimizará los problemas de instalación gracias a la propia comunicación entre dispositivos. Pues esto es todo lo que nos deja el tiempo disponible. Muchas gracias por tus comentarios. Gracias a vosotros y espero un ejemplar de la revista en cuanto esté publicada. dnm.asp.net Ángel Esteban Creación y utilización de servicios Web desde ASP.NET En este artículo lo que se pretende es mostrar paso a paso, y de forma práctica, el proceso de creación y utilización de un servicio Web desde una aplicación Web de ASP .NET utilizando para ello el lenguaje Visual Basic .NET y la herramienta de desarrollo Visual Studio .NET. Ángel Esteban Colaboradora habitualmente con dotNetManía. Ingeniero Técnico Informácito, MCSD, MCAD y MCT. Es Software Architect en Alhambra-Eidos un servicio Web, sino que se va a explicar cómo se crea uno desde un proyecto Web de ASP.NET dentro de Visual Studio .NET, y cómo se va a utilizar desde una página ASP.NET. Aún así vamos a realizar una breve introducción y definición de lo que se entiende por servicio Web. La plataforma .NET posibilita la extensión del concepto de aplicaciones distribuidas mediante la construcción de servicios Web, que básicamente van a ser funciones albergadas en un sitio Web a las que se puede llamar desde otra página remota (u otro tipo de cliente). Además el .NET Framework posibilita su fácil programación y manejo tal como veremos en este artículo. Al fin y al cabo un servicio Web va a ser un tipo de software publicado en un servidor y que va a ser distribuido como un servicio. Desde un punto de vista lógico, podemos pensar en un servicio Web como en un componente, o caja negra, que suministra algún servicio útil a los clientes, o consumidores. A diferencia de DCOM, RMI, IIOP, o cualquier otro modelo de objetos común de uso específico, un consumidor accede a un servicio Web usando un protocolo estándar, aceptado, y bien conocido, como es HTTP, y un formato de datos basado en XML. El punto de vista del consumidor del servicio Web es el de una interfaz que expone un número de métodos bien definidos. Todo lo que necesita el consumidor es llamar a esos métodos usando los protocolos estándares de Internet, pasando parámetros en formato XML y recibiendo respuestas también en formato XML. Ya no vamos a entrar en más detalles en cuanto a funcionamiento interno de los servicios Web, sino que vamos a pasar a crear nuestro servicio Web desde Visual Studio .NET. Creación de servicios Web. Servicio Web:“Hola Mundo” Partimos del supuesto de que ya hemos creado una aplicación ASP.NET desde el explorador de soluciones de Visual Studio .NET pulsamos con el botón derecho del ratón sobre el proyecto y seleccionamos del menú la opción “Agregar/Agregar servicio Web”. Con esto agregaremos a nuestro proyecto un fichero especial que tiene la extensión ASMX. Este fichero es el que va a contener la definición de nuestro servicio Web. En el fuente 1 se aprecia el contenido que tiene la clase asociada a este fichero nada más ser creado por Visual Studio .NET. Desde Visual Studio .NET ni siquiera tenemos la posibilidad de ver el contenido del fichero ASMX que se corresponde con el servicio Web que acaba- [ ] Podemos decir que los servicios Web son la extensión natural del concepto de componente que nos ofrece la plataforma .NET. Después veremos que ASP .NET ofrece soporte para construir servicios Web a través de ficheros con la extensión .ASMX. Los servicios Web se pueden considerar como el sistema de publicación de componentes del .NET Framework. << dotNetManía << No se persigue realizar una definición exhaustiva de lo que es 13 << dnm.asp.net Imports System.Web.Services <System.Web.Services.WebService(Namespace:=”http://tempuri.org/Art/Service1”)> _ Public Class Service1 Inherits System.Web.Services.WebService #Region “ Código generado por el Diseñador de servicios Web “ Public Sub New() MyBase.New() ‘El Diseñador de servicios Web requiere esta llamada. InitializeComponent() ‘Agregar su propio código de inicialización después de ‘llamar a InitializeComponent() End Sub ‘Requerido por el Diseñador de servicios Web Private components As System.ComponentModel.IContainer ‘NOTE: el Diseñador de servicios Web requiere el siguiente procedimiento ‘Puede modificarse utilizando el Diseñador de servicios Web. ‘No lo modifique con el editor de código. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub servicio Web o bien de forma separada dentro de un assembly. • Language : Este otro atributo es opcional y nos permite indicar el lenguaje que se va a utilizar para compilar el servicio Web. Su valor por defecto es VB, es decir, se utiliza el lenguaje Visual Basic .NET. Para empezar vamos a crear un sencillo método; realizaremos para nuestro primer contacto con los servicios Web el famoso ejemplo “Hola Mundo”. Para ello debemos utilizar el atributo WebMethod. El código fuente resultante sería así de sencillo (fuente 3): <WebMethod(Description:=_ "el clásico Hola Mundo")> _ Public Function HolaMundo() As String HolaMundo = "Hola Mundo" End Function Fuente 3 Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) ‘CODEGEN: el Diseñador de servicios Web requiere este procedimiento ‘No lo modifique con el editor de código. If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub Utilización de los servicios Web #End Region ‘EJEMPLO DE SERVICIO WEB ‘El servicio de ejemplo HelloWorld() devuelve la cadena Hello World. ‘Para generar, quite los comentarios de las siguientes líneas y, a continuación, ‘guarde y genere el proyecto. ‘Para probar este servicio Web, compruebe que la página de inicio es el archivo .asmx ‘ y presione F5. ‘ ‘<WebMethod()> Public Function HelloWorld() As String ‘ HelloWorld = “Hello World” ‘ End Function End Class Ahora añadimos a nuestro proyecto un formulario Web, es decir, la página ASP .NET desde la que se hará uso del servicio Web. Si fuera necesario agregar una referencia Web a nuestro proyecto debemos pulsar con el botón derecho del ratón sobre la carpeta References dentro del explorador de soluciones de Visual Studio .NET y seleccionar la opción de menú “Agregar referencia Web”; en este punto aparece una pantalla como la de la figura 1 en la que debemos indicar la URL del servicio Web que vamos a utilizar. Fuente 1 <%@ WebService Language="vb" Codebehind="ServicioWeb.asmx.vb" Class="Art.ServicioWeb" %> Fuente 2 mos de crear, pero si lo visualizamos con otro editor de texto veremos un código similar al que se muestra en el fuente 2. <<dotNetManía La directiva @WebService 14 La directiva @WebService únicamente se puede utilizar en ficheros .ASMX, ya se va a utilizar para indicar la clase en la que se encuentra la implementación del servicio Web. Esta directiva posee dos atributos: • Class: Este atributo es obligatorio y vamos a utilizarlo para indicar el nombre del la clase que implementa el servicio Web. La clase del servicio Web se puede encontrar definida en el propio fichero ASMX del Figura 1 Una vez indicada la URL del servicio Web pulsamos el botón “Ir” y ya está << dnm.asp.net localizado el servicio Web; ahora ya sólo nos queda pulsar el botón etiquetado como “Agregar referencia”. De esta forma la referencia Web estará añadida a nuestro proyecto y podremos utilizar sin problemas el servicio Web. Realizado este paréntesis volvemos a nuestro ejemplo de formulario Web que va a hacer uso del servicio Web recién creado. Nuestra página ASP.NET va a ser muy sencilla, va a contener un botón que al ser pulsado va a realizar una llamada a nuestro servicio Web para que muestra el mensaje de “Hola Mundo” dentro de una etiqueta. En el fuente 4 se puede observar el código fuente de esta sencilla página ASP.NET y su clase asociada (fuente 5) y una figura con el resultado de su ejecución (figura 2). <WebMethod(Description:="devuelve el nombre de la máquina del servidor")> _ Public Function NombreServidor() As String Return Server.MachineName End Function <WebMethod(Description:="devuelve la hora del servidor")> _ Public Function HoraServidor() As String Return Context.Timestamp.TimeOfDay.ToString() End Function Fuente 6 Ahora vamos a añadir un par de métodos más a nuestro servicio Web (fuente 6); uno de ellos nos va a devolver el nombre del servidor en el que se está ejecutando y otro la hora del mismo. Los métodos de nuestro servicio Web son muy sencillos, pero son exactamente lo que necesitamos para mostrar de forma sencilla y práctica la cre- Es el momento de modificar nuestra página ASP.NET para hacer uso de estos dos nuevos métodos que hemos incorporado al servicio Web. Podemos añadir un botón más para que invoque a estos métodos y el resultado de la ejecución de los mismos los mostrará en otra etiqueta. El código resultante sería de la siguiente manera (fuente 7). Private Sub btnDatosServidor_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDatosServidor.Click lbDatosServidor.Text = MiServicio.NombreServidor() & "-----"& MiServicio.HoraServidor() End Sub Fuente 7 <%@ Page Language=”vb” AutoEventWireup=”false” Codebehind=”WebForm1.aspx.vb” Inherits=”Art.WebForm1”%> <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <HTML> <HEAD> <title>WebForm1</title> <meta name=”GENERATOR” content=”Microsoft Visual Studio .NET 7.1”> <meta name=”CODE_LANGUAGE” content=”Visual Basic .NET 7.1”> <meta name=”vs_defaultClientScript” content=”JavaScript”> <meta name=”vs_targetSchema” content=”http://schemas.microsoft.com/intellisense/ie5”> </HEAD> <body MS_POSITIONING=”GridLayout”> <form id=”Form1” method=”post” runat=”server”> <asp:Button id=”btnHolaMundo” style=”Z-INDEX: 101; LEFT: 48px; POSITION: absolute; TOP: 32px” runat=”server” Text=”Hola Mundo” Width=”104px” Height=”24px”></asp:Button> <asp:Label id=”lbHolaMundo” style=”Z-INDEX: 102; LEFT: 48px; POSITION: absolute; TOP: 72px” runat=”server” Width=”96px”></asp:Label> </form> </body> </HTML> Fuente 4 Public Class WebForm1 Inherits System.Web.UI.Page Dim MiServicio As New ServicioWeb Private Sub btnHolaMundo_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnHolaMundo.Click lbHolaMundo.Text = MiServicio.HolaMundo() End Sub End Class Fuente 5 También se pueden pasar todos los parámetros que sean necesarios a nuestros servicios Web. Por ejemplo podemos añadir un método que calcule el cubo del entero que le pasamos por parámetro. El método sería así (fuente 8): <WebMethod(Description:="devuelve el “ &_ “cubo de un entero")> _ Public Function Cubo(ByVal valor As _ Integer) As Double Return Math.Pow(valor, 3) End Function Fuente 8 Este nuevo método lo podemos utilizar desde la página ASP .NET, desde la que le pasamos el valor de una caja de texto para que calcule el valor al cubo correspondiente. A continuación se puede observar el fragmento de código de la clase de la página (fuente 9). Private Sub btnCubo_Click(_ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnCubo.Click lbResultado.Text = _ MiServicio.Cubo(txtValor.Text) End Sub Fuente 9 <<dotNetManía Figura 2 ación y utilización de servicios Web. Más adelante veremos cómo complicar un poco nuestro servicio Web. 15 << dnm.asp.net Imports System.Data Imports System.Data.SqlClient Public Class Clase Public Function DevuelveEmpleados() As DataSet Dim conexion As SqlConnection = New SqlConnection( _ "server=(local);database=northwind;uid=sa;pwd=xxx") Dim adapterEmpleados As SqlDataAdapter = New SqlDataAdapter( _ "select firstname, lastname from Employees", conexion) Dim ds As DataSet = New DataSet conexion.Open() adapterEmpleados.Fill(ds, "Empleados") conexion.Close() Return ds End Function End Class Fuente 10 <WebMethod(Description:="devuelve a través de un clase un DataSet de empleados")> _ Public Function DevuelveEmpleados() As DataSet Dim MiObjeto As New Clase Return MiObjeto.DevuelveEmpleados() End Function Fuente 11 <%@ Page Language=”vb” AutoEventWireup=”false” Codebehind=”WebForm1.aspx.vb” Inherits=”Art.WebForm1”%> <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <HTML> <HEAD> <title>WebForm1</title> <meta name=”GENERATOR” content=”Microsoft Visual Studio .NET 7.1”> <meta name=”CODE_LANGUAGE” content=”Visual Basic .NET 7.1”> <meta name=”vs_defaultClientScript” content=”JavaScript”> <meta name=”vs_targetSchema” content=”http://schemas.microsoft.com/intellisense/ie5”> </HEAD> <body MS_POSITIONING=”GridLayout”> <form id=”Form1” method=”post” runat=”server”> <asp:Button id=”btnSQL” style=”Z-INDEX: 105; LEFT: 32px; POSITION: absolute; TOP: 24px” runat=”server” Text=”Datos SQL”></asp:Button> <asp:DataGrid id=”dgDatos” style=”Z-INDEX: 106; LEFT: 144px; POSITION: absolute; TOP: 24px” runat=”server”></asp:DataGrid> </form> </body> </HTML> de datos; para realizar esta función utilizará una clase que vamos a agregar a nuestro proyecto de Visual Studio .NET, esto es tan fácil como pulsar con el botón derecho del ratón sobre nuestro proyecto y seleccionar del menú la opción de “Agregar clase”. El contenido del fichero VB en el que se define la clase va a ser el del fuente 10. Tiene un método que nos va a devolver en un objeto DataSet el contenido de la tabla de empleados. Desde el servicio Web podemos utilizar directamente la clase recién creada, es tan sencillo como instanciar un objeto de la clase y realizar la llamada al método correspondiente. En el siguiente código se puede apreciar la implementación del método del servicio Web que hace uso de esta clase (fuente 11). En todo este proceso ahora nos queda únicamente realizar la llamada al servicio Web desde la página ASP.NET. El código resultante sería el siguiente: primero aparece el código de la página (fuente 12) y luego el fragmento de código de la clase (fuente 13), también adjuntamos una figura en la que se muestra un ejemplo de ejecución de esta página (figura 3): Fuente 12 Private Sub btnSQL_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)_ Handles btnSQL.Click dgDatos.DataSource = MiServicio.DevuelveEmpleados() dgDatos.DataBind() End Sub Fuente 13 <<dotNetManía Servicios Web y acceso a datos 16 En algunos casos los servicios Web dentro de aplicaciones ASP.NET se utilizan como una capa intermedia de acceso a datos, en una arquitectura de una aplicación Web determinada pueden contener únicamente los métodos que hacen uso de clases de .NET que serán las encargadas de acceder a los datos. Vamos a realizar para nuestro servicio Web del ejemplo un método un poco más complicado que los anteriores. Este método nos va a devolver el contenido de una tabla de empleados de una base Figura 3 Ésta suele ser la forma más común de utilizar los servicios Web dentro de un entorno real de una aplicación Web de ASP.NET. El servicio Web es una capa intermedia entre las páginas ASP.NET y un conjunto de clases que van a realizar las operaciones sobre las bases de datos. Ahora animo a los lectores a que empiecen a hacer uso de los servicios Web dentro de sus proyectos de aplicaciones Web; como se ha podido observar es algo muy sencillo. dnm.comunicaciones Braulio Díez Redes de mensajería y .NET (y II) En la primera parte de esta serie, vimos cómo iniciar una sesión con Messenger (autentificándonos con éxito) y chequear nuestra lista de contactos. En esta segunda parte vamos a ver como “chatear” con ellos. << Servidores SwitchBoard Si los servidores de notificación nos sirven para dar a conocer nuestro estado y sincronizar nuestra lista de contactos, los Switchboard (que llamaremos también servidores de charla) sirven como salas en las que podemos establecer charlas con uno o varios compañeros. Hay dos formas de entrar en una charla: • Pasiva: Alguien nos invita a que participemos en una conversación (el mensaje que recibimos para ello, es muy descriptivo RNG… ¡Ring!). • Activa: Reservamos una sala de charla en un Switchboard server, y le comunicamos a alguien de nuestra lista que queremos hablar con él. << dotNetManía Entrar en charla de forma pasiva 18 Cuando un contacto de nuestra agenda quiere hablar con nosotros, reserva una sala de charla, y nos envía un mensaje en el que nos indica en qué dirección IP está dicha sala (el servidor switchboard), la secuencia de pasos sería la siguiente: 1. Recibimos un mensaje RNG indicándonos que uno de nuestros contactos quiere establecer una sesión de charla con nosotros (este comando nos da la dirección IP del servidor de charla al que nos debemos conectar) así como un valor que usaremos para autentificarnos. 2a. Establecemos una conexión con el servidor de charla que se indicó en el mensaje previo y confirmamos nuestra presencia enviando un mensaje ANS (en el que indicamos como parámetro el ID de sesión y el valor de autentificación que obtuvimos en el paso previo). 2b El servidor nos contesta dándonos una lista con los usuarios que pertenecen a esa charla. Para ello nos envía una serie de mensajes IR0 en los que se incluye el nombre de cada participante, y da por terminada la lista enviándonos un mensaje ANS. Cliente Messenger 1. << Mensaje RNG, alguien quiere hablar con nosotros Servidor de notificación 2. >> Conexión con el servidor de charla enviando un mensaje ANS 2. << Lista de usuarios que pertenecen a esa charla, IR0 Servidor de charla Ya estamos preparados para enviar y recibir mensajes de “chateo” Figura 1. Un contacto de nuestra agenda quiere hablar con nosotros. En la figura 1 puede ver un esquema de cómo se realiza ese diálogo y en la tabla 1 la secuencia de mensajes al detalle. Entrar en charla de forma activa Si somos nosotros los que queremos iniciar una conversación, esto implica un poco más de trabajo que en el apartado anterior: Pedimos una sala de charla libre al servidor de notificación, conectamos con Braulio Díez colabora habitualmente con dotNetManía. Es MCSD en programación distribuida con Visual C++. Es Solutions Developer de Avanade. << dnm.comunicaciones PASO 1. Recibimos del servidor de notificación un mensaje RNG en el que alguien nos indica que quiere hablar con nosotros (para ello, el mensaje nos da la dirección IP del servidor de charla al que nos tenemos que conectar y el identificador de la sala que nos ha reservado esa persona). // // // // << Recibimos del servidor de notificación una petición de charla. Los parámetros que tiene el mensaje son: ID de sesión de charla (podemos decir que es la sala), dirección IP del servidor de charla (switchboard server), algoritmo que se usa para la autentificación (siempre CKI), token que se usa para autentificarnos, dirección de correo y nombre de la persona que nos quiere contactar. RNG 11752013 207.46.108.38:1863 CKI 849102291.520491113 [email protected] Example%20Name\r\n PASO 2. Nos conectamos a la direccion del servidor de charla que obtuvimos en el paso anterior, le enviamos un mensaje ANS para confirmarle que queremos entrar en la sesión de charla, y el servidor de charla nos contesta dándonos una lista de los participantes de la misma. // ¡OJO!, al servidor de notificación no le respondemos nada, NOS CONECTAMOS AL SERVIDOR DE CHARLA // QUE OBTUVIMOS EN EL MENSAJE ANTERIOR. // // // >> El comando ANS tiene cuatro parámetros: La secuencia del mensaje (es un contador que vamos llevando nosotros, ver primera parte del artículo para más información), nuestra cuenta de pasaporte, el token de autentificación y el identificador de sesión de charla. ANS 1 [email protected] 849102291.520491113 11752013\r\n // // // << << El servidor nos informa de que participantes están en la conversación; el primer parámetro es el numero de secuencia del mensaje, el segundo la posición del participante en la lista de IR0's, el tercero es el número total de participantes que hay en esa lista, el cuarto es la cuenta passport del participante y el quinto su nombre. IRO 1 1 2 [email protected] Mike\r\n IRO 1 2 2 [email protected] My%20Name\r\n // Cuando se han enviado toda la lista de participantes, el servidor nos lo notifica con un mensaje ANS, con el mismo // número de secuencia que el ANS original que enviamos. << ANS 1 OK\r\n Tabla 1. Un contacto de nuestra agenda quiere hablar con nosotros (secuencia de comandos) cador de sesión que está asociado a la charla. 3c. Una vez que la persona con la que queremos hablar le ha confirmado 1. >> Petición de reserva, XFR Cliente Messenger 1. << Dirección de servidor de charla e identificador de sesión Servidor de notificación 2. >> USR con conexión y autentificación 2. << Confirmación sala reservada 3. >> Petición de llamada a un contacto, CAL 3. << CAL del servidor RINGING, llamando al contacto Servidor de charla 3. << Contacto acepta la invitación, JOI Ya podemos comenzar la charla Figura 2.Tomamos la iniciativa, y establecemos nosotros la conversación con uno de nuestros contactos <<dotNetManía ella, y a continuación invitamos a las personas con las que queremos hablar. La secuencia de pasos es la siguiente: 1a. Enviamos una petición de reserva de sala de charla (mensaje XFR). 1b. El servidor nos contesta indicándonos a qué servidor de charla nos podemos conectar, y cuál es nuestro identificador de sesión de charla. 2a. Establecemos conexión con el servidor de charla y nos autentificamos enviándole un mensaje USR con el identificador de sesión que obtuvimos en el paso previo. 2b. El servidor nos contesta informándonos que la sala ha sido reservada satisfactoriamente. 3a. Le pedimos al servidor de charla que llame (mensaje CAL) a uno de nuestros contactos. 3b. El servidor nos contesta con otro CAL que tiene como parámetro la cadena ”RINGING” , en el que nos confirma que está llamando a ese contacto. Otro parámetro que incluye ese mensaje es el identifi- 19 << dnm.comunicaciones PASO 1. Envíamos al servidor de notificación una petición de reserva de sala de charla (XFR), el servidor nos contesta dandonos la dirección IP de un servidor de charla (Switchboard server). // // // >> Enviamos al servidor de notificación una petición de sala de charla, los parámetros que tiene el mensaje son: número de secuencia del mensaje (ver puntos anteriores) y un segundo parámetro SB que significa “Switchboard” (pedimos conexión con un servidor de charla). XFR 15 SB\r\n // // // << El servidor nos contesta dándonos la dirección IP y el puerto del servidor de charla al que nos debemos conectar (tercer parámetro) y una cadena de autentificación que el servidor de charla nos pedirá cuando nos conectemos (último parámetro). XFR 10 SB 207.46.108.37:1863 CKI 17262740.1050826919.32308\r\n PASO 2. Nos conectamos a la dirección del servidor de charla obtenida y le enviamos un mensaje USR con la cadena de autentificación que recibimos en el paso anterior, si todo va bien el servidor nos contesta con otro mensaje USR con un parámetro cuyo valor es OK. // // // >> NOS CONECTAMOS AL SERVIDOR DE CHARLA QUE OBTUVIMOS EN EL MENSAJE ANTERIOR. El comando USR tiene tres parámetros: la secuencia del mensaje, nuestra cuenta de pasaporte y la cadena de autentificación que obtuvimos en el paso anterior. USR 1 [email protected] 17262740.1050826919.32308\r\n // Si todo va bien el servidor nos contesta con otro USR, con un parámetro con valor OK. << USR 1 OK [email protected] Example%20Name\r\n PASO 3. Le decimos al servidor de charla que queremos hablar con uno de nuestro contactos, el servidor nos notifica que lo está llamando, por último, si el contacto ha contestado afirmativamente a la llamada, el servidor nos informa de ello (en este caso ya podemos comenzar a hablar con él). // El comando CAL sirve para invitar a alguien a una conversación, tiene como parámetros: el número de secuencia // del mensaje, la cuenta pasaporte del usuario con el que queremos contactar. >> CAL 2 [email protected]\r\n // El servidor de charla nos indica que lo está llamando (Ringing) y nos da el identificador de sesión de la charla. // (último parametro) << CAL 2 RINGING 11752013\r\n // Si el contacto quiere hablar con nosotros, el servidor nos confirma que se ha unido a la charla, enviándonos un // mensaje JOI (join). << JOI [email protected] Name_123\r\n Tabla 2. Queremos establecer contacto con un miembro de nuestra lista de contactos (secuencia de comandos) al servidor de charla que quiere establecer comunicación con nosotros, este nos envía un comando JOI (join), en el que nos indica que esa persona ya está metida en la conversación. <<dotNetManía En la figura 2 puede ver un esquema de cómo se realiza ese diálogo, y en la tabla 2 la secuencia de mensajes al detalle. 20 Chateando… Una vez que ya tenemos la sala de charla a punto, para comunicarnos con [ Firewalls, Proxies… Para poder conectarnos a Messenger nos hace falta establecer como cliente una conexión TCP a un servidor, pero algunos administradores de red cortan esa posibilidad por motivos de seguridad. Cuando esto pasa tenemos que cambiarnos a la implementación del protocolo de Messenger via HTTP (bastante más lento que usando TCP, pero si no hay más remedio…). Podemos tener otro pequeño problema si tenemos que pasar por un servidor proxy, ya que esto nos afectará a las peticiones HTTPS que hagamos para autentificar nuestro pasaporte (las clases de .NET framework que gestionan esto, permiten añadir la dirección de nuestro proxy). ] << dnm.comunicaciones >> MSG Descripción Vamos sólo a cubrir el caso de un mensaje con texto de un participante: // // // // // // // >> En la cabecera del mensaje le indicamos nuestro número de secuencia, si queremos que nos confirme que el mensaje ha llegado y la longitud del cuerpo del mensaje en bytes. En el cuerpo, podemos ver que el mensaje es de tipo "plain text" y que el encoding que usa es UTF-8, tambén le indicamos otros datos como la fuente, el color... y por supuesto el texto que envíamos al participante... :-). MSG 4 N 133\r\n MIME-Version: 1.0\r\n Content-Type: text/plain; charset=UTF-8\r\n X-MMS-IM-Format: FN=Arial; EF=I; CO=0; CS=0; PF=22\r\n \r\n Hello! How are you?\r\n // El servidor nos notifica que el mensaje se recibió satisfactoriamente. << ACK 4 0\r\n << MSG Recibimos texto de un particpante (podríamos recibir otro tipo de información en este mensaje), ejemplo: // La cabecera del mensaje nos indica la cuenta de pasaporte y // nombre de la persona que nos envía el mensaje, así como la // longitud del cuerpo del mensaje. // El cuerpo del mismo es igual al MSG de salida que hemos // visto previamente. <<< MSG [email protected] Mike 133\r\n MIME-Version: 1.0\r\n Content-Type: text/plain; charset=UTF-8\r\n X-MMS-IM-Format: FN=Arial; EF=I; CO=0; CS=0; PF=22\r\n \r\n Hello! How are you?\r\n Tabla 3. Mensajes MSG los participantes de la misma enviaremos mensajes del tipo MSG, y recibiremos también mensaje de ese tipo cuando un participante quiera contarnos algo, ¿Simple...? Bueno, estos mensajes son del tipo payload, están compuestos por una línea de texto (que termina con \r\n) y un cuerpo de longitud variable (longitud indicada por un parámetro en la línea de texto anterior). Esta segunda parte nos puede indicar acciones como que el participante en concreto está tecleando, o simplemente recibir en ella el mensaje. En la tabla 3 puede ver la descripción de un mensaje con texto de charla. Como el contenido de un MSG es variable, se podrían implementar clientes que fueran capaces de enviar y recibir contenidos de mensajes con formato HTML o RTF. Sería interesante, por ejemplo, desarrollar un messenger para programadores que respetara el formato y colores del código fuente que enviemos. Ampliando nuestro ejemplo en .NET A nuestro ejemplo de messenger, le hemos añadido un nuevo namespace, se llama SwitchboardServer y se encarga de comunicarse con los servidores de charla. Al haber partes comunes con el namespace de notificación, he hecho un poco de refactoring y subido funcionalidad común a clases base que se comparten en el namespace General. Un diagrama con las clases principales lo puede ver en la figura 3. Las novedades más destacadas que se han introducido son: Namespace General Este incluye funcionalidad común, hemos añadido algo extra de funcionalidad. • MixedCharByteReader: Hasta ahora para leer mensajes, usabamos la clase StreamReader , que nos permite, de una forma muy cómoda, leer líneas de texto (detecta por nosotros donde está el salto de línea) y bloques de texto, pero... tenemos un pequeño problema, los mensajes con payload indican la longitud del cuerpo del mensaje en Figura 3. Diagrama de clases de nuestra assembly de ejemplos. <<dotNetManía Dirección Mensaje 21 << dnm.comunicaciones Namespace NotificationServer Figura 4. Funcionamiento de una charla “pasiva” <<dotNetManía bytes, y al estar esto codificado con UTF-8 (compatible con ASCII), en cuanto introducimos un caracter especial (como una letra con una tilde) el número de caracteres a leer ya no coincide con el número de bytes a leer. Solución: leer siempre bytes, e implementar una clase que nos ayude a leer líneas de texto y bloques de bytes. 22 [ Pocos cambios en este espacio de nombres, los necesarios para gestionar las sesiones de charla. • NotificationServer: Para poder iniciar una conversación tenemos que pasar por este servidor. Aquí es donde se nos asigna una dirección IP de un servidor de charla (cuando comenzamos una charla de forma activa) y donde recibimos mensajes RNG, que nos indican que un contacto quiere comenzar una charla con nosotros. Nota: La aplicación de ejemplo (disponible en www.dotnetmania.com) está realizada para poder “jugar” un poco con la red messenger; está lejos de ser un código en productivo, para dar este paso habría que añadir un control de errores más exhaustivo, tapar posibles agujeros, etc. ¿Peer to Peer? Cuando usamos Messenger no estamos trabajando de “igual a igual”, en realidad cuando hablamos con alguien, no estamos físicamente conectados a esa persona, sino que ambos nos conectamos a un servidor Messenger, podemos decir que ese servidor hace de proxy entre nosotros y las personas con las que hablamos. ] Namespace SwitchboardServer Para saber más Este es nuevo; envuelve toda la implementación para gestionar las sesiones de charlas (en figura 4 puede ver un esquema del funcionamiento de una charla pasiva). • SwitchboardSession: Esta clase se encarga de gestionar una sesión de charla en concreto. Dispone de una hebra que será la encargada de escuchar todos los mensajes relacionados con esa charla, así como de variables miembro que contienen información acerca de los participantes de la charla, cadena de autentificacion, eventos para notificar la llegada de nuevos mensajes, etc. • SwitchboardDispatcher: Es un contenedor de objetos. Tiene en una tabla hash los pares Session ID / SwitchboardSession, controla su creación y destrucción. Bueno, nos hemos “logado” a Messenger, hemos mantenido charlas con nuestros contactos, pero... ¡Yo quiero enviar ficheros¡ ¡Yo quiero conectarme con la webcam ¡ ¡Yo quiero...¡, si quiere seguir investigando sobre este interesante tema, aquí tiene unos links que le pueden ser de ayuda: Acerca del protocolo • La web “maestra” sin duda alguna es: http://www.hypothetic.org/docs/msn/ , muy completa (allí también encontrará unos apuntes sobre aspectos legales muy interesantes: http://www.hypothetic.org/docs/msn/phorum/read.php?f=1&i= 2169&t=2169 ). • Otra, en la que encontrará información acerca de esta y otra redes de mensajería: http://www.chat.solidhouse.com. • Tratando el tema de la seguridad, este documento es interesante: http://bofriis.dk/security/securing_msn.pdf. Implementaciones .NET: • Una implementación en C# del proceso de “login” la puede encontrar en: http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp. • Otra Implementación en C#, esta más completa, de libre uso, pero sin fuentes (sólo el assembly) es: http://members.home.nl/b.geertsema/dotMSN. dnm.plataforma.net José M.Alarcón Ampliando la capacidad de los controles y ventanas mediante técnicas de subclasificación La subclasificación de ventanas es una técnica específica de la plataforma Windows que permite ampliar las capacidades de la mayoría de los controles y formularios de Windows Forms. Con su uso se consiguen características poco frecuentes pero muy útiles.Veamos cómo sacarle partido. José Manuel Alarcón es redactor de dotNetManía. es ingeniero industrial y especialista en consultoría de empresa. Ha escrito varios libros, y ha publicado más de d oscientos artículos sobre informática e ingeniería en revistas especializadas. da desde sus orígenes en la existencia de mensajes que se envían constantemente a las ventanas. Cualquier cosa que ocurre en la interfaz está sustentada en el envío de mensajes. Por ejemplo, cuando pulsamos con el ratón sobre un botón éste puede responder a nuestra acción porque el sistema operativo le envía un mensaje indicándole lo que ocurre. Junto con el mensaje se le facilita también toda la información que necesita para gestionar el evento: posición del cursor, qué botón del ratón se ha usado, las teclas que están pulsadas, etc… Del mismo modo se envían mensajes a las ventanas para indicarles que se maximicen, se muevan, cambien de tamaño o incluso para que redibujen los controles que hay en su superficie. Además de hacerlo el propio sistema operativo, otras aplicaciones también pueden generar y enviar sus propios mensajes. De este modo es factible modificar el comportamiento de controles y ventanas aunque éstas no pertenezcan a nuestra aplicación. Existen técnicas de comunicación entre procesos que utilizan mensajes para intercambiar información de una forma genérica. En definitiva, los mensajes constituyen una parte integral del sistema y gracias a ellos se pueden conseguir multitud de efectos y características avanzadas. La primera manera de sacarle partido a los mensajes es enviándolos. Gracias a una función de la API de Windows, que luego estudiaremos, seremos capaces de enviar mensajes a ventanas y controles para forzarlas a hacer algo u obtener información sobre ellas. La otra manera de utilizar en nuestro provecho los mensajes es interceptándolos. Esta es la base de la subclasificación: interceptar mensajes dirigidos a una ventana para modificarlos, anularlos o responder a ellos. Dadas las muchas limitaciones de las que adolecían los formularios de Visual Basic clásico, esta técnica tenía un potencial increíble en aquella época. Por ejemplo, era indispensable realizar subclasificación para manejar iconos en el área de notificación o responder a notificaciones de cambios de archivos, por no mencionar la detección de muchas acciones que se llevaban a cabo sobre los formularios y para las que no había eventos. En la actualidad .NET y Windows Forms ofrecen tanta capacidad “de serie” que la subclasificación ya no es tan necesaria como antes. Sin embargo todavía hay muchas ocasiones en las que nos quitará de apuros. Para vislumbrar la potencia de estas técnicas vamos a desarrollar varios ejemplos que nos permitan estudiarla en la práctica, haciéndolo más entretenido. El código se escribirá en C# pero el lector interesado puede traducirlo a Visual Basic .Net con mucha facilidad porque es prácticamente idéntico. En la Web de la revista (www.dotnetmania.com) encontrará un archivo con los ejemplos ya desarrollados para facilitar su estudio. Le recomiendo que descargue estos ejemplos antes de continuar la lectura o puede que le resulte difícil seguirla. Primer ejemplo: engañando a una ventana Los formularios de Windows Forms poseen una propiedad muy interesante llamada TransparencyKey que sirve para especificar qué color de su superficie <<dotNetManía << La interfaz gráfica del sistema operativo Windows está basa- 23 << dnm.plataforma.net <<dotNetManía Figura 1. Las ventanas transparentes son muy espectaculares y fáciles de crear en .NET. La mayor dificultad viene a la hora de moverlas por carecer de barra de título. Subclasificando las pulsaciones del ratón podemos conseguirlo fácilmente. 24 se considerará transparente. De este modo basta con pintar algo sobre el área cliente del formulario (o asignar un gráfico cualquiera como fondo) para que las partes de éste que sean del color indicado en TransparencyKey se vuelvan transparentes (ver figura 1). Esto permite crear de una forma sencilla y rápida formularios con formas extrañas o caprichosas. Normalmente estos formularios, al igual que el de la figura, carecen de barra de título (propiedad FormBorderStyle con valor None) para que se parezcan lo menos posible a un formulario normal. El problema es que, al hacer esto, no hay forma de moverlas de su sitio ya que les falta la zona superior por la que normalmente se arrastran. ¿Cómo solucionamos esta situación? Muy fácil: engañando al formulario para que, al pulsar en cualquier parte de él se piense que en realidad se ha pulsado sobre la barra de título inexistente. Esta es una primera aplicación obvia de la subclasificación. Al contrario de lo que ocurría con otros lenguajes antiguos (Visual Basic, C, C++), poner en marcha esta técnica en .NET es sorprendentemente fácil. Basta con sustituir el método WndProc del formulario en cuestión para conseguirlo. Todas las ventanas de Windows (sean de .Net o no) disponen de una rutina especial que es la encargada de procesar todos los mensajes que se le envían. Normalmente hay que usar técnicas avanzadas para sustituir este procedimiento por otro propio y poder gestionar nosotros mismos los mensajes. Sin embargo los diseñadores de Windows Forms pensaron en hacernos la vida mucho más fácil a los programadores .NET y exponen dicha rutina como miembro de la clase Form con el nombre de WndProc. Por lo tanto basta con sustituirla por una propia para obtener todo el control sobre los mensajes. debemos procesar para engañar a la ventana. Cuando se pulsa sobre un lugar cualquier de una ventana, Windows le envía a ésta un mensaje de tipo WM_NCHITTEST. Cada mensaje se define con un valor numérico que en este caso es el número 84 en hexadecimal, por lo que es muy fácil detectarlo en la rutina de gestión de mensajes. Al enviar este mensaje, Windows envía también como información adicional en qué zona concreta de la ventana se ha pulsado. Por ejemplo, cuando se pulsó sobre el área cliente el valor es HTCLIENT (1), y si se toca la barra de título el valor es HTCAPTION (2). Todas estas constantes están definidas en el archivo winuser.h del SDK de plataforma para C/C++, disponible de manera gratuita en la Web de MSDN (http://www.microsoft.com/msdownload/platformsdk/sdkupdate) e incluido con Visual Studio. Bien, en resumen, lo que debemos hacer para mover la ventana por su área cliente es capturar el mensaje WM_NCHITTEST cuando se pulse sobre el área cliente de la ventana y engañar a ésta diciéndole que en realidad se ha pulsado sobre la barra de título. Todo el código que necesitamos es el del fuente 1 dentro del formulario. //Constantes de mensajes private const int WM_NCHITTEST = 0x0084; private const int HTCLIENT = 1; private const int HTCAPTION = 2; protected override void WndProc(ref Message m) { base.WndProc (ref m); if (m.Msg == WM_NCHITTEST) { if(m.Result.ToInt32() == HTCLIENT) m.Result = new IntPtr(HTCAPTION); } } Fuente 1 Una vez que podemos recibir desde nuestro código todos los mensajes dirigidos a una ventana, podemos decidir cuáles merecen nuestra atención o no, procesándolos de la forma más pertinente. Sabiendo esto, para acabar nuestro primer ejemplo, sólo necesitamos saber una cosa más: el mensaje que Las primeras líneas definen las constantes que necesitamos. El método WndProc recibe los mensajes de la ventana por lo que sólo debemos comprobar cuándo se recibe el que estábamos buscando (WM_NCHITTEST), y cambiamos el resultado del procesamiento asignándole otro valor. << dnm.plataforma.net Segundo ejemplo: mejorando los formularios La mayoría de los eventos de los formularios y controles de Windows Forms son en realidad el resultado del procesamiento de un mensaje. Minimizar una ventana, cambiarla de tamaño, activarla, moverla, etc… todas estas acciones se traducen en mensajes que es posible capturar. La plataforma .NET expone infinidad de eventos en sus controles y formularios que se corresponden con mensajes de Windows por lo que la mayoría ya están contemplados nativamente y no Los mensajes de ventana forman parte intrínseca y fundamental de la arquitectura de Windows. Comprendiendo el uso que el sistema hace de ellos es posible sacarle mucho partido para mejorar las características de nuestras aplicaciones Windows Forms tendremos necesidad de utilizar técnicas de subclasificación para gestionarlos desde nuestro código. De todos modos hay todavía algunos que no se gestionan y que en determinadas ocasiones pueden resultarnos de utilidad. Por ejemplo, sería de mucha utilidad que los formularios dispusieran de un evento que se notificase cuando cambie la resolución de la pantalla de modo que pudiéramos adaptar su tamaño o la disposición de los controles de forma automática. La clase Form no dispone de nada similar. He creado un ejemplo que define una nueva clase FormMejorada heredada de Form que es idéntica a ésta pero que añade algunas características interesantes mediante subclasificación. La clase FormMejorada Figura 2. Nuestro formulario ampliado ofrece tres nuevos añade tres nuevos eventos a los foreventos que le permitirán reaccionar a los cambios de resomularios Windows (figura 2). lución de pantalla, a modificaciones del tema estético aplica• ResChanged: se notifica este do a las ventanas y a condiciones de falta de memoria libre. evento cuando cambia la resolución de la pantalla. • ThemeChanged: se lanza cuando el de Form que sobrescribe el método usuario cambia el tema activo en WndProc y detecta tres mensajes espeel escritorio desde las propiedaciales que Windows envía a todas las des de pantalla. ventanas activas cuando ocurre alguno • LowMemory: notifica a la aplicación de estos eventos, y que son: WM_DISPLAYCHANGE, WM_THEMECHANGED y WM_COMque hay poca memoria libre en el PACTING respectivamente. La figura 3 sistema. Puede resultar de mucha utilidad en aplicaciones que conmuestra el código del procesamiento de suman muchos recursos. Al recimensajes. Estudie con detenimiento el bir este evento podemos liberar código que puede descargar desde la recursos cerrando ventanas inneWeb de la revista y verá que no tiene cesarias, manteniendo menos mayor complicación. datos en memoria o con acciones Para que uno de nuestros formusimilares. larios pueda hacer uso de este nuevo tipo de ventana mejorada sólo teneEl código es muy sencillo y consismos que acudir a su código y camte en definir una nueva clase heredada biarlo para que en lugar de heredar de <<dotNetManía El resultado es un puntero a un valor entero por lo que no debemos asignarle directamente HTCAPTION sino que encapsulamos antes este valor en una clase IntPtr que representa el puntero necesario. La clase Message ofrece a través de sus miembros todo lo necesario para acceder a la información del mensaje de Windows recibido en cada momento. La propiedad Msg contiene el valor del mensaje que se ha recibido. La propiedad Result es un puntero al resultado del procesamiento del mensaje. Las propiedades WParam y LParam contienen punteros a ciertos valores que se pueden pasar con el mensaje y que dependen del tipo de éste, ofreciendo adicionalmente el método GetLParam como un medio para copiar esta información a las estructuras con las que se corresponden. No vamos a profundizar en estos parámetros porque dependen del mensaje concreto que se procese y vienen profusamente documentadas en el SDK de plataforma. Siempre se debe permitir que el procedimiento original de la ventana procese también el mensaje o de otro modo impediremos que llegue correctamente a su destino y se impedirá el funcionamiento de la ventana, de ahí la llamada de la primera línea que ejecuta el proceso WndProc original al que estamos sustituyendo. Con esto hemos engañado a la ventana. Pruebe el ejemplo adjunto a este texto y verá cómo arrastrando por cualquier sitio la ventana transparente podrá moverla sin problemas. 25 << dnm.plataforma.net System.Windows.Forms.Form lo haga de FormMejorada. Sólo con cambiar esto, <<dotNetManía los formularios heredan estas interesantes características. Además de los mencionados eventos, y con la intención de ilustrar el uso de mensajes propios, nuestros formularios mejorados añaden también una nueva característica. Se trata de una opción adicional en el menú del sistema (que es el que aparece al pulsar sobre el icono de la ventana o sobre el botón correspondiente a ésta en la barra de tareas (vea la figura 4). En este caso se añade un separador y una opción “Acerca de…” como muestra la figura. Al pulsar sobre el nuevo menú, se muestra un diálogo con información sobre la aplicación. Para conseguir este efecto debemos recurrir primero a la API de Windows para agregar la nueva opción al menú del sistema del formulario. Estudiar el uso de la API desde .NET se sale del ámbito de este artículo por lo que no profundizaremos en ello (el lector puede ver el código completo en la descarga), pero mencionaré que es necesario utilizar dos funciones de la API en el constructor de la clase FormMejorada: • GetSystemMenu : esta función devuelve el manejador del menú del sistema del formulario que se le indique en el primer parámetro. • AppendMenu : agrega una nueva opción de menú como hija del menú que se le indica como primer parámetro. 26 Cuando un usuario pulsa sobre un menú también se envía un mensaje a la ventana que lo contiene. El valor identificador de dicho mensaje dependerá del menú en concreto que se ha seleccionado, pero en el caso del menú del sistema dicho valor es estándar y viene definido por la constante WM_SYSCOMMAND que es el que debemos detectar. Este mensaje viene acompañado por un parámetro que indica qué opción concreta del menú en cuestión es la que se ha seleccionado. En nuestro caso como la opción la definimos nosotros mismos podemos elegir el identificador que deseamos utilizar; en este caso hemos elegido el entero 1000 , y lo representamos con una constante de nombre WM_ACERCA_DE. Al definir la nueva opción de menú indicamos al sistema que debe usar como texto “Acerca de…” y como identificador del menú WM_ACERCA_DE (vea el código). Ahora lo único que nos queda es capturar el mensaje correspondiente, lo cual se consigue con sólo añadir las líneas del fuente 2 a la sentencia switch de la figura 3. deseemos o incluso interceptar la pulsación de las opciones estándar (minimizar, maximizar, mover…) para sustituirlas o modificar su comportamiento. Tercer ejemplo: un cuadro de texto un tanto especial En Windows no sólo los formularios son tratados como ventanas. En realidad casi todos los controles con un área de usuario se tratan exactamente del mismo case WM_SYSCOMMAND: if (m.WParam.ToInt32() == WM_ACERCA_DE) MessageBox.Show("(c) José M. Alarcón Aguín 2004 \n\n www.jasoft.org", "Acerca de...", MessageBoxButtons.OK, MessageBoxIcon.Information); break; Fuente 2 Figura 3. Código de gestión de mensajes para generar los eventos de nuestro formulario extendido. Es decir, si el mensaje revela una pulsación sobre el menú del sistema, se comprueba además si la opción elegida es la nuestra, en cuyo caso se muestra un diálogo con el copyright. Usando esta técnica podemos añadir tantas opciones como modo y no son más que tipos especiales de ventanas. Así, los cuadros de texto, botones, listas desplegables, rejillas, menús, barras de botones, e infinidad de controles no son más que tipos especiales de ventana. Otros controles que se dibu- << dnm.plataforma.net jan mediante código no se tratan como tales. El ejemplo más evidente es el de las etiquetas (Label), que no son ventanas. Normalmente todos los controles que son ventanas disponen de una propiedad Handle que permite obtener su manejador de ventana. Todos los tipos de ventana funcionan exactamente igual en lo que se refiere al tratamiento de mensajes. Por lo tanto es posible subclasificar también los controles para mejorar sus características. Sólo Figura 6. Código del cuadro de texto ampliado que gestiona los mensajes del portapapeles, los anula y sustituye sus acciones asociadas. es necesario conocer qué mensajes en concreto les afectan y ello está ampliamente documentado en el SDK de plataforma y en MSDN. Para terminar con el artículo vamos a crear un control de texto mejorado que, a las características habituales de este tipo de controles, añade las siguientes: • No permite pegar texto desde el portapapeles, impidiendo así que se modifiquen sus contenidos a menos que el usuario los escriba directamente pulsando teclas. • Cuando un usuario copia o corta texto desde uno de estos cuadros de tex- Figura 5. Formulario de ejemplo que utiliza dos controles de texto extendidos desarrollados en el artículo. to mejorados, se le añade automáticamente información de copyright a los contenidos que van a pasar al portapapeles. • Dispone de una propiedad de sólo lectura llamada FirstVisibleLine que nos permite averiguar cuál es la primera línea de los contenidos que está visible en el control tras haber realizado un desplazamiento (scroll) de éstos (ver figura 5). • Expone una propiedad LeftMargin que nos permite indicar o averiguar el margen en píxeles que el cuadro de texto deja a la izquierda de los contenidos, en lugar de pegarlos totalmente que es el comportamiento por defecto. Las dos primeras características se consiguen capturando los mensajes que Windows envía a la hora de utilizar el portapapeles. Las restantes implican que sea nuestro código y no el sistema operativo el que envíe ciertos mensajes al control para que cambie su forma de actuar o nos proporcione información como resultado de procesarlos. Lo primero es crear una clase, TextBoxEx, que derive de TextBox. En este caso aunque no es un formulario también tenemos la oportunidad de sobrescribir el método WndProc ya que estos controles son, como se comentó, un tipo más de ventana. Cuando un usuario copia, corta o pega texto en un TextBox, éste recibe los mensajes WM_COPY, WM_CUT y WM_PASTE respectivamente. Sólo hay que capturarlos tal y como se observa en el código de la figura 6. <<dotNetManía Figura 4. Hemos añadido una opción “Acerca de” a nuestro formulario ampliado. Ahora podemos ofrecer información directamente desde el menú del sistema asociado a los formularios extendidos. 27 << dnm.plataforma.net Nótese que en este caso se llama también el método WndProc de la clase base, pero se hace al final del procedimiento y no al principio. Se hace así para tener la oportunidad de cambiar el mensaje antes de que lo procese el control. De este modo lo que hacemos es anular el mensaje en los tres casos sustituyendo su código por un cero, que es lo mismo que no enviar mensaje alguno, y haciendo el trabajo nosotros mismos. Como queremos anular la posibilidad de pegar texto, simplemente se anula el mensaje. Dado que al copiar y pegar queremos incluir un mensaje de copyright en el portapapeles junto con el contenido original, anulamos el mensaje e implementamos nosotros mismos ambas acciones escribiendo directamente en el portapapeles. Para implementar las propiedades adicionales de nuestro control mejorado haremos uso de una función de la API de Windows que nos permite enviar mensajes mediante código a cualquier formulario o control. La definición de la función SendMessage es la del fuente 3. A esta función se le pasa como parámetros un puntero al manejador de la ventana objetivo del mensaje (un entero de 32 bits que es una especie de identificador global de ésta), la constante que identifica al mensaje que se envía y los valores de los parámetros adicionales que caracterizan al mensaje enviado. Todas las ventanas (y controles que son ventanas) de Windows disponen de un identificador llamado manejador de ventana (window handle) que en .NET se puede obtener a través de su propiedad Handle. La función SendMessage, además de enviar un mensaje, devuelve el resultado del procesamiento de éste por parte de la ventana objetivo. Ello permite usarla también para obtener información interesante de los controles. Por ejemplo, cuando se envía un mensaje EM_GETFIRSTVISIBLELINE a un control TextBox, éste tras procesarlo, devuelve como resultado el número de línea que actualmente está de primero en el área visible del control. Ello puede ser útil en controles multilínea cuyo [DllImport("user32.dll", EntryPoint="SendMessage")] private static extern int SendMessage( IntPtr hWnd, int wMsg, int wParam, int lParam); Fuente 3 public int FirstVisibleLine { get { return SendMessage(this.Handle, EM_GETFIRSTVISIBLELINE, 0, 0); } } <<dotNetManía Fuente 4 28 public int LeftMargin { get { return SendMessage(this.Handle, EM_GETMARGINS, EC_LEFTMARGIN, 0); } set { SendMessage(this.Handle, EM_SETMARGINS, EC_LEFTMARGIN, value); } } Fuente 5 contenido puede haberse desplazado ya que no hay ninguna propiedad o método que nos informe de ello. El código para obtener este dato es, por tanto, así de sencillo (vea el fuente 4). El mensaje EM_SETMARGINS sirve para ajustar los márgenes de los controles de texto. En este caso se debe especificar con el parámetro WParam qué margen es el que se fija y con LParam el número de píxeles que tendrá. Por otra parte existe un mensaje muy similar, EM_GETMARGINS que funciona de manera parecida y sirve para obtener el valor actual de los márgenes. Según esto, para crear la propiedad LeftMargin que deseábamos para el control extendido, debemos escribir el código del fuente 5, que lo que hace es enviar sendos mensajes para obtener y ajustar el valor del margen del control actual, cuyo manejador se obtiene con la propiedad Handle. Revise con detenimiento el código complementario a este artículo para ver cómo se utiliza el nuevo control en un formulario común. En resumen Los mensajes de ventana forman parte intrínseca y fundamental de la arquitectura de Windows. Comprendiendo el uso que el sistema hace de ellos es posible sacarle mucho partido para mejorar las características de nuestras aplicaciones. En este artículo hemos estudiado como aprovecharlos para ciertas tareas y hemos visto la forma de extender formularios y controles estándar de Windows Forms para añadirle nuevas capacidades. La documentación del SDK de plataforma es la referencia más importante sobre los mensajes de Windows y le recomendamos que la estudie si quiere ampliar conocimientos. La utilidad de la técnica se ha visto mermada gracias a la gran cantidad de características incluidas en .NET pero aún así, y como hemos podido comprobar, todavía se le puede sacar mucho partido. Aún quedan muchas posibilidades por explorar en esta técnica. Esperamos que el artículo le haya abierto los ojos a nuevas formas de hacer las cosas en el sistema operativo Windows. dnm.plataforma.net Rodrigo Corral Sistemas distribuidos en .NET con Remoting (I) Sin duda la gran mayoría de las aplicaciones que se desarrollan actualmente son aplicaciones distribuidas. El framework de .NET nos proporciona un poderoso marco para el desarrollo de este tipo de aplicaciones.Veremos como .NET remoting permite desarrollar, desplegar y configurar con facilidad aplicaciones distribuidas sin los quebraderos de cabeza y las limitaciones que presentaban anteriores soluciones. miento y procesamiento de la información es realizado sobre varias computadoras que permanecen en contacto entre ellas mediante elementos de comunicación. Ventajas de los sistemas distribuidos Rodrigo Corral colabora habitualmente con dotNetManía. Es Microsoft MVP y analista de Sisteplant, empresa líder en el sector de las aplicaciones de gestión industrial • Compartición de recursos: Un sistema distribuido permite compartir hardware y software. • Apertura: La apertura de un sistema es el grado al cual se puede extender agregándole nuevos recursos no propietarios. Los sistemas distribuidos son sistemas abiertos que incluyen software y hardware de diferentes fabricantes. • Concurrencia: En un sistema distribuido varios procesos operan al mismo tiempo en diferentes computadoras de la red comunicándose entre ellos si es necesario. • Escalabilidad: En un sistema distribuido relativamente sencillo aumentar la capacidad del mismo añadiendo nuevos elementos al sistema. A menudo esta escalabilidad se ve limitada por el nexo de unión entre los diferentes equipos, habitualmente el factor limitador es la capacidad de la red. • Tolerancia a fallos: Disponer de varios equipos trabajando en paralelo permite duplicar aquellos equipos que realizan tareas críticas, de manera que ante la caída de un equipo no ocurra una pérdida del servicio proporcionado por el sistema. • Transparencia: La transparencia consiste en esconder al usuario la arquitectura del sistema. Para el usuario es indiferente usar un sistema distribuido. Desventajas de los sistemas distribuidos • Complejidad: Es evidente que los sistemas distribuidos son más difíciles de diseñar, construir, depurar y mantener. • Seguridad: El sistema se puede acceder desde diferentes lugares, lo que hace que el tráfico de red pueda estar sujeto a inspecciones no deseadas. • Mantenibilidad: Las diversas computadoras de un sistema pueden ser de diferentes tipos o ejecutar diferentes sistemas operativos. Los fallos en una máquina pueden propagarse con consecuencias impredecibles a priori. • Impredecibilidad: Como vemos a diario, como usuarios de Internet, los sistemas distribuidos son impredecibles en su respuesta. Ésta depende de la carga del sistema, de su estado y de la carga de la red, lo que hace que el tiempo para atender peticiones varíe ampliamente. Tecnologías para el desarrollo de aplicaciones distribuidas El desarrollo de aplicaciones distribuidas sería una tarea prácticamente impracticable sin la existencia de diferentes tecnologías o frameworks que hacen la tarea más llevadera proveyendo una serie de servicios básicos a toda aplicación distribuida. A lo largo de los últimos tiempos se han desarrollado diferentes de estos frameworks; a menudo unos son evolución lógica de otros añadiendo una nueva capa de abstracción y simplicidad. <<dotNetManía << Un sistema distribuido es áquel donde el almacena- 29 << dnm.plataforma.net DCE/RPC Disctributed Computing Environment (DCE) fue diseñando por la Open Software Fundation, a principios de los años 90, en un intento de proveer una serie de herramientas y servicios (llamadas a procedimientos remotos, seguridad, etc...) que facilitasen el desarrollo de sistemas distribuidos. Sin embargo aunque DCE/RPC ha sido una tecnología ampliamente usada y válida, nunca se ha caracterizado por su facilidad de implementación. Otro importante problema es que la implementación ha estado restringida a lenguajes diferentes de C/C++. Otra carencia de este entorno es la ausencia total de orientación a objetos. A pesar de estos problemas, DCE/RPC es la base para algunos de los frameworks más usados como son COM+ y DCOM. Muchas aplicaciones distribuidas de amplio uso, también tienen como base DCE/RPC, por ejemplo, MS SQL Server, Exchange Server, SMB (Server Message Block) y NFS (Network File System). <<dotNetManía CORBA (Common Object Requets Broker Arquitectura) 30 CORBA es un estándar definido por el consorcio OMG (Object Management Group), formado por más de 800 empresas. CORBA es solamente una colección de estándares; la implementación es realizada por todas aquellas terceras compañías que lo deseen. Esto unido a que partes del estándar son opcionales y a que a menudo las compañías que implementan el estándar añaden extensiones propietarias incompatibles con otras implementaciones, han hecho que el objetivo de interoperabilidad con el que nació CORBA no se haya alcanzado de manera plena. A pensar de estos problemas, dejando a parte SOAP, CORBA es el único entorno multiplataforma y multilenguaje para aplicaciones distribuidas. Existen ORBs (Object Request Brokers) para la totalidad de sistemas operativos y librerías para el desarrollo en la mayoría de los lenguajes. También existen capas para integrar CORBA con otras tecnologías como COM y EJB. COM/DCOM (Distributed Component Object Model) A veces llamado oRPC (Object RPC), DCOM es una extensión de RPC orientada a objetos. COM nace a raíz de la necesidad de compartir objetos entre aplicaciones, ya sean objetos visibles (componentes ActiveX) o objetos sin parte visual (librerías ActiveX). DCOM es una extensión de COM que permite desplegar los componentes de una aplicación de manera transparente sobre una red para formar un sistema distribuido. DCOM presenta problemas en lo relativo a su uso sobre redes dispersas, al usar un formato binario (DCE/RPC) para transmitir la información y realizar la asignación de puertos para comunicaciones de manera dinámica, hace difícil su uso si hay firewalls de por medio. La principal pega de este marco tecnológico es que está íntimamente ligado a sistemas Windows y la dificultad de una correcta configuración, aunque ésta no es mayor que la habitual en otros sistemas distribuidos. La total integración con los sistemas Windows es sin duda el punto fuerte de COM+. Mencionar por último que .NET delega en COM+ cuando necesita los servicios anteriormente citados. Java EJB Entrerprise Java Beans (EJB) fue la respuesta que SUN dio a COM+. EJB es un estándar pero al contrario que CORBA, que es sólo un estándar, SUN proporciona una implementación de referencia, lo que garantiza que un sistema que corra sobre esta implementación lo hará sobre cualquier otra que esté de acuerdo al estándar. Sin duda los servicios Web son el primer entorno que realmente logra una verdadera solución a la integración entre sistemas heterogéneos, gracias al uso de estándares ampliamente extendidos y ya existentes en la mayoría de las plataformas Existen implementaciones de DCOM para Windows y Unix, sin embargo, su uso está casi restringido a sistemas Windows donde, con anterioridad a .NET, constituía un marco tecnológico casi omnipresente. COM+ COM+ fue el primer intento serio de Microsoft de proveer un servidor de aplicaciones de nivel empresarial. En esencia, COM+ es una serie de servicios (eventos distribuidos, pool de objetos, transacciones distribuidas, mensajería entre aplicaciones, eventos bajo suscripción, administración de seguridad, balanceo de carga, etc...) construidos sobre DCOM y que extienden sus posibilidades. EJB ha sido ampliamente aceptado por la industria informática, de manera que existen implementaciones del estándar realizadas por numerosas empresas e incluso implementaciones Open Source muy dignas (www.jboos.org). El principal problema con EJB es que a menudo las empresas implementan contenedores que aportan características más allá del estándar, y si las usamos, nuestro sistema estará ligado a un contendor determinado. Otro problema es que el despliegue de la aplicación y la configuración del contendor es un proceso bastante complicado. Web Services/SOAP/XML-RPC Sin duda los servicios Web son el primer entorno que realmente logra una ver- << dnm.plataforma.net ¿Qué es .NET Remoting? Si bien .NET Remoting se basa en tecnologías similares a las comentadas para los servicios Web, no tiene la interoperatibilidad como principal meta. Esto permite que el acceso a objetos remotos se pueda realizar mediante protocolos más eficientes... .NET Remoting Si bien .NET Remoting se basa en tecnologías similares a las comentadas para los servicios Web, no tiene la interoperatibilidad como principal meta. Esto permite que el acceso a objetos remotos se pueda realizar mediante protocolos más eficientes, lo que unido a la posibilidad de usar objetos que mantienen su estado entre llamadas, lo convierten en un candidato ideal para el desarrollo de aplicaciones distribuidas. .NET Remoting ofrece un marco de desarrollo de aplicaciones distribuidas muy flexible y extensible que permite al desarrollador y al administrador elegir el meca- nismo de transporte, el formato de codificación y la configuración de la seguridad. El único punto flojo es la necesidad de declarar de manera precisa que un objeto va a ser usado remotamente en el momento de su codificación; esto no era necesario con los objetos DCOM, cualquier objeto podía ser remoto sin necesidad de hacer cambios en su código. Ésta en cualquier caso es una pega menor. .NET Remoting frente a DCOM • • • • • • • No es tan transparente como DCOM. No necesita de los servicios de interoperabilidad (Interop). Ofrece mayores opciones de despliegue. No está ligado a un protocolo o formato de comunicación. Tolera los firewalls. Delega los servicios empresariales en COM+. Permite especificar explícitamente que objetos son remotos. .NET Remoting frente a Web Services • No requiere Internet Information Server en la parte servidora. • Gran flexibilidad a la hora de elegir donde “vive” el servidor. • Provee total orientación a objetos (propiedades, métodos, constructores y eventos). • No está ligado a HTTP para el transporte. • No está ligado a SOAP para la codificación de la comunicación. • Posibilidad de usar objetos con estado. • Permite un total control sobre la transmisión de la información y el tiempo de vida de los objetos. • Más flexible y más complejo que los Web Services. • Menor capacidad para interoperar con otros sistemas. • Más información: • NET Remoting frente a los servicios Web ASP.NET www.microsoft.com/spanish/msdn/articulos/archivo/221102/voices/bdadotnetarch14.asp. • ASP.NET Web Services or .NET Remoting: How to Choose: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/bdadotnetarch16.asp <<dotNetManía dadera solución a la integración entre sistemas heterogéneos, gracias al uso de estándares ampliamente extendidos y ya existentes en la mayoría de las plataformas. Los servicios Web usan HTTP POST para realizar llamadas a componentes remotos, usando XML para codificar la información necesaria para realizar la llamada, pasar parámetros y recibir resultados. SOAP es el protocolo más usado a la hora de codificar la información necesaria para realizar la llamada. SOAP (Simple Object Access Protrocol), WSDL (Web Service Description Language) y UDDI (Universal Dscription, Discovery and Integration) constituyen una serie de estándares basados en XML y HTTP que forman un marco tecnológico que permite de una manera sencilla la comunicación entre sistemas heterogéneos gracias a la amplia disponibilidad de HTTP y XML, únicas tecnologías necesarias para la implementación de estos estándares. La principal carencia de los servicios Web es la imposibilidad de mantener el estado de los objetos entre llamadas y el menor rendimiento. .NET Remoting es la arquitectura nativa para la invocación de objetos remotos en la plataforma .NET. Más adelante entraremos en detalle de qué es lo que se considera un objeto remoto en .NET; de momento basta con mencionar que un objeto remoto es el que se crea en un dominio de aplicación distinto. .NET Remoting permite la creación, invocación y comunicación entre objetos a través de los límites de procesos y máquinas. Es totalmente independiente del protocolo de comunicación y el formato en el que se transmite la información. .NET Remoting es EXTENSIBLE: permite controlar cómo y sobre qué protocolo se transmite la información. Podemos definir nuestros propios canales y “formateadores”. 31 << dnm.plataforma.net .NET Remoting es FLEXIBLE: se puede cambiar el despliegue y la configuración de los objetos, sin tener que realizar cambios en el código, a través de archivos de configuración. .NET Remoting surge por la necesidad de atravesar las fuertes fronteras impuestas por los dominios de aplicación y de máquina. Sin .NET Remoting es imposible invocar objetos fuera de nuestro dominio de aplicación o fuera de nuestra máquina. <<dotNetManía ¿Qué son los dominios de aplicación? 32 Las aplicaciones .NET se ejecutan en un proceso físico, no manejado, pero como sabemos requieren un entorno manejado para su ejecución. Un dominio de aplicación provee ese entorno manejado dentro de un proceso no manejado. Los dominios de aplicación también permiten la portabilidad pues son un concepto lógico, no algo físico. Al contrario que los procesos, los dominios de aplicación no están ligados al sistema operativo. Los dominios de aplicación (Application Domains) son fronteras de procesamiento utilizadas para aislar aplicaciones. Los dominios de aplicación proveen una unidad de procesamiento segura y versátil que el CLR puede usar para proveer aislamiento entre aplicaciones. Los assemblies se cargan en un dominio de aplicación de manera que tengan acceso a los recursos manejados como son el Garbage Collector, la pila o los servicios de Interop. Cada proceso puede contener múltiples dominios de aplicación, aunque habitualmente sólo habrá uno por proceso. Se pueden crear mediante código nuevos dominios de aplicación por motivos de aislamiento y seguridad. Diferentes dominios de aplicación pueden tener diferentes privilegios de seguridad. Cruzar los límites de un dominio de aplicación es menos costoso que cruzar los límites de un proceso, pero aún así hay un coste. Por ejemplo, ASP.NET pone cada aplicación en un dominio de aplicación diferente, sin embargo, todas comparten proceso. Figura 1. Esquema de la arquitecutra .NET Remoting Los motivos para la elección de este modelo son: • Nos beneficiamos del aislamiento sin tener el coste de un nuevo proceso. • Crear y parar un dominio es más ligero que crear y parar un proceso. • Menor consumo de recursos, mantener un dominio es menos costosos que mantener un proceso. • Las variables estáticas lo son por dominio. Arquitectura de .NET Remoting Dado que las aplicaciones deben compartir objetos, es necesario un mecanismo que permita cruzar los límites impuestos por los dominios de aplicación. Uno de estos mecanismos es .NET Remoting. Cuando cruzamos los límites de un dominio de aplicación es necesario abrir un canal. Los canales proporcionan un camino para transportar datos cuando un cliente llama a un objeto en otro dominio de aplicación. .NET proporciona dos canales por defecto HttpCannel y TcpChannel que usan HTTP y TCP respectivamente como protocolo de comunicación. Una vez que tenemos un canal abierto es necesario formatear los objetos que queremos mover a través del canal. De nuevo .NET proporciona dos “formateadores” por defecto: SOAP y Binary. SOAP es a menudo usado para la comunicación entre sistemas heterogéneos mientras que el formato binario es mucho más eficiente, pero está limitado a la comunicación entre sistemas .NET. Los principales elementos en la arquitectura de .NET Remoting son: • Mensajes (Messages): Qué comunicamos. • Canales (Channels): Dónde establecemos la comunicación. • Formateadores (Formatters): Cómo establecemos la comunicación. Estos elementos se asocian en una cadena (Sink Chain), y mediante la combinación de diferentes mensajes, canales y formateadores podemos adaptar la comunicación a nuestras necesidades. Mensajes Los mensajes son objetos que implementan la interfaz IMessage. Esta interfaz simplemente presenta un diccionario de pares de claves y valores. Existen diferentes tipos de mensajes: • Según su propósito: • Mensajes de construcción de objetos y su respuesta asociada. • Mensajes de invocación de métodos y su respuesta asociada. • Según el tipo de invocación • Síncronos: Invocación de un método con espera a una respuesta inmediata. • Asíncronos: Invocación de un método con una respuesta no inmediata o sin respuesta. << dnm.plataforma.net Canales Figura 3. Channel Sink Chain: total control sobre el proceso La cadena del canal (Channel Sink Chain) Los diferentes elementos que hemos visto hasta ahora se combinan en forma de cadena para formar la cadena del canal. Como muestra la figura 3, la cadena del canal esta formada por los diferentes elementos encargados de la codificación y trans- Figura 2. Canal: la vía de comunicación Los canales se pueden personalizar de forma que provean a los desarrolladores de control sobre el propio mecanismo de transporte de mensajes a y desde el objeto remoto. Todos los mensajes se pasan a través de SecuritySink, TransportSink y FormatterSink antes de que se puedan transportar a la aplicación remota, donde fluyen a través de los mismos receptores en orden inverso. El framework de .NET provee dos canales por defecto: el canal TCP y el canal HTTP. misión se de los objetos. También forman parte de esta cadena los elementos proporcionados por el programador, de manera que se puede variar el comportamiento del canal, modificando el tipo de elementos que forman la cadena o incluso interponiendo nuestros propios elementos (Sinks) en la cadena. Canal HTTP El canal HTTP transporta los mensajes a y desde los objetos remotos utilizando el protocolo SOAP. Todos los mensajes se pasan a través del formateador de SOAP, donde el mensaje se cambia a XML y se pone en serie; también en esta fase se agregan a la secuencia los encabezados de SOAP necesarios. Asimismo, se puede especificar el formateador binario, que resulta en una secuencia de datos binaria. A continuación, ésta se transporta al URI de destino utilizando para ello el protocolo HTTP. Características del canal HTTP: • System.Runtime.Remoting.Channels.Http. • Usa el protocolo HTTP 1.1. • La transmisión se realiza en formato SOAP 1.1 (XML). • La serialización se realiza en formato SOAP (SoapFormatter). • Estándar abierto. • La mejor elección para la comunicación a través de Internet. • La mejor elección para interoperatibilidad e integración. Canal TCP El canal TCP utiliza el formateador binario para poner en serie todos los mensajes en una secuencia binaria, transportando la secuencia al URI de destino con el protocolo TCP. Características del canal TCP: • System.Runtime.Remoting.Channels.Tcp • Utiliza sockets planos TCP para la comunicación. <<dotNetManía Los canales se utilizan para transportar mensajes a y desde objetos remotos. Cuando un cliente llama a un método en un objeto remoto, los parámetros, así como otros detalles relacionados con la llamada, se transportan a través del canal al objeto remoto. Cualquier resultado de la llamada se devuelve al cliente de la misma forma. Un cliente puede seleccionar cualquiera de los canales registrados en el servidor para comunicarse con el objeto remoto, permitiendo a los desarrolladores, por tanto, cierta libertad en cuanto a la selección del canal que mejor se ajuste a sus necesidades. También se puede personalizar un canal existente, o bien, construir nuevos canales que empleen protocolos de comunicación distintos. Todos los canales se derivan de IChannel e implementan IChannelReceiver o IChannelSender, dependiendo del propósito del propio canal. La mayoría implementan tanto la interfaz del destinatario como la del remitente, a fin de permitir que éstos se comuniquen en cualquier dirección. 33 << dnm.plataforma.net • Utiliza el formato binario para la comunicación. • Por defecto utiliza el formateador BinaryFormatter. • Es el formato nativo de .NET. • Es muy rapido y poco pesado. • Puede utilizar formateadores personalizados. • Es la mejor elección para comunicaciones en entornos LAN. • Utiliza conexiones permanentes. • No recomendado para conexiones a través de Internet. Canales personalizados Los canales personalizados nos permiten usar nuestros propios protocolos (APPC, IPX, Pipes...) para la comunicación.También nos permiten seleccionar nuestro propio formato para la transmisión de la información, podemos usar los formateadores por defecto (SOAP o binario) o nuestro propio formato (IIOP, RMI, ORPC...). Tiene utilidad sobre todo para la integración de tecnologías. Figura 4. Proxy: transparencia en la ubicación del objeto Remoting hosts Un remoting host, es necesario en la parte servidora para proveer un entorno manejado para el objeto remoto. El host es el responsable de registrar los tipos remotos servidos por él, así como los canales que usará para servirlos. Podemos usar dos tipos de remoting hosts IIS o host de usuario (generalmente implementados como ejecutables). IIS como Remoting Host Formateadores Los formateadores son los encargados de serializar los objetos en el formato adecuado para su transmisión a través del canal. Los formateadores son utilizados por el canal de forma implícita, y se implementan como uno de los elementos de la cadena que forma el canal. El framework de .NET proporciona dos formateadores por defecto uno para formato SOAP, generalmente asociado al canal SOAP y otro para formato binario generalmente asociado al canal TCP. • Usar IIS evita tener que escribir el código del host. • Provee autenticación y encriptación (SSL). • Sólo puede servir objetos a través de canales HTTP. • Soporta el formateador SOAP y el binario. • Objetos sin estado pueden ser distribuidos en una granja de servidores. • No requiere la instalación del proceso host en el lado servidor. Remoting Hosts personalizados • Prácticamente cualquier ejecutable .NET puede servir como remoting host. <<dotNetManía Proxys 34 Cuando un cliente llama a un método en un proxy, el marco de servicios remotos intercepta la llamada y ésta se cambia a mensaje que, a su vez, se reenvía a la clase RealProxy (o más bien a una instancia de la clase que implementa RealProxy). La clase RealProxy reenvía dicho mensaje a un receptor de mensajes para su procesamiento. El receptor de mensajes se encarga de establecer la conexión con el canal registrado por el objeto remoto y de transportar los mensajes a través del canal (a otro dominio de aplicación), desde donde se distribuye al propio objeto remoto. El proxy está formado por dos elementos: El transparent proxy, proporcionado por el framework y que no podemos modificar y el real proxy, que podemos adecuar a nuestras necesidades, modificando su comportamiento. using System; namespace HelloRemoting { public class HelloRemotingObject : MarshalByRefObject { public HelloRemotingObject() { } public string GetHello() { return “Hello from “ + Environment.MachineName; } } } Fuente 1. HelloRemnoting.cs << dnm.plataforma.net System; System.Runtime.Remoting; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Channels.Tcp; HelloRemoting; • Permite total flexibilidad en cuanto a los canales usados. • Permite total flexibilidad en cuanto a las opciones de despliegue. • Puede usar canales tanto TCP como HTTP. • Puede usar configuración basada en archivos o mediante programa. • No provee ningún servicio de autenticación o encriptación. • El remoting host debe estar corriendo antes de poder llamar a los objetos que expone. namespace HelloRemotingClient { class ClientStarup { [STAThread] static void Main(string[] args) { //Creamos un nuevo canal TcpChannel chnl = new TcpChannel(); //Registramos el canal ChannelServices.RegisterChannel(chnl); //Obtenemos el objeto remoto HelloRemotingObject hro = (HelloRemotingObject)Activator.GetObject( typeof(HelloRemotingObject), “tcp://tiron:1234/HelloRemotingObject.TCP”); //Llamamos a un metodo del objeto remoto y mostramos el resultado Console.WriteLine(hro.GetHello()); El primer servidor de objetos remotos Pasos para escribir un servidor de objetos remotos 1) Console.ReadLine(); } } } Fuente 2. HelloRemnotingClient.cs using using using using using System; System.Runtime.Remoting; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Channels.Tcp; HelloRemoting; 2) 3) namespace HelloRemotingHost { class ServerStartup { [STAThread] static void Main(string[] args) { //Creamos un nuevo canal TcpChannel chnl = new TcpChannel(1234); //Registramos el canal ChannelServices.RegisterChannel(chnl); //Configuramos remoting para exponer el objeto RemotingConfiguration.RegisterWellKnownServiceType( typeof(HelloRemoting.HelloRemotingObject), “HelloRemotingObject.TCP”, WellKnownObjectMode.SingleCall); Console.WriteLine(“Presione una tecla para detener el servidor...”); Console.ReadLine(); } } } Fuente 3. HelloRemnotingHost.cs Creamos una DLL con los tipos de objetos remotos que queremos exponer, podemos ver el código en HelloRemoting.cs , en nuestro ejemplo simplemente devolvemos la cadena ”Hello” seguida del nombre de la máquina. Elegimos el tipo de host que vamos a utilizar: Custom host o IIS; en el ejemplo simplemente utilizaremos una aplicación de consola como host. Escribimos el código necesario para crear nuestro host, que podemos ver en HelloRemotingHost.cs 4) a. Cargamos los tipos. b. Decidimos qué tipos vamos a exponer. c. Configuramos remoting para exponer esos tipos. Escribimos un programa cliente, que podemos ver en HelloRemotingClient.cs. Ejemplo: HelloRemoting (ver material de apoyo de este artículo en www.dotnetmania.com) En la próxima entrega veremos los diferentes comportamientos que pueden presentar los objetos en .Net Remoting, cómo el Framework controla el tiempo de vida de los objetos y como podemos variar la lógica que controla el tiempo de vida de los objetos. <<dotNetManía using using using using using 35 dnm.servidores.sql Salvador Ramos SQL Server Analysis Services ¡Hola Cubo! (III) Con este artículo concluiremos la creación de nuestra primera base de datos multidimensional, en la que tendremos un cubo compuesto por dos medidas y cinco dimensiones, que ya quedará listo para su explotación con las herramientas cliente. << Es el momento de continuar con las tareas que dejamos pendientes en el anterior artículo. Ahora vamos a crear la dimensión Artículo, esta es una dimensión con “Esquema de copo de nieve” (snowflake schema). Este tipo de dimensiones se utiliza cuando queremos crear una estructura jerárquica a partir de diversos campos de una tabla, algunos de ellos son clave externa de otra tabla y suelen agrupar varias filas de elementos. Procedamos a la creación de la dimensión artículo. Para ello volvemos a crear una nueva dimensión con el asistente, y en este caso indicaremos que queremos crear la dimensión como “Esquema de copo de nieve”, que es el que nos permite crear una dimensión con una jerarquía de niveles basados en múltiples tablas de dimensiones relacionadas. <<dotNetManía Salvador Ramos colabora habitualmente con dotNetManía. Es Microsoft SQL Server MVP y responsable del sitio HelpDNA.com, formador y consultor de Inforges, en las áreas de Bases de datos (SQL Server, Oracle, DB2/400) y de tecnologías .NET 36 El siguiente paso es seleccionar las tablas de dimensiones que vamos a utilizar. En este caso vamos a crear una dimensión artículo que tiene dos niveles (Familia y Artículo). La información para generar estos dos niveles se encuentra en las tablas dwArtic y dwFamilias de nuestro origen de datos, que son las que seleccionaremos como se puede apreciar en la imagen. Ahora es el momento de indicar la columna o columnas que nos servirán de enlace entre ambas tablas, siguiendo las instrucciones que aparecen en la pantalla. Hay que tener en cuenta que el asistente intenta realizar las combinaciones que él considera correctas, pero casi siempre tenemos que retocar manualmente estas combinaciones. En la siguiente pantalla hay que seleccionar las columnas que formarán los distintos niveles de nuestra dimensión, en este caso el primer nivel será la familia del artículo, y dentro de cada familia ten- << dnm.servidores.sql dremos un segundo nivel formado por todos los artículos de dicha familia. Nivel Familia Name Familia Member Name Column RTRIM("dbo"."dwFamilias"."nombre")+' [' + RTRIM(CAST("dbo"."dwFamilias"."codigo" AS CHAR(3))) + ']' Order By Key (Hay que tener en cuenta que la propiedad Order By se encuentra en la pestaña “Avanzadas”, mientras que el resto se encuentran en la pestaña “Básicas”). Nivel Artículo Name Artículo Member Name Column RTRIM("dbo"."dwArtic"."nombre") + ' [' + RTRIM(CAST("dbo"."dwArtic"."codigo" AS CHAR(15))) + ']' Order By Key En la siguiente pantalla, donde debemos especificar las columnas clave del miembro pulsaremos el botón “Siguiente”. Hay que resaltar que al finalizar el asistente nos aparecerá el editor de dimensiones donde podremos realizar cualquier modificación que no hayamos tenido en cuenta durante su creación con el asistente. En la pantalla de opciones avanzadas tampoco haremos ningún cambio, y pulsaremos el botón “Siguiente”. Dejaremos para otra ocasión el manejo de las opciones avanzadas del asistente. Finalmente nos pide el nombre de la dimensión, allí escribiremos Artículo, y pulsaremos el botón “Finalizar”. Al igual que en los casos anteriores, vamos a realizar ciertas personalizaciones en las propiedades para que la dimensión y cada uno de sus niveles presenten la información de la forma más clara posible. Esto por supuesto depende de los gustos y preferencias de cada uno, pero yo seguiré utilizando las características que expuse anteriormente :-). Modificaremos las propiedades con los valores que se indican: 1 Ahora continuaremos montando una dimensión que prácticamente es necesaria en cualquier cubo que vayamos a realizar, el Tiempo. Casi siempre necesitaremos contrastar los datos cronológicamente. Para estos casos el asistente para la creación de dimensiones del Analysis Manager dispone de una serie de opciones que nos permiten crearla de una forma muy sencilla. Ejecutaremos de nuevo el asistente para dimensiones, y en este caso seleccionaremos la que también será nuestra tabla de hechos 1, la tabla Una Tabla de Hechos es la tabla central de un esquema, y es necesario que haya una, y sólo una, por cada cubo que tengamos en nuestra base de datos multidimensional.Esta tabla contiene medidas numéricas y claves que relacionan los hechos con las tablas de dimensiones.Aquí están los datos de sucesos específicos de nuestro negocio, como ventas, compras, pagos. Se suelen generar, en muchas ocasiones, a partir de lo que conocemos como tablas de movimientos, mientras que las tablas de dimensiones se suelen generar a partir de lo que solemos llamar tablas maestras o tablas auxiliares. <<dotNetManía Bueno, pues aquí tenéis ya creada una dimensión jerárquica formada por dos niveles. 37 << dnm.servidores.sql dwVentasCabDet, que como comentamos anteriormente es una tabla denormalizada en el DataWarehouse, que contiene información de las tablas normalizadas VentasCab y VentasDet (cabecera y detalle de ventas). Ahora elegiremos como tipo de dimensión “Dimensión de tiempo”, y seleccionaremos la columna de fechas, que siempre será un campo DateTime o SmallDateTime; en concreto crearemos la dimensión por el campo de fecha de venta (FechaMov). <<dotNetManía En el siguiente paso debemos elegir la estructura jerárquica que queremos que tenga esta dimensión -como veis nos lo está poniendo bastante fácil el asistente-. En este caso queremos que la estructura de la dimensión sea “Año, trimestre, mes, día”, en la pantalla se pueden ver las diversas variantes que tenemos disponibles para la estructura de esta dimensión. 38 En la siguiente pantalla ya se ven con detalle los diferentes niveles que acabamos de crear para nuestra dimensión Tiempo, aquí simplemente pulsaremos el botón “Siguiente”. Y como en casos anteriores, y debido al nivel de iniciación de este artículo, no haremos ninguna modificación en las opciones avanzadas, y pulsaremos el botón “Siguiente”. Para concluir indicaremos el nombre de la dimensión, Tiempo en este caso, y pulsaremos el botón “Finalizar”. Y aquí tenéis el resultado de esta dimensión y su estructura jerárquica. Os puede ser útil echar un vistazo a los valores Member Key Column y Member Name Column de cada uno de los niveles de esta dimensión. éstas deben ser siempre datos numéricos. Seleccionaremos las columnas Cantidad, Precio y Pr Compra. Una vez seleccionadas las medidas, elegiremos las dimensiones que formarán nuestro cubo. En este caso, y puesto que sólo vamos a crear un cubo y hemos creado expresamente las dimensiones que necesitamos para este ejemplo, las seleccionaremos todas. Aunque lo habitual es que en una base de datos multidimensional tengamos muchas más dimensiones compartidas que serán utilizadas en otros cubos. Por ejemplo, es habitual tener una dimensión Proveedor que será utilizada en un cubo de Compras, etc. Con esto concluimos la creación de dimensiones compartidas. Ahora vamos a proceder a la creación de un cubo que utilice estas dimensiones. Para ello pulsaremos el botón secundario del ratón sobre la carpeta Cubos, y elegiremos la opción “Nuevo Cubo/Asistente…”, como se muestra en la imagen. Nos aparecerá la primera pantalla del Asistente para cubos que es meramente informativa, y pulsaremos el botón “Siguiente”. Ahora debemos elegir la tabla de hechos de nuestro cubo, que será dwVentasCabDet, y pulsaremos el botón “Siguiente”. Ahora es el momento de seleccionar la Medidas que tendrá nuestro cubo; Ahora va a proceder el asistente a hacer el recuento de filas de la tabla de hechos, y nos avisa que este proceso puede tardar en completarse, dependiendo del número de filas de la tabla. Pulsaremos “Sí” y esperaremos a que finalice el recuento. Una vez finalizado este proceso, lo más habitual es que el asistente no sea capaz de combinar automáticamente las columnas de la tabla de hechos con las correspondientes en las tablas de dimensiones, y nos dará un aviso indicándonos las que no ha podido combinar. Pulsaremos el botón “Aceptar”. Finalmente nos mostrará la << dnm.servidores.sql En este momento aparecerá el editor de cubos, donde podremos ver en la parte de la izquierda las dimensiones y medidas que forman nuestro cubo, y debajo de éstas otra serie de objetos (Miembros calculados, Celdas calculadas, etc.) que se salen del ámbito de este artículo, pero que sí que quiero indicar que nos abren un amplio abanico de posibilidades de cálculo y de obtención de información para los cubos. En la parte de la derecha podemos ver un diagrama de la estructura del cubo, mostrándose en color amarillo siempre la tabla de hechos y en color azul las tablas de dimensiones. Ahora procederemos a completar las combinaciones de columnas para establecer las relaciones correctamente y a recolocar las tablas para que nos quede más claro el diseño. Así es como queda, como se ve es muy similar a la estructura de nuestro DataWarehouse, pero esto es porque hemos construido un DataWarehouse muy pequeño y estamos utilizando todas sus tablas en nuestro único cubo. Lo habitual es que contenga una gran cantidad de tablas. Es conveniente realizar unas tareas bastante sencillas, éstas son la validación de la estructura del cubo y la optimización del esquema. Las podemos realizar con dos de las opciones disponibles en el menú “Herramientas” del Editor de Cubos del Analysis Manager. Una vez que hemos realizado todos estos pasos, ya hemos terminado la creación de nuestro cubo, y es muy importante que procedamos a guardarlo. Ahora para que realmente podamos acceder a la información, en primer lugar debemos procesar el cubo, consiguiendo así alimentarlo con datos procedentes del DataWarehouse. Este proceso será el que cuando lo ejecutemos la primera vez nos pida que diseñemos la estructura de almacenamiento, donde indicaremos el número de agregaciones que queremos que el cubo tenga ya calculadas y listas para mostrarnos. Cuanto mayor sea este número, más rápidas serán las consultas, ya que accederá directamente a los datos sumados y almacenados, pero en contraposición, será mayor su tamaño y su tiempo de proceso. Como en este caso es la primera vez que procesamos el cubo, debemos indicar las opciones de almacenamiento. Este proceso, al igual que el resto se hace bastante sencillo al abrirse un asistente que nos va guiando paso a paso. Como aquí no vamos a entrar en detalles de optimización del rendimiento, no haremos ningún cambio dejando todos los valores que aparecen por defecto y pulsando el botón “Siguiente”. Como habréis comprobado, hemos utilizado el tipo de almacenamiento MOLAP explicado en el primer artículo de esta serie. Conclusión Objetivo conseguido, ya tenemos un cubo cargado de información y listo para ser accedido desde diversas herramientas cliente para mostrar los datos al usuario. Aunque este tema lo dejaremos para el siguiente artículo … Y finalmente, para no dejaros sin ver los resultados, os diré que si pulsáis el botón secundario del ratón sobre el cubo, y elegís la opción “Examinar datos” podréis echar un primer vistazo a los datos del cubo. En el próximo artículo explicaremos con más detalle cómo utilizar el “Examinador de cubos” y cómo acceder con otras herramientas cliente, como MS Excel y MS Data Analyzer. <<dotNetManía estructura del nuevo cubo, con sus dimensiones y medidas, y nos pedirá el nombre que le queremos asignar, en este caso le llamaremos Ventas, y pulsaremos el botón “Finalizar”. 39 dnm.plataforma.net José Miguel Torres Interoperabilidad no administrada y migración (I) << Durante los últimos años COM ha sido el modelo de programación de referencia que utilizábamos los desarrolladores cuando teníamos en nuestras manos herramientas Microsoft. Ahora, este modelo de componentes ha cambiado; como suele ocurrir en informática, se está quedando obsoleto. Prácticamente todos los componentes que tocábamos en Visual Basic 6.0, entre otros lenguajes, estaban basados en COM, como ADO, SQL DMO, CRXDRT, etcétera. Pues bien, ahora todo ello ha quedado atrás y a la hora de empezar a desarrollar una aplicación ya empezamos a contar con .NET. Pero, ¿qué hacemos con componentes propios que funcionan perfectamente? Pues bien ésta y otras preguntas las trataremos en estas páginas. Código administrado y no administrado <<dotNetManía José Miguel Torres colabora habitualmente con dotNetManía. Es técnico superior en desarrollo de aplicaciones informáticas y trabaja como arquitecto de software en el departamento de tecnologías de la información de MRW 40 Con el tiempo las aplicaciones en .NET sustituirán a las aplicaciones basadas en COM, pero hasta que esto suceda habrá una serie de componentes que funcionan a la perfección que podremos utilizar, o incluso crear, desde nuestras aplicaciones .NET. He aquí un ejemplo de interoperabilidad. Pero profundicemos algo más. El código de una aplicación en .NET que compila el CLR, se llama Código Administrado. Éste utiliza datos que son gestionados en cuanto a solicitud y asignación de memoria o la comprobación de tipos por el CLR (Common Language Runtime) con lo cual los datos también pasan a ser datos administrados. Así cualquier acceso que debamos hacer a cualquier código, sea COM o no, que esté fuera de este marco de desarrollo será código no administrado, como los ActiveX o las llamadas a API Win32. Los tipos de datos, la definición en sí de componente y sus métodos y el control de errores son totalmente dis- tintos entre código administrado y no administrado. CLR permite ocultar estas diferencias para poder facilitar la migración y/o interoperabilidad entre ambos. De esta forma podremos consumir componentes bajo las rigurosas normas COM desde .NET, pero también podremos consumir componentes .NET desde COM, así como utilizar librerías de vínculo dinámico (DLL) externas, no basadas en COM, como por ejemplo las APIs de Windows, desde .NET. En la interoperabilidad de código administrado a código no administrado existe una serie de reglas que establecen la conversión de manera segura y lo más eficaz posible. Estas reglas utilizan un cálculo de referencias y su ámbito se centra en la administración de memoria, y en las conversiones de tipos en todos sus contextos, desde el paso de parámetros hasta la manipulación de matrices. Para poder entender mejor en qué consiste detallaremos un comportamiento predeterminado en interoperabilidad COM. Tanto en código administrado como en no administrado existen tipos de datos de 1, 2 y 4 bytes, por ejemplo. Sí, es verdad que se llaman distinto, por ejemplo un long de Visual Basic 6.0 equivale a un Int en el CLR (System.Int32), en realidad no se debe hacer un cálculo muy complejo puesto que un dato de 4 bytes no supondrá un control exhaustivo por parte del contador de referencias, sino que tendrán una representación común en memoria. A estos tipos se le llaman tipos que se pueden representar como bits o bytes. Sin embargo existen tipos de datos que sus representaciones no pueden basarse en bits o bytes. La representación de dichos tipos en código no administrado es, por tanto, distinta que en código administrado y viceversa, y será la aplicación de una serie de reglas para el cálculo de sus referencias las que harán posible su inte- << dotNetManía Conocer las ventajas y posibilidades tanto de COM Interop como de la interoperabilidad con código no adminsitrado en general, nos permite no sólo extender el alcance de nuestras apliciones sino replantearnos los escenarios de migración,ayudados con estas técnicas que ofrece .NET, permitiendo una mayor productividad, menores costes de mantenimiento y como resultado una estrategia de migración mas eficiente. 40 << dnm.plataforma.net Tipos de Datos que se representan en bits o bytes Tipo que no puede representarse como bits o bytes System.Byte System.Array System.SByte System.Boolean System.Int16 System.Char System.UInt16 System.Class System.Int32 System.Object System.UInt32 System.String System.Int64 System.Valuetype System.IntPtr System.UIntPtr Matrices unidimensionales de estos tipos Tabla 1. Relación de tipos que pueden o no representarse como bits o bytes. El proceso interno y funcional de CCW no es idéntico que RCW. Cuando un componente .NET es llamado por un COM, el runtime lee la información de tipo para el componente del metadato del ensamblado y genera un CCW compatible que ejerce de proxy entre ambos contextos. De la misma forma que RCW y CCW se responsabiliza de crear y administrar el objeto administrado crea las interfaces más importantes como IUnknown e IDispatch en él, basadas en tipo de información del componente .NET e interpreta las excepciones .NET en valores COM HRESULT para el manejo de errores. roperabilidad. Ambos los podemos encontrar en la tabla 1. El cálculo de referencias facilita, como hemos visto, la conversión de tipos entre contextos, aunque a veces, deberemos echarle una mano, por ejemplo, con conversiones explícitas en llamadas a funciones externas. Con la entrada de .NET Framework son muchos ya los que han empezado a migrar sus aplicaciones a .NET. En muchos casos, existen componentes COM que funcionan perfectamente y que las empresas optan por exponerlos bajo código administrado, descartando la necesidad de reprogramarlos de nuevo. También los hay que desarrollan componentes .NET para que puedan ser accesibles desde componentes COM. Estos son un ejemplo bidireccional entre la interoperabilidad COM y .NET. CLR es el encargado de gestionar la interoperabilidad entre ambos pero, realmente, ¿cómo lo hace? Pues se ayuda de contenedores. Veamos que son. Para conocer más a fondo la interoperabilidad debemos conocer la existencia y funcionamiento del Runtime Callable Wrapper RCW. RCW es un contenedor que actúa como proxy para las llamadas a código no administrado. Cuando un componente realiza una llamada, ésta utiliza o se ayuda de RCW para que a través de sus interfaces públicas llegue la llamada al Figura 1.Tanto RCW como CCW facilitan la tarea de Interoperabilidad entre COM y .NET objeto COM bajo código no administrado. RCW no deja de ser un objeto administrado por CLR aunque su funcionamiento es algo distinto ya que su principal función es el cálculo de referencias de llamadas entre .NET y COM. Asimismo RCW es la responsable de la creación del objeto COM que recibirá la llamada, de administrar la vida de uso del mismo y su posterior deshecho administrando a su vez una caché de punteros de interfaz. También compatibiliza los tipos de datos entre ambos contextos mediante la aplicación de las reglas de cálculo de referencias en argumentos entre métodos y valores de retorno, así como interpretará los valores retornados por COM HRESULT en excepciones administradas. Si RCW permitía la comunicación desde .NET a COM, COM Callable Wrapper CCW, es el que se encarga del proceso contrario, es decir, es el contenedor COM que permite la llamada de un objeto COM a uno .NET. Para ver más claramente la funcionalidad de ambos contenedores expondremos dos ejemplos de interoperabilidad, de COM a .NET y viceversa en unos ejemplos sencillos. Implementar COM desde .NET El primer paso es importar toda la información del componente COM para que se pueda exponer bajo .NET y el lugar dónde está dicha información es en la biblioteca de tipos. Para ello lo primero que hay que hacer es importar la biblioteca de tipos como un ensamblado. En la biblioteca de tipos se guarda la información del componente COM; por otro lado los metadatos son los encargados de esa misma función para .NET. Ambos son muy distintos con lo que necesitamos que la biblioteca de tipos genere dicha información para poder residir bajo un ensamblado. Los archivos de biblioteca de tipos residen como archivos inde- <<dotNetManía Interoperabilidad COM vs. .NET 41 <<dotNetManía << dnm.plataforma.net 42 pendientes bajo extensión .TLB o bien dentro del mismo componente COM DLL o COM EXE. Aunque a priori parece complejo, tenemos cuatro posibles vías de importación y de un manejo realmente sencillo. Por una parte tenemos el propio Visual Studio. NET. Quizás sea la opción más sencilla y directa aunque también la menos flexible. Visual Studio .NET convierte directamente la biblioteca de tipos en metadatos de un ensamblado. El proceso es muy similar al de referenciar a un ensamblado. Cuando agregamos una referencia a nuestro proyecto tenemos, por una parte los componentes .NET firmados y registrados en nuestro sistema y en otra ficha los componentes COM, tales como ADODB, etcétera. En caso de tener nuestro propio componente buscaremos el archivo de biblioteca de tipo con extensión .DLL, .TLB, .EXE o dónde proceda, el cual deberemos tener registrado en el sistema, y lo seleccionaremos. Otra posibilidad es importar la biblioteca de tipos y generar un ensamblado con su propio espacio de nombres de una forma más flexible mediante una herramienta que funciona bajo el intérprete de comando y que se llama TLBIMP.EXE. Su funcionamiento puede ser tan sencillo como ejecutar el programa seguido del archivo .DLL o . TLB, incluyendo a continuación una serie de parámetros opcionales que permitirán una serie de operaciones como la de crear, por ejemplo, un espacio de nombre propio con nombre seguro para evitar el problema de la duplicación de nombres mediante la utilización de fichero de claves keyfile. Otra alternativa, quizás las más flexible, es utilizando la clase TypeLibConverter. TypeLibConverter es una clase sellada (no heredable) del espacio de nombre System.Runtime.InteropServices que permite convertir objetos COM a .NET y viceversa. Es lógico pensar pues, que la utilización de esta clase pueda resultar mucho más flexible, como la posibilidad de convertir en metadatos una biblioteca de tipos almacenada en memoria, y además algo más compleja que las posibilidades vistas anteriormente. Nos podemos encontrar con el caso de que un componente no tenga una biblioteca de tipos determinada o ésta contenga información errónea. Esta situación se resuelve mediante los contenedores COM personalizados. Éstos crean una definición del componente en código administrado y posteriormente es compilado con un compilador CLR para generar los metadatos en un ensamblado. Desgraciadamente es necesario una serie de elementos entre los que se encuentran las descripciones de las interfaces del componente y conocimiento de las reglas de conversión de biblioteca de tipos en ensamblados. De todas estas posibilidades vistas obtenemos un ensamblado. El ensamblado resultante se conoce como ensamblado de interoperabilidad primaria. Dicho ensamblado puede ser modificado mediante el desensamblador y/o creado manualmente mediante compilador, añadiendo ciertos atributos. Vamos a ver un ejemplo que va a ser realizado con Visual Basic 6.0, aunque también podríamos utilizar Visual C++ 6.0 para la realización del componente COM. La definición del componente en Visual Basic 6.0 la podemos ver en la figura 2. fichero DLL llamado clsUsuario.dll. Para facilitar y no extendernos demasiado, dicha clase no contiene dependencias a ningún otro objeto COM. Además, Visual Basic 6.0 crea la biblioteca de tipos dentro del mismo archivo DLL por defecto. Veremos cómo utilizar dicha clase mediante dos de las tres posibles opciones de interoperabilidad dentro de nuestro proyecto .NET. Visual Studio .NET Bien, ahora se trata de que desde .NET podamos utilizar todas las propiedades, métodos y eventos; así que lo primero es la importación de la biblioteca de tipos. En este primer supuesto partimos de la base que tenemos el fichero clsUsuario.dll y tenemos la biblioteca de tipos en dicha clase. Mediante Visual Studio .NET en nuestro proyecto agregamos una nueva referencia (figura 3). En la ficha COM localizamos el fichero clsUsuario.dll y los seleccionamos y fijémonos en el comportamiento de Visual Studio .NET. La referencia que se ha añadido es UsuarioCOM. Este nombre proviene del nombre del proyecto que ha genera- Figura 2. Clase COM en Visual Basic 6.0 que utilizaremos para el ejemplo. Se trata de un módulo de clase que gestiona, de una manera simple, un determinado usuario en un contexto funcional de manipulación de expedientes. Esta clase ha sido compilada y como resultado hemos obtenido un do la clase clsUsuario.dll. Como ha encontrado la biblioteca de tipos a partir de la DLL, la referencia UsuarioCOM es del tipo ActiveX, y no Assembly como por ejemplo System.Data. << dnm.plataforma.net Figura 3. Formulario Agregar referencia de Visual Studio .NET private void Form1_Load(object sender, System.EventArgs e) { UsuarioCOM.clsUsuarioClass usu = new UsuarioCOM.clsUsuarioClass(); //asignamos eventos usu.ExpedienteCaducado += new UsuarioCOM.__clsUsuario_ ExpedienteCaducadoEventHandler(usu_ExpedienteCaducado); //asignamos una propiedad de prueba usu.Apellidos = "Torres"; //obtenemos de una propiedad MessageBox.Show(usu.Apellidos); } // evento ExpedienteCaducado. private void usu_ExpedienteCaducado( ref object expediente, ref DateTime fechaCaducado) { } Fuente 1. Ejemplo de utilización del ensamblado de interoperabilidad primaria. Figura 4.Vista del Ensamblado de Interoperabilidad primaria des del Examinador de objetos <<dotNetManía Si examinamos el espacio de nombres UsuarioCOM vemos que éste se encuentra dentro de interop.usuariocom. Además dentro de dicho espacio de nombres encontramos una serie de elementos. Éstos elementos han sido creados para que el componente se integre en el CLR de manera satisfactoria. Encontramos 4 interfaces que implementan los respectivos métodos y propiedades, por un lado, y los eventos, por otro, que ha encontrado en clsUsuario. Además, ha creado dos delegados correspondientes a los dos eventos de clsUsuario y que se implementan en la interface __clsUsuario_Event. Recordemos que en COM, una itnerfaz es una clase abstracta, y que siempre se crea una interfaz con prefijo subrayado, en este caso _clsUsuario. Durante la importación se crea una clase administrada que representa a cada coclase COM, en este caso de la clase original clsUsuario a clsUsuarioClass , añadiéndole al final la palabra Class. De manera transparente, al importar se le añade a la clase administrada el atributo GuidAttribute para capturar el identificador de clase (CLSID) perteneciente a la coclase, clsUsuario, cuyas interfaces tienen un único identificador global (IID). Además se agrega una interfaz con el mismo nombre que la coclase y al igual que la clase administrada en dicha interfaz se añade un atributo CoClassAttribute para la identifación CLSID de la coclase origen. Como el nombre de los elementos de un mismo tipo no pueden ser el mismo, al importar, por defecto, se resuelve cualquier conflicto subrayando antes del nombre de la interfaz, de ahí que encontremos interfaces con nombre __clsUsuario. En la clase administrada clsUsuarioClass, .NET ha añadido un constructor por defecto sin parámetros (figura 4). Hasta aquí hemos visto la sencillez de importación de un componente COM propio y hemos explicado lo que hace .NET cuando se importa una clase de tipo COM. Las llamadas..., pues tan sencillo como utilizar cualquier otra clase en .NET como podemos observar en el ejemplo del fuente 1. 43 << dnm.plataforma.net TlbImp.exe Para mostrar el siguiente ejemplo de cómo importar el componente COM vamos a crear la biblioteca de tipos fuera de la DLL. Para ello, a la hora de compilar el proyecto UsuarioCOM de Visual Basic 6.0 en la propiedades de proyecto, en la ficha componente, marcamos la opción “Remote Server Files”, generar archivos remotos. Esto generará un archivo clsUsuario.TLB con la descripción de la biblioteca de tipos. Lo que haremos será importar mediante TlbImp.exe la biblioteca de tipos y registrar el ensamblado resultante con un nombre seguro. Para ello abriremos el “Símbolo del sistema” de Visual Studio .NET y ejecutamos la utilidad TlbImp.exe seguido del nombre del archivo que hace referencia a la biblioteca de tipos y que tiene extensión TLB; en nuestro caso sería clsUsuario.tlb. Podemos utilizar los parámetros /keyfile para aplicar un nombre seguro señalando el fichero resultante de la ejecución de la utilidad sn.exe, por ejemplo. El resultado una vez ejecutado TlbImp será un archivo DLL. El nombre por defecto será el que ha utilizado anteriormente y que es el equivalente al nombre del proyecto de Visual Basic 6.0 en el que se compiló, o sea, UsuarioCOM.DLL. A continuación utilizaremos la utilidad Regasm.exe y registraremos el nuevo ensamblado, UsuarioCOM. Figura 5.Vista desde del bloc de notas del ensamblado UsuarioCOM en MSIL. Una vez hecho esto ahora sí podemos desde Visual Studio .NET agregar una referencia pero no es necesario que sea desde la ficha de COM, sino que en el mismo .NET seleccionamos el recientemente creado archivo UsuarioCOM.DLL. Ahora, podemos empezar a trabajar bajo código administrado. observar, pese a que la teoría y funcionamiento interno es realmente complejo, el CLR nos lo oculta y nos permite interactuar con objetos COM de una manera simple, transparente y eficaz. Esta es la primera parte de tres entregas. En la siguiente entrega veremos un ejemplo de interopera- C:\sn -k UsuarioCOM.snk C:\Tlbimp clsUsuario.tlb / keyfile:UsuarioCOM.snk Este ensamblado, llamado ensamblado de interoperabilidad, será el encargado de hacer de puente con el componente COM. Dicho ensamblado puede ser modificado manualmente utilizando el desensamblador IldASM.exe. Si ejecutamos C:\ildasm Figura 6.Vista del ensamblado de interoperabilidad UsuarioCOM des del examinador de objetos <<dotNetManía UsuarioCOM.dll /out=UsuarioCOM.il 44 creará un archivo con extensión IL que contendrá la definición MSIL (código intermedio). Si abrimos dicho archivo con el Bloc de Notas (figura 5), podríamos modificarlo y tras guardarlo trataríamos de ensamblarlo de nuevo. Conclusión En esta primera parte, hemos implantado un componente COM desde .NET. Como habrá podido bilidad de .NET desde COM con un ejemplo sencillo. En la web de dotNetManía (www.dotnetmania.com) puede descargar el código fuente de este artículo. dnm.lenguajes.delphi Octavio Hernández Acceso a datos en Delphi 2005 Delphi 2005 ofrece la posibilidad de desarrollar para la plataforma .NET utilizando dos vías diferentes para el acceso a datos: a través de los recursos que ofrece la VCL.NET, una librería de compatibilidad desarrollada por Borland; o a través de ADO.NET, la tecnología de acceso a datos “nativa” de la plataforma .NET. << Delphi 2005 es un entorno integrado para el desarrollo Acceso a datos desde aplicaciones <<dotNetManía Octavio Hernández es colaborador habitual de dotNetManía, Ingeniero en Informática de Sistemas y MVP de C#.Actualmente es Director Técnico de Danysoft 46 de aplicaciones tanto para Win32 como para .NET Framework. En cualquiera de los dos casos, la herramienta ofrece toda una gama de facilidades para permitir desarrollar de una manera altamente productiva, aplicaciones y componentes que accedan a cualquiera de las bases de datos más populares del mercado. En lo que respecta al desarrollo de aplicaciones .NET, Delphi 2005 ofrece la posibilidad de hacerlo utilizando dos vías diferentes para el acceso a datos: a través de los recursos que ofrece la VCL.NET, una librería de compatibilidad desarrollada por Borland para facilitar la migración de aplicaciones Win32 a .NET, así como el desarrollo de aplicaciones portables entre ambas plataformas; o a través de ADO.NET –la tecnología de acceso a datos nativa de la plataforma .NET–. Ambas vías ofrecen a su vez diferentes alternativas al desarrollador. Este artículo presenta las principales alternativas disponibles para acceder de una manera directa a diferentes bases de datos desde aplicaciones o componentes .NET creados con Delphi 2005. Esto quiere decir que no describiremos aquí los recursos que permiten el desarrollo de aplicaciones de múltiples capas, tema que merece un artículo independiente. Inicialmente se presentan brevemente las alternativas que ofrece la VCL.NET, que interesarán mayormente a los usuarios de versiones anteriores de Delphi; a continuación, nos centraremos en las alternativas “cien por cien .NET” basadas en la utilización de ADO.NET, y describiremos con mayor nivel de detalle el Proveedor de Datos de Borland (BDP, Borland Data Provider), una extensión de las clases de acceso a datos de .NET desarrollada por Borland para facilitar el acceso nativo de alto rendimiento a las bases de datos relacionales más populares del mercado. VCL.NET Con la aparición de Delphi 2005, Borland ha puesto a disposición de los desarrolladores interesados en migrar sus aplicaciones a .NET o en mantener aplicaciones que puedan ser compiladas para ambas plataformas a partir de una única base de código fuente, todos los mecanismos de acceso a datos con los que se podía desarrollar en Delphi 7 y versiones anteriores. Estos mecanismos son: • Borland Database Engine (BDE). La alternativa de acceso a datos por excelencia de Borland durante casi una década. El BDE es un motor de acceso a datos cuyo objetivo fundamental era facilitar el acceso genérico a diferentes bases de datos a las aplicaciones C++ y Delphi. Permite el acceso tanto a bases de datos “de escritorio” (dBase, Paradox, Access) como a las principales bases de datos corporativas (Oracle, Informix, DB2, SQL Server, InterBase). Actualmente el BDE ha visto pasar sus mejores días, y no se recomienda utilizarlo en nuevos desarrollos. No obstante, quedan muchísimas aplicaciones basadas en él, y sigue siendo la vía más efectiva para acceder a bases de datos con interfaz ISAM, como Paradox. • DBExpress (DBX). Esta tecnología apareció con Delphi 6, como sustituto para el obsolescente BDE. Se trata igualmente de una tecnología para el acceso genérico a bases de datos que intentaba superar las deficiencias fundamentales del BDE, en primer lugar muy “pesado” y engorroso de desplegar, y en segundo lugar demasiado atado a Windows (en aquellos tiempos comenzaba su andadura Kylix, la versión de Delphi para Linux). Para aligerar DBExpress en la medida de lo posible, Borland tomó las siguientes decisiones: << dnm.lenguajes.delphi Acceso a datos desde aplicaciones FCL.NET La plataforma .NET define un mecanismo universal para el acceso a ensamblado común y se asocian a un mismo espacio de nombres. La versión 1.1 de .NET Framework incluye de serie cuatro proveedores de datos diferentes (ver tabla 1): • El proveedor de datos .NET para SQL Server, un conjunto de clases diseñadas específicamente para interactuar de forma nativa y con un alto nivel de eficiencia con bases de Especializados datos de Microsoft SQL Server. • El proveedor de datos .NET para Oracle, un conjunto de clases que permite el acceso nativo a bases de datos Oracle. Genéricos • El proveedor de datos .NET para OLEDB, un conjunto de clases que permite acceder a cualquier almacén de datos para el que se disponga de un proveedor OLEDB. • El proveedor de datos .NET para ODBC, un conjunto de clases que permite acceder a cualquier base de datos relacional para el que se disponga de un controlador ODBC. Tabla 1 datos –ADO.NET–, que entre muchas otras buenas características incluye la de ser una tecnología abierta y extensible. El objetivo del resto de este artículo no es otro que mostrar cómo Delphi 2005 no sólo ofrece la posibilidad de explotar todas las características de ADO.NET, sino que además se apoya en dicha tecnología para ofrecer una nueva solución que aporta un valor añadido a sus usuarios –el Proveedor de Datos de Borland (BDP)–. Se denomina en su conjunto “proveedor de datos .NET”, al conjunto de clases que implementan las interfaces de .NET Framework que especifican las funcionalidades que se deben satisfacer para acceder a una fuente de datos específica e interactuar con ella en ambas direcciones (recuperando y enviando datos). Tales conjuntos de clases generalmente se almacenan en un La plataforma .NET define un mecanismo universal para el acceso a datos -ADO.NET-, que entre muchas otras buenas características incluye la de ser una tecnología abierta y extensible. Delphi 2005 ofrece soporte completo para la utilización de estos cuatro proveedores en aplicaciones y componentes .NET. Inicialmente, la Paleta de Componentes sólo muestra los componentes que conforman el proveedor de datos para SQL Server (ver figura 1). Figura 1.Contenido inicial de la página de Acceso a Datos de la Paleta de Componentes Para hacer uso mediante programación de cualquiera de los otros tres proveedores de datos desde Delphi 2005, será necesario incorporarlos a la “Paleta de Componentes”. Esto se logra mediante la opción “Component | Installed .NET <<dotNetManía • Limitar el soporte de DBExpress sólo a bases de datos basadas en la utilización del lenguaje SQL. • Ofrecer únicamente recursos para el trabajo con cursores unidireccionales. Esta característica potenció el crecimiento de una filosofía de desarrollo basada en componentes de caché y trabajo en régimen desconectado. • DBGo. Inicialmente conocida como ADOExpress, y luego renombrada por problemas legales, esta tecnología no es más que una fina capa de software impuesta sobre ADO para adecuarla a los convenios habituales a los que están acostumbrados los programadores de Delphi. Desde su aparición, ha sido utilizada con bastante frecuencia por los equipos de desarrollo de Delphi para crear aplicaciones, fundamentalmente contra bases de datos SQL Server o Access. • IBExpress (IBX). Es una librería de componentes orientada únicamente a bases de datos InterBase, el motor SGBD propio de Borland. Su principal ventaja es el alto rendimiento que proporciona, al apoyarse directamente en GDS32.DLL , la librería cliente de InterBase. En principio, el uso recomendado de estas tecnologías para el desarrollo .NET se circunscribe a las aplicaciones VCL.NET; si bien es factible acceder a estas tecnologías desde aplicaciones Windows Forms o ASP.NET, su utilización complicaría tanto la programación como el despliegue de las mismas. 47 << dnm.lenguajes.delphi Components…” del menú principal, marcando las casillas correspondientes a las clases Command, Connection y DataAdapter con prefijos ODBC, OleDB y Oracle (ver figura 2). Ejemplo de aplicación básica A continuación, ofrecemos un pequeño tutorial que describe la creación con Delphi 2005 de una aplica- Figura 4.El asistente para la edición de la cadena de conexión Figura 2. Instalación de componentes ADO.NET en la “Paleta de Componentes” de Delphi 2005 Las clases se integrarán en la página “Data Components” de la “Paleta de Componentes” (figura 3). ción que accede a la tabla HR.EMPLOYEES de la base de datos de sistema de una instancia de Oracle llamada ORCL. El proceso es muy similar al que realizaríamos de estar utilizando Visual Studio .NET. Para comenzar, creamos una nueva aplicación WinForms en Delphi 2005. Es conveniente configurar en este momento las propiedades del formulario principal y guardar todos los ficheros del proyecto. Seguidamente, arrastramos sobre el formulario un componente de la clase OracleConnection y le asignamos su cadena de conexión utilizando el asistente asociado a la propiedad (vea la figura 4). La cadena de conexión resultante tiene una apariencia similar a la siguiente: <<dotNetManía data source=ORCL;user id=MiUsr;password=MiPwd 48 Figura 3.La página de “Componentes de Datos” ampliada Donde MiUsr y MiPwd son el nombre de usuario y la contraseña a utilizar para acceder a la base de datos. Por supuesto, resulta obligada la advertencia de que no es una buena idea incluir la contraseña estáticamente en la cadena de conexión (¡ni siquiera en aplicaciones de prueba como ésta!). Ahora colocamos sobre el formulario un componente OracleDataAdapter, que utilizaremos como “puente” para traer los datos de la base de datos a un objeto DataSet . Desplegamos la propiedad SelectCommand, donde se deben establecer las características de la sentencia SQL que utilizaremos para recuperar esos datos. Asignamos una referencia a nuestro objeto de conexión a la propiedad interna Connection de SelectCommand, y la sentencia SELECT * FROM HR.EMPLOYEES a la propiedad CommandText. A continuación, pulsamos con el botón derecho del ratón sobre el adaptador de datos y lanzamos el asistente “Generate DataSet”; esto producirá un objeto DataSet11 , que contendrá un objeto llamado Table, de tipo DataTable, donde se almacenarán los datos de los empleados provenientes de la base de datos. Finalmente, para presentar los datos en el formulario, colocamos sobre él un componente DataGrid (página Data Controls), asignamos a su propiedad DataSource una referencia a DataSet11, y a la propiedad DataMember una referencia a Table. Ahora sólo falta una línea de código en el evento Load del formulario para que al arrancar la aplicación se traigan los datos de la base de datos al formulario y se muestren en la rejilla: << dnm.lenguajes.delphi procedure fmOracle1.fmOracle1_Load( sender: Object; e: EventArgs); begin OracleDataAdapter1.Fill(DataSet11); end; La aplicación en ejecución tendrá una apariencia similar a la figura 5. liares) que ofrece una interfaz de programación uniforme para las principales bases de datos SQL del mercado (en Delphi 2005: Oracle, SQL Server, DB2, Sybase, InterBase y Access). En el fondo, BDP no es más que un “paraguas” Figura 5. La aplicación creada, en ejecución El Proveedor de Datos de Borland (BDP) Como hemos comentado antes, Microsoft ha provisto al acceso a datos en .NET de una arquitectura abierta, que hace posible que no sólo dispongamos de genérico que oculta tras de sí a conjuntos de clases especializadas en el acceso nativo de alto rendimiento a una base de datos específica. El BDP enruta todas las peticiones que recibe al proveedor interno correspondiente, como se muestra en la figura 6. cación a otro SGBD podría reducirse a algo tan simple como cambiar los valores de la propiedad ConnectionString de los objetos de conexión (que podrían, para una flexibilidad aún mayor, almacenarse en un fichero de configuración, fuera del código). Otra ventaja relacionada con la anterior es que el uso del Proveedor de Datos de Borland simplifica en gran medida el desarrollo de aplicaciones que deban estar preparadas para poder trabajar contra diferentes bases de datos, algo que utilizando exclusivamente las librerías de .NET Framework sólo puede resolverse programando a nivel de interfaces. Por último, hay que destacar que los proveedores específicos para cada una de las bases de datos soportadas son proveedores nativos que “atacan” directamente al software cliente de la base de datos, lo que asegura un alto rendimiento, además de simplificar el despliegue, ya que no se requiere la instalación de ningún middleware adicional. Soporte para BDP en tiempo de diseño Las facilidades que ofrece Delphi 2005 para el desarrollo visual de aplicaciones de acceso a datos a través del BDP son superiores a las que obtendremos con cualquier otra tecnología de acceso a datos. Las conexiones a bases de datos se configuran dentro del propio entorno utilizando la pestaña “Data un conjunto cerrado de proveedores, sino que podamos además aprovechar los nuevos proveedores que desarrollen los diferentes fabricantes de software para dar un soporte optimizado para una base de datos específica, o (como en el caso de Borland) un tipo de soporte diferente del que ofrece por defecto .NET. El Proveedor de Datos de Borland (BDP, Borland Data Provider) no es más que un proveedor de datos .NET (formado por las clases BdpConnection , BdpCommand, BdpDataAdapter y otras auxi- La ventaja fundamental de este enfoque radica en que los desarrollos quedan mucho más protegidos ante un posible cambio de base de datos. Si se utilizan directamente los componentes que ofrece .NET 1.1, cualquier cambio de base de datos exigiría numerosas modificaciones en el código fuente (por ejemplo, para cambiar todos los usos de SqlConnection por OracleConnection, etc.). Si se utiliza el proveedor BDP (y se evita en lo posible la utilización de extensiones propietarias de SQL en el código), portar una apli- Figura 7.El “Explorador de Datos “ de Delphi 2005 <<dotNetManía Figura 6. Arquitectura del Proveedor de Datos de Borland 49 << dnm.lenguajes.delphi ría es Live Data, o sea, datos vivos), que hace posible visualizar los datos directamente en tiempo de diseño, detalle al que están acostumbrados desde siempre los programadores de Delphi (figura 9). Invitamos al lector a que desarrolle la aplicación básica equivalente a la que hemos creado en el punto “Ejemplo de aplicación básica”, utilizando el proveedor BDP en lugar del proveedor de Oracle suministrado por .NET Framework. El Proveedor de Datos de Borland no es más que un proveedor de datos .NET que ofrece una interfaz de programación uniforme para las principales bases de datos SQL del mercado Explorer” del “Gestor de Proyectos” (figura 7). El explorador no sólo nos permite configurar las propiedades de las conexiones a bases de datos, sino también realizar de forma centralizada muchas tareas prácticas como crear, copiar o visualizar tablas, entre otras. En el caso de Oracle, el diálogo de configuración de una conexión a una base de datos a través de BDP podría tener la apariencia de la figura 8. Figura 9. “Datos vivos” en tiempo de diseño Figura 8.El “Editor de Conexiones” de Delphi 2005 La cadena de conexión resultante sería similar a la siguiente: hace el Proveedor de Datos de Borland cuando se le indica, por ejemplo, que ejecute una sentencia SQL contra una conexión específica. Durante el desarrollo, para generar objetos BdpConnection y BdpDataAdapter correctamente configurados basta con arrastrar y soltar una tabla cualquiera desde el “Explorador de Datos” a un formulario del proyecto. Sólo resta entonces generar mediante el asistente del adaptador el objeto DataSet y configurar los controles visuales necesarios. Como ventaja <<dotNetManía Assembly=Borland.Data.Oracle,Version=2.0.0.0,Culture=neutral, PublicKeyToken=91d62ebb5b0d1b1b;vendorclient=oci.dll;database=ORCL;provider=Oracle; username=MiUsr;password=MiPwd 50 La estructura de esta cadena de conexión deja entrever qué es lo que adicional, los adaptadores de datos BDP ofrecen una propiedad Active (su catego- Conclusiones En este artículo hemos presentado las opciones que pone Delphi 2005 en manos del desarrollador que se enfrenta al desarrollo de una aplicación o componente .NET que acceda a bases de datos. Inicialmente hemos mencionado las opciones de compatibilidad con Win32, para luego centrarnos en las alternativas basadas en ADO.NET, la tecnología de acceso a datos incorporada a .NET Framework. Hemos mostrado cómo con Delphi 2005 es posible utilizar cualquiera de los proveedores de datos .NET predefinidos por la FCL.NET, o aprovechar las ventajas que ofrece el BDP, un proveedor de datos creado por Borland para el acceso genérico de alto rendimiento a las bases de datos más populares del mercado. CD VOLUMEN 1 dotNetManía LLÉVATELO TODO dotNetManía CD Volumen 1 es un CD con todos los artículos publicados en la revista dotNetManía entre febrero de 2004 y enero de 2005 (números 1 al 11). Puede obtener de forma gratuita este dotNetManía CD Volumen 1 con una nueva suscripción o con su renovación a la revista dotNetManía. Aunque aún no tenga que renovar, puede hacerlo de forma anticipada y así recibirlo gratuitamente y sin esperas. Si no desea suscribirse o renovar su suscripción, puede adquirir el dotNetManía CD Volumen 1 por 24,50€ (IVA incluido) (sólo para envíos en España). Más información y pedidos al teléfono (34) 91 666 74 77 o en www.dotnetmania.com. dnm.todotnet.qa Dino Esposito ¿Está seguro con ASP.NET? ToDotNet-QA es la nueva columna dirigida por Dino Esposito con la que pretendemos solucionar las dudas que los lectores nos envíen y servir a todos con contenidos amenos e interesantes. Si desea enviar consultas a Dino para esta columna, puede hacerlo al email [email protected]. << Muchos desarrolladores han aprendido por cuenta propia Dino Esposito es redactor de dotNetManía. Formador, consultor y escritor afincado en Roma. Miembro del equipo de Wintellect, Dino está especializado en ASP.NET y ADO.NET. Puede enviarle sus consultas a [email protected] que la seguridad de sus aplicaciones no es algo que se pueda añadir simplemente al final, o ser olvidado en las fases de diseño de las aplicaciones. La seguridad es algo que debe ser inherente a la funcionalidad de la aplicación y debería planearse como una de las primeras características al más alto nivel. Por naturaleza, las aplicaciones Web están sujetas a varios tipos de ataques, cuyo daño e impacto varían bastante dependiendo de la naturaleza misma de la aplicación. La aplicación segura es aquella que resiste los ataques, no la que se queda en el mero diseño de seguridad, ya que se trata de un puzzle complejo que cambia entre aplicaciones. Lo importante es recordar que –muy a menudo– la seguridad se manifiesta mediante una mezcla de medidas a nivel de aplicación junto a otras que afectan al sistema operativo. No hay aplicaciones Web seguras en una red insegura, de la misma forma que la red más fortificada no puede proteger una aplicación pobremente diseñada, que ofrece el campo suficiente para los ataques. En esta primera entrega de esta nueva sección responderé unas cuantas cuestiones generales sobre seguridad, y espero que muestre la forma de construir e instalar aplicaciones sólidas y resistentes. Habría que estar sordo y ciego para ignorar todos los comentarios acerca de los problemas asociados a la seguridad. No digo que esto sea un bulo, porque lo demuestran las estadísticas e informes, pero veo que la mayoría de la literatura al respecto se limita a mostrar causas y efectos pero no se para mucho en las contramedidas. Así pues, ¿Qué se entiende por una aplicación segura? Cada vez más analistas acuerdan que la parte más insegura son las aplicaciones y no los sistemas. Los años de experiencia han hecho que se cree hardware que no contiene en sí ninguna medida de seguridad, para luego implantarla mediante configuraciones del software. Durante años hemos construido aplicaciones bajo la falsa apreciación de que un sistema seguro era más que suficiente. Esto se ha demostrado que es falso ya que en la 1 actualidad la mayoría de los ataques de seguridad se camuflan bajo la apariencia de peticiones correctas al servidor, y acceden a las aplicaciones a través de la puerta principal: el puerto 80. ¿Cómo puedes diseñar una aplicación segura? Hay varias soluciones implicadas, tal y como comentan David Leblanc y Michael Howard, en su clásico “Writing Secure Applications”, de MS Press (2003)1. Sin embargo, un aspecto en particular es fácil de implementar y de recordar, al menos en lo que concierne a ASP.NET 1.1. La guía de seguridad se puede resumir en lo siguiente: nunca te fíes de los datos de entrada del usuario. Solamente mediante la aplicación de este principio, habrás conseguido reducir la superficie de exposición a ataques en un considerable porcentaje. void OnSubmit (Object sender, EventArgs e) { Output.Text = "Hello, " + Input.Text; } Tres de los ataques más comunes –inyección SQL, código de script fuera de ámbito o el llamado ataque “one-click”– son debidos a una capa de validación pobre e insegura. Las aplicaciones Web funcionan aceptando y procesando datos de usuarios; si la entrada está falseada, la aplicación está en riesgo. Que levante la mano el usuario que nunca haya añadido a una cadena, el contenido de una caja de texto para construir una consulta. Esta operación no es peligrosa de por sí, pero puede tener efectos devastadores combinada con otras debilidades. Fijémonos en el siguiente código: Supongamos que Input es una caja de texto y Output una etiqueta (label). En este código, cualquier cosa que escriba el usuario, se reflejará en la página final. Un usuario malintencionado puede insertar ahí un bloque de Javascript que permita grabar y recuperar cookies. De nuevo, una cookie robada puede ser o no un problema. Sin embargo, ofrece a los atacantes un frente claro sobre el que actuar en el sistema. ¿Y qué pasa si el contenido simbolizado por Input es una consulta o una cookie envenenada? (una cookie enve- Los distribuidores para España de libros de MS Press en inglés para su distribución vía WEB son Visual Programming (visualpr.net) nenada es aquella cuyo contenido ha sido artificialmente creado o alterado). Más en general, el problema con el código anterior es que no existe validación alguna del mismo. Antes de utilizar cualesquiera datos introducidos por el usuario, el texto debería de pasar por un examen preliminar, que nos garantice que la entrada es segura. Eso significa que los datos deben ser del tipo esperado, acorde con el patrón y longitud esperadas, y encontrarse dentro del rango de valores requerido. Una aplicación que no cumple estos requisitos es potencialmente insegura, mientras que una aplicación que sí lo hace consigue reducir la superficie de ataque expuesta a la mínima dimensión. ¿Puede decirnos algunas reglas prácticas para la construcción de aplicaciones ASP.NET seguras? No quiero leer más avisos genéricos acerca de “buffer overruns” o validaciones de entrada. Lo que me gustaría es una lista detallada de cosas a tener en cuenta. Me gusta la pregunta por que plantea el mismo problema desde una distinta perspectiva. Los “buffer overrun”, o sea, permitir más espacio para las entradas del que es necesario, y por lo tanto, capacitar a los atacantes a que incluyan instrucciones de ataque adicionales, y la validación de entradas, son la clave de la seguridad Web. Estoy de acuerdo sin embargo, en que estas directivas son quizá un tanto generalistas, así que pongámoslo claro: las aplicaciones ASP.NET seguras deberían cumplir al menos con lo siguiente: • Mantener ValidateRequest activo. • Asignar un valor no vacío a ViewStateUserKey. • Utilizar procedimientos almacenados para el acceso a datos. • Otorgar permisos de escritura en las bases de datos con extremo cuidado. • Utilizar datos fuertemente tipados, expresiones regulares y validaciones de rango. Analicémoslas con más detalle. ValidateRequest es un atributo de la directiva @Page introducido por ASP.NET 1.1. Aplica una expresión regular a ciertos formularios de entrada de datos (campos de entrada y cadenas de consulta SQL) para detectar datos potencialmente peligrosos. En particular, este atributo filtra cualquier código HTML que pueda ser el preludio de código Javascript malicioso. Este atributo está activado por defecto y no hay razón para deshabilitarlo a no ser que resulte imprescindible que tu aplicación tenga que captar datos en formato HTML. No se trata de un salvavidas absoluto contra los ataques, sino una medida más de prevención, que debe ser tenida en cuenta junto con las propias que adopte el desarrollador. ViewStateUserKey es también una propiedad de la clase Page que fue introducida en la versión 1.1 de ASP.NET. Debería inicializarse a una cadena no vacía diferente para cada usuario. Por ejemplo, podría ser el nombre de usuario, si la aplicación tiene una pantalla de credenciales de inicio, o incluso mejor, el valor de la variable SessionID. ¿Qué beneficios se obtienen con esto? Que hace que sea imposible para los potenciales atacantes preparar un formulario específico para “crackear” una página concreta, el llamado “ataque one-click”, una forma relativamente nueva de “script fuera de ámbito”. Si se activa y asigna a un valor dependiente del servidor y con un dato específico para cada usuario, resulta imposible –prácticamente– violarlo mediante esa técnica. En cuanto a los procedimientos almacenados, existen dos razones: rendimiento y seguridad. Es bien conocido que los procedimientos almacenados están “precompilado” en el servidor, lo que redunda en un acceso mucho más rápido. Además, suelen utilizar un buen número de sentencias que obligan al programador a personalizar el procedimiento mediante el uso de variables fuertemente tipadas. No hay necesidad de concatenar cadenas para construir las peticiones de datos, el tipo y la longitud son obligatorios y el riesgo de “inyección de código” se minimiza. Al mismo tiempo, el acceso a datos requiere una cuenta con permisos de lectura y escritura. Para reducir la superficie de ataques, deberían utilizarse las cuentas con el menor número de permisos para realizar la operación deseada, y –si es posible– nunca elevar los permisos por encima del nivel de seguridad (y menos a nivel de administrador) a ninguno de los usuarios. Finalmente, exigir la validación estricta de los datos de entrada. Cualquier canal de entrada, en cualquier aplicación está diseñado para recibir datos de un cierto tipo y con un cierto tamaño e incluso con alguna clase de formato, o dentro de un rango determinado. Por variadas razones, sin embargo, no siempre se verifican los datos de entrada. Esta discrepancia es la semilla potencial para los ataques. Después de todo, de eso va la validación. Muchas fuentes recomiendan utilizar seguridad integrada cuando se accede a SQL Server. ¿Es ésa la mejor política en las aplicaciones ASP.NET? Podría ser. La ventaja clave de la seguridad integrada cuando se conecta a una instancia de SQL Server, es que no necesita de credenciales explícitas. No se toman datos personales de la cadena de conexión, ni se tienen que introducir manualmente o recordar. Utilizamos en ese caso un modelo único de seguridad que hereda las características de bloqueo y expiración de contraseñas directamente de Windows. SQL Server necesita configurarse para ejecución en Windows o en modo mixto. Ambos programas gestionan todo e intercambian la información necesaria. ¿Qué significa eso en el contexto de una aplicación ASP.NET? Trata de escribir una página simple que se conecte a SQL Server usando seguridad integrada. En una configuración estándar, obtienes un error de autenticación. La seguridad integrada significa que la cuenta de proceso de ASP.NET (sea ASPNET o NETWORK SERVICE) es la que se usa en la conexión al servidor. Si esta cuenta no aparece en la lista de cuentas del servidor, se emite una excepción de autorización. Si se añade un nuevo login, todo empieza a funcionar. ¿Es eso todo? La seguridad integrada es estupenda, siempre que sea aceptable que una única cuenta de usuario realice todas las tareas en el servidor. ¿Qué sucede si se ha diseñado la aplicación utilizando roles? En ese caso, existen muchas probabilidades de que algunos usuarios ejecuten tareas con más nivel de permisos del que sea necesario. Esto no es malo en sí, pero puede dejar la puerta abierta a ataques por “inyección SQL”. Si se utilizan roles, lo mejor es autenticar al usuario en la misma puerta de la aplicación y aprovechar la capa intermedia para comprobarlas. Se asigna cada rol a una cuenta específica de acceso al servidor y es esa cuenta la que realiza las tareas competentes del rol que le corresponde. No existe una superficie extra para los ataques, y se mantiene la eficiencia del pool de conexiones. <<dotNetManía << dnm.todotnet.qa 53 dnm.laboratorio.net Pedro Pozo Raptier, rápido por naturaleza Raptier es una herramienta de desarrollo rápido, que sirve para generar una aplicación web o de escritorio para gestionar la información de una base de datos en un abrir y cerrar de ojos. << Raptier nos permite acortar de forma espectacular el <<dotNetManía Pedro Pozo es redactor de dotNetManía. Es es consultor e-Bussines. Ingeniero Técnico Informático de Sistemas y Webmaster del portal para desarrolladores .NET Framework Clikear.com 54 tiempo de desarrollo, obteniendo un código muy bien estructurado y documentado. En Raptier todo es muy sencillo, se trata de una herramienta poco vistosa que ofrece las opciones justas y evita incluir cosas superfluas que casi nunca se utilizan. A pesar de ser poco espectacular en su aspecto, sí que nos sorprenderá por su efectividad; en apenas unos minutos podemos tener una aplicación completamente funcional, bien estructurada y fiable para gestionar la información de nuestra base de datos. El código que se genera es independiente del tipo de base de datos que utilicemos de forma que podemos cambiar, por ejemplo, de Microsoft SQL Server a ORACLE sin ningún problema. Raptier admite cualquier base de datos OLE DB, por lo cual podemos utilizar casi cualquier base de datos existente. Al entrar en Raptier nos aparece una aplicación que puede parecer incluso un poco austera, y al comenzar un nuevo proyecto nos aparecerá una ventana (igual que cuando realizamos una conexión UDL) para definir sobre qué base de datos vamos a trabajar. A continuación, tan solo deberemos marcar las opciones que deseamos para nuestro proyecto, que no son muchas pero sí muy interesantes. Como podemos ver en la figura, Raptier nos permite elegir entre Visual Basic .NET y C# como lenguajes en los que creará el código fuente, también nos permite elegir entre si deseamos que cree un proyecto para Visual Studio .NET 2002 o 2003 o Borland C#. Otra opción curiosa es que nos da a elegir entre crear procedimientos almacenados o generar las consultas en el código y, sin duda la mejor de todas, es que nos permite crear la aplicación para Web o como aplicación de escritorio, o de ambas formas. Después tan solo tendremos que seleccionar generar código y ya tendremos nuestra aplicación para gestionar la información de una base de datos. Podremos añadir, modificar y borrar datos de todas nuestras tablas de la base de datos a través de sencillos formularios, y si deseamos darle más funcionalidad siempre podemos acceder al código fuente y modificarlo a nuestro gusto. El código que genera Raptier separa perfectamente la capa de acceso a datos de la interfaz de la aplicación, es un código bien estructurado y fácilmente modificable. Además genera una documentación muy completa sobre la base de datos en HTML. Aunque el diseño gráfico de las aplicaciones que genera RapTier no es muy espectacular, nos ofrece la posibilidad de crear una plantilla que nos permite personalizar más el aspecto de nuestras aplicaciones. Así podemos crear distintos diseños web y adaptarlos al look&feel de nuestra web. La versión Enterprise nos ofrece la posibilidad de generar la documentación de la base de datos automáticamente. Esta documentación incluye información sobre las tablas, vistas, procedimientos almacenados, triggers y relaciones. De esta forma Raptier también nos ahorra tiempo, no sólo en el desarrollo sino también a la hora de generar documentación y poder mantenerla actualizada. También cabe destacar de Raptier que genera un conjunto de servicios Web con toda la funcionalidad del mantenimiento de las tablas de la base de datos elegida, pudiendo así gestionar los datos de las tablas de nuestra base de datos desde cual- << dnm.laboratorio.net bajar y obtener resultados visibles. Sin necesidad de ningún conocimiento de programación podemos crear una aplicación que sirva para añadir, modificar o borrar datos de las tablas de una base de datos. Hay muchas herramientas de desarrollo más completas y versátiles que Raptier, pero hay pocas con las que se pueda empezar a obtener resultados tan rápido y con un tiempo de aprendizaje tan corto. Entre los inconvenientes se debe destacar la corta funcionalidad de esta aplicación, es una pena que sólo sirva para crear mantenimientos de tablas de base de datos y no nos ofrezca más posibilidades, pero si lo hiciera quizá perdería su sencillez. quier entorno que llame a estos servicios Web. Requisitos del sistema Los requisitos básicos para la instalación Raptier son bastante asequibles, lo mínimo recomendable puede verse en la siguiente tabla de requisitos del sistema: Requisitos del Sistema Procesador Intel Pentium 100 Memoria RAM 128 MB Disco duro 5 Mb de espacio libre Sistema Operativo Windows XP o Windows 2000 Software .NET Framework Diferencias entre las versiones Raptier se ofrece en 3 versiones: Lite, Professional y Enterprise. La versión Lite podemos descargarla gratuitamente de Internet y tiene como limitación el poder trabajar con un máximo de 15 tablas. La versión Professional permite trabajar con un número ilimitado de tablas y también ofrece soporte técnico. Por último, la versión Enterprise que suma a las características de la versión professional el permitir generar la documentación de la base de datos. Conclusiones Quizá se echen en falta algunas opciones más para poder personalizar más la aplicación o para poder añadirle alguna funcionalidad más, pero siempre tenemos la opción de poder modificar el código que obtenemos con Raptier a través de la herramienta de desarrollo que deseemos. Pero si desea poder realizar mantenimientos de base de datos de una forma rápida y sencilla, Raptier es una herramienta ideal. Ficha técnica Ventajas e inconvenientes Sin duda la principal virtud de Raptier es la rapidez y sencillez con la que podemos conseguir empezar a tra- A pesar de ser poco espectacular en su aspecto, sí que nos sorprenderá por su efectividad; en apenas unos minutos podemos tener una aplicación completamente funcional, bien estructurada y fiable para gestionar la información de nuestra base de datos Nombre RapTier Versión 1.4.1 Fabricante SharpPower Web www.sharppower.com Categoría Herramientas de desarrollo Edición Precio Lite Gratis Professional 1 licencia 299$ > 4 licencias 169$ Enterprise 1 licencia 499$ >4 licencias 279$ Valoración <<dotNetManía Aspecto de la pantalla de configuración de Raptier. 55 Suscripción a dotNetManía ❑ Deseo suscribirme a dotNetManía por un año (11 ejemplares) y beneficiarme de la oferta del 10% de descuento por un importe total de 60 € para España; o por 120€ para el resto del mundo (envío por avión) (IVA incluido). ❑ Deseo suscribirme a dotNetManía por un año (11 ejemplares) por un importe de 45 € por ser estudiante (IVA incluido). Aporto fotocopia del carné de estudiante o sello del centro académico (IMPRESCINDIBLE). OFERTA VÁLIDA SÓLO PARA ESTUDIANTES RESIDENTES EN ESPAÑA. IMPORTES VÁLIDOS HASTA NUEVA OFERTA DATOS DE FACTURACIÓN CIF/NIF . . . . . . . . . . . . . . . . . . . . .Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . DATOS DE ENVÍO (sólo si son distintos de los datos de facturación) CIF/NIF . . . . . . . . . . . . . . . . . . . . .Empresa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nombre y apellidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dirección . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Código Postal . . . . . . . . . . . . . . . . . . . Provincia . . . . . . . . . . . . . . . . . . . . . . . . . Teléfono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fax . . . . . . . . . . . . . . . . . . . . . . . . . . . email . . . . . . . . . . . . . . . . . . . . . . . . . . . . FORMA DE PAGO ❑ Talón nominativo a nombre NETALIA, S.L. ❑ Transferencia bancaria a nombre de NETALIA, S.L. a: La Caixa - Número de cuenta 2100 4315 48 2200014696 (Indique su nombre en la transferencia) ❑ Domiciliación Bancaria (con renovación automática, previo aviso) Indique su número de cuenta: ❑ Tarjeta de crédito ❑ VISA ❑ MASTERCARD Número de su tarjeta: Fecha de caducidad: / (imprescindible) Firma y/o sello (imprescindible) a ❑ Nº5 ❑ Nº6 ❑ Nº7 de ❑ Nº8 de 20 0 ❑ Nº9 Si desea algún otro número indíquelo Puede enviar los datos al email [email protected], al FAX (34) 91 499 13 64 o al teléfono (34) 91 666 74 77. También puede enviarlo por correo postal a la siguiente dirección: Netalia, S.L C/ Robledal, 135 28529 - Rivas Vaciamadrid Madrid (España) Usted autoriza a la mecanización de estos datos. El responsable y destinatario de éstos es Netalia, S.L. Usted tiene derecho a acceder a sus datos, modificarlos y cancelarlos cuando lo desee. Sus datos no serán cedidos en ninguna de las formas posibles a terceras partes y no se utilizarán más que para el buen funcionamiento de su suscripción a la revista dotNetManía y para informarle de las actividades comerciales que realice la editorial Netalia, S.L. Si no desea recibir información comercial de dotNetManía marque la casilla siguiente ❑ ❑ Nº10 ❑ Nº11 << dnm.biblioteca.net dnm.biblioteca.net OOP:Building Reusable Components with Microsoft® Visual Basic® .NET Ken Spencer,Tom Eberhard, y John Alexander Editorial: Microsoft Press ISBN: 0735613796 Páginas: 495 Publicado: Octubre, 2002 En el camino se implementan los elementos de la solución mediante capas que se corresponden con algunas de las técnicas más importantes de construcción de aplicaciones: mecanismos de seguridad, capas de datos, implementación de clientes génericos de servicios Web, capas de negocio, interfaces de usuario (Web y Windows) e incluso el uso de Remoting para comunicaciones. C# for Java Developers Allen Jones y Adam Freeman Editorial: Microsoft Press ISBN: 0735617791 Páginas: 550 Publicado: Agosto, 2002 Los autores, dos experimentados programadores en Java (y autores de varias obras sobre ese lenguaje), analizan primero la plataforma y sus diferencias estructurales respecto a J2EE, para continuar con un análisis exhaustivo del lenguaje C#, siempre manteniendo en el punto de mira el perfil teórico del lector del libro (o sea, otro programador de Java), haciendo especial hincapié en las diferencias entre ambos lenguajes, y explicando, en muchos casos, las novedades que aporta C#, de las que no existen equivalentes naturales en Java. La obra concluye con unos capítulos finales sobre servicios Web, integración de plataforma, creación de ensamblados compartidos, recolección de basura, interoperabilidad entre lenguajes, configuración de aplicaciones, y una –utilísima– guía de las APIs .NET en su correspondencia con los “packages” java.*. De lectura recomendable para el desarrollador de java que desee migrar aplicaciones. <<dotNetManía << Esta primera propuesta bibliográfica es algo que por su sencillez aparente, muchos echábamos de menos. Un habitual del Tech-Ed, Ken Spencer, gran comunicador y divulgador famoso por su sencillez y claridad expositiva, codirige, junto a otros colaboradores también conocidos, esta obra cuya mayor virtud es, quizás, lo modesto de sus objetivos iniciales. El libro, recorre la construcción de una aplicación, siguiendo algunas de las más populares “buenas prácticas para .NET”, en un viaje que va desde la arquitectura de la solución propuesta, (que será desarrollada en su integridad a lo largo del libro), hasta el montaje final o implementación. 57 noticias.noticias << dnm.desvan Marino Posadas Nuevas herramientas de seguridad de Microsoft Microsoft sigue empeñada en la mejora de sus herramientas de seguridad, pero esta vez, anuncia herramientas instalables, y no service packs. Por un lado, y basada en la tecnología adquirida a la compañía Giant, Windows Antispyware, se encuentra disponible desde el pasado mes de enero, y aparte de su funcionalidad esencial, aporta complementos de seguridad que aparecieron asociados el Windows XP SP2, como control de las ventanas pop-up, los cambios no deseados en las configuraciones de Internet y el uso no autorizado de información personal. Microsoft cuenta con la comunidad SpyNet, una red de usuarios voluntarios que ayuda a descubrir rápidamente nuevas amenazas para asegurar que todos los usuarios estén bien protegidos. Documentos en la Red Asimismo, la nueva herramienta para eliminar código malicioso consolida las herramientas existentes en una única solución, que será actualizada el segundo martes de cada mes como parte de la iniciativa de actualizaciones mensuales de Microsoft. La herramienta se encuentra en http://www.microsoft.com/athome/security/spyware/software, y podría completarse con otras herramientas para la eliminación de virus. Microsoft vuelve a organizar PDC (Professional Developers Conference) Esta vez, en Septiembre 2005 (del 11 al 16, en Los Angeles, CA). Las fechas son tremendamente sospechosas, así que (dados los anuncios de calendario), parece que coincidiría con la salida de Visual Studio 2005 y/o SQL Server 2005, si es que uno de ellos no ha visto la luz antes. Utilidades recomendadas (Especial utilidades de monitorización de sitios web) Introduction to Data Communications es un obra muy completa, (más de 500 páginas) de Eugene Blanchard, que puede encontrarse gratuitamente en www.techbooksforfree.com/intro_to_data_com/ toc.html. Las 46 mejores utilidades gratuitas de todos los tiempos (moder- En la misma ubicación, pueden encontrarse otras “joyas”, sobre tecnología informática y sobre .NET en particular, en especial las ubicadas en la página www.techbooksforfree.com/microsoft.shtml, incluidos algunos interesantes avances, como por ejemplo Developer Guide to Migration and Interoperability in Longhorn, o las excelentes Real World XML Web Services, del conocido divulgador Yasser Shohoud (ponente habitual en Tech-Ed's y PDC's), o The .NET Developer's Guide to Windows Security, de Keith Brown, otro gran conocedor de las APIs de Windows y autor de obras de referencia desde los tiempos de MS-DOS. ConfigInspector: Utilidad gratuita para análisis de la información <<dotNetManía Guia para la grabación y codificación musical es el nombre aproximado de “A guide to ripping and encoding music”, documento disponible en http://arstechnica.com/guides/tweaks/encoding.ars comenzando por las definiciones de los conceptos más comunes. 58 Cómo funciona un buscador Por fin, como complemento a al especial de utilidades recomendadas para la monitorización de sitios Web, recomendamos este documento en: www.alt64.com/extras/Como_Funciona_un_Buscador.zip nos), es la oferta que podemos encontrar en “The 46 Bestever Freeware Utilities”, disponible en http://www.techsupportalert.com/best_46_free_utilities.htm. del sistema. Dispone de las mismas utilidades que el “Administrador de Tareas de Windows” más toda una serie de características añadidas. Está disponible en http://softvoile. com/configinspector.php. Herramientas gratuitas para el seguimiento y mejora del posicionamiento de sitios Web en los buscadores: Las hay de varios tipos, desde las que permiten altas simultáneas: Marketleap en http://www.marketleap.com/siteindex o seguimiento de bloqueos (Poodle predictor: http://www.gritechnologies.com/tools/spider.go?q=www.noticias.com y Summit Spider Simulator: http://tools.summitmedia.co.uk/spider), hasta conocer la densidad de las palabras clave en el texto (sitio: http://www.ranks.nl/tools/spider.html, o herramienta Density Analyzer, en http://www.searchengineworld.com/cgi-bin/kwda.cgi), pasando por comparaciones de la posición de una Web respecto a ciertas palabras (Thumbshots: http://ranking.thumbshots.com) o cómo conocer el Page Rank de una página Web: http://pagerank.walidator.com. Photo Story 3 for Windows: Para concluir esta larga lista de recomendaciones, no olvidemos esta nueva herramienta gratuita de Microsoft, que puede descargarse de www.microsoft.com/windowsxp/using/digitalphotography/photostory.
Documentos relacionados
El modelo de objetos de Visual Studio .NET El modelo de objetos
Administración Pilar Pérez ([email protected]) Asesor Técnico Marino Posadas ([email protected]) Redactores Antonio Quirós, Dino Esposito, Guillermo 'guille' Som, Jorge Serra...
Más detallesPON: P2P Over .NET PON: P2P Over .NET
Administración Pilar Pérez ([email protected]) Asesor Técnico/Coordinación Marino Posadas ([email protected]) Redactores Antonio Quirós, Dino Esposito, Guillermo 'guille' Som...
Más detallesVisual Basic • C# • ASP.NET • ADO.NET • .NET Framework
problemas de rendimiento en SQL Server. El artículo de portada este mes es nuevamente para la sección dnm.futuro, donde Octavio Hernández presenta las novedades de VB 9.0 para implementar LINQ. Est...
Más detalles