Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
miércoles, 9 de enero de 2008
Visual Basic .NET 9.0, disponible con Visual Studio 2008, incluye, al igual que C# 3.0, multitud de novedades y mejoras que sin duda nos harán la vida más fácil.

Una de ellas es la posibilidad de declarar variables sin necesidad de indicar de forma explícita su tipo, cediendo al compilador la tarea de determinar cuál es en función del tipo de dato obtenido al evaluar su expresión de inicialización. El tipado implícito o inferencia de tipos también existe en C# y ya escribí sobre ello hace unos días, pero me parecía interesante también publicar la visión para el programador Visual Basic y las particularidades que presenta.

Gracias a esta nueva característica, en lugar de escribir:
  Dim x As XmlDateTimeSerializationMode = XmlDateTimeSerializationMode.Local
Dim i As Integer = 1
Dim d As Double = 1.8
podremos utilizar:
  Dim x = XmlDateTimeSerializationMode.Local
Dim i = 1
Dim d = 1.8

El resultado en ambos casos será idéntico, ganando en comodidad y eficiencia a la hora de la codificación y sin sacrificar los beneficios propios del tipado fuerte.

Hay un detalle importante que los veteranos habrán observado: Visual Basic ya permitía (y de hecho permite) la declaración de variables sin especificar el tipo, de la forma Dim i = 1 (con Option Strict Off), por lo que podría parecer que el tipado implícito no sería necesario. Sin embargo, en este caso los compiladores asumían que la variable era de tipo Object, por lo que nos veíamos obligados a realizar castings o conversiones en tiempo de ejecución, penalizando el rendimiento y aumentando el riesgo de aparición de errores imposibles de detectar en compilación. Tampoco tiene nada que ver con tipados dinámicos (como los presentes en javascript), o con el famoso tipo Variant que estaba presente en Visual Basic 6; el tipo asignado a la variable es fijo e inamovible, como si lo hubiésemos declarado explícitamente.

En Visual Basic 9, siempre que no se desactive esta característica incluyendo la directiva Option Infer Off en el código, el tipo de la variable será fijado justo en el momento de su declaración, deduciéndolo a partir del tipo devuelto por la expresión de inicialización. Por este motivo, la declaración y la inicialización deberán hacerse en el mismo momento:

Dim i = 1 ' La variable "i" es Integer desde este momento

Dim j ' La variable "j" es Object, como siempre,
j = 1 ' ... si Option Scrict está en Off.
' En caso contrario aparecerá un error de compilación.
 

El tipado implícito puede ser asimismo utilizado en las variables de control de bucles For o For Each, haciendo su escritura mucho más cómoda:
 
Dim suma = 0
For i = 1 To 10 ' i se está declarando ahí mismo como Integer,
suma += i ' no existía con anterioridad
Next

Dim str = "abcdefg"
For Each ch In str ' ch se declara automáticamente como char,
Console.Write(ch) ' que es el tipo de los elementos de "str"
Next
 
Y también puede resultar bastante útil a la hora de obtener objetos de tipos anónimos, es decir, aquellos cuya clase se define en el mismo momento de su instanciación, como en el siguiente ejemplo:

Dim point = New With {.X = 1, .Y = 5}
point.X += 1
point.Y += 1
 

Por último, es interesante comentar que, a diferencia de C#, Visual Basic permite declarar en la misma línea distintas variables de tipo implícito, por lo que es posible escribir Dim k=1, j=4.8, str="Hola" sin temor a un error en compilación, asignándose a cada una de ellas el tipo apropiado en función de su inicialización (en el ejemplo, Integer, Double y String respectivamente).

Coinciden, sin embargo, en que en ambos lenguajes esta forma de declaración de variables se aplica exclusivamente a las locales, es decir, aquellas cuyo ámbito es un método, función o bloque de código. No pueden ser propiedades ni variables de instancia; en el siguiente ejemplo, x será declarada de forma implícita como Object, mientras que el tipo de la variable y será inferido como Integer:
  Public Class Class1
Dim x = 2 ' Es una variable de instancia
Public Sub New()
Dim y = 2 ' Es una variable local
End Sub
End Class
 
En resumen, se trata de una característica muy útil que, además de permitirnos programar más rápidamente al ahorrarnos teclear los tipos de las variables locales, actúa como soporte de nuevas características del lenguaje y la plataforma .NET, como el interesantísimo Linq.

Es conveniente, sin embargo, utilizar esta característica con cordura y siendo siempre conscientes de que su uso puede dar lugar a un código menos legible y generar errores difíciles de depurar. De hecho, Microsoft recomienda usarlas "sólo cuando sea conveniente".

Publicado en: Variable Not Found.
lunes, 7 de enero de 2008
Variable not foundEn un blog relativamente joven como este, donde el tráfico se ha incrementado de forma bastante considerable en los últimos meses, y cuyos lectores son mayoritariamente nuevos, es posible que éstos no hayan accedido a artículos anteriores a este periodo que pueden resultar interesantes dado el número de lecturas y repercusión conseguida por los mismos.

Me ha parecido interesante la idea de Martín, desde Pensamientos Ágiles, de recoger los posts más visitados de su blog durante el pasado 2007, así que, con su permiso, voy a tomarla prestada y aplicarla a Variable Not Found. ;-)

1. El indiscutible vencedor, "Entre 10 y 28 programadores por el precio de uno", publicado el pasado mes de julio, en el que comentaba un post de Phil Haack que hablaba de factores que influyen en la productividad de los desarrolladores. Este post fue muy difundido gracias a menéame y otros blogs que se hicieron eco de él.

2. En segundo puesto, "Bordes redondeados en webs (sin esfuerzo) con Nifty Corners Cube" puso de manifiesto el interés que despierta este asunto entre los desarrolladores de webs. De hecho, la gran difusión de este post superó todas las expectativas, y fue el causante de la creación de NiftyDotNet, mi primer componente de código abierto.

3. "Llamar a métodos estáticos con ASP.NET Ajax" forma parte de una serie de posts sobre el framework Ajax de Microsoft, donde he procurado explicar cómo usar esta tecnología, siempre de forma muy práctica y aplicada a casos concretos. De hecho, sumando las visitas de forma individual a cada una de las páginas de la serie ("Llamar a servicios web paso a paso", "Intercambio de entidades de datos", "Retornar DataSets desde PageMethods" y "Espía a tus visitantes con Ajax"), casi podríamos llegar al primer puesto, pues todas ellas están entre las quince más visitadas del blog.

4. Los comentarios en el código fuente... sí, eso que parece tener bastante poca importancia a la hora de desarrollar, ha escalado rápidamente en diciembre hasta conseguir la cuarta posición de la mano del post "13 Consejos para comentar tu código fuente", conclusión llevada a la práctica de un artículo anterior, "Problemas al comentar el código fuente". Obviamente, el tema interesa bastante más de lo que podría parecer en un principio.

5. El quinto puesto ha sido una sorpresa. Aunque con un cierto aire off-topic, alejado de la temática habitual del blog, "Escaneo de puertos con idle scan" muestra de forma detallada los entresijos de una interesante técnica de detección de puertos abiertos en equipos remotos, y parece ser que ha resultado interesante. Su continuación práctica, "Idle scan en la práctica", también ha sido seguido, aunque con menor afluencia, por muchos usuarios a la búsqueda de información sobre esta técnica.

6. El sexto puesto también ha resultado sorprendente, pues se trata de un post bastante antiguo y cuya temática normalmente no se trata demasiado por aquí. "Instalar OpenCms bajo Windows" recogía los pasos a seguir para poner en marcha este CMS bajo Windows, y supongo que por la ausencia de otros textos similares en castellano, ha sido ofrecido por Google como resultado a todos los usuarios que buscaban respuesta a sus cuestiones.

7. El séptimo puesto va para un post de opinión, "10 razones por las que tu blog te ayuda a encontrar empleo", en el que recogía reflexiones sobre por qué un blog podía ser una ayuda interesante para destacar y promocionarse para la búsqueda de empleo.

8. La expectación ante la llegada de Visual Studio 2008 hizo que el post "Diez cosas a saber sobre VS2008 y .Net Framework 3.5" subiera también hasta los "top ten" del blog. Cosas que pasan cuando citas a los grandes como Daniel Moth.

9. El post "Hábitos de personas altamente inovadoras", demostró el interés que despiertan las actitudes que facilitan la generación de ideas y la innovación.

10. En el décimo lugar se encuentra una reflexión sobre esta profesión. "¿Recomendarías a tu hijo que se dedicase al mundo del desarrollo de software?" lanzaba una pregunta al aire sobre la satisfacción de los que nos ganamos la vida con esto.

Más allá de décimo lugar también han despertado interés los posts acerca de características de C# como los generics, null coalescing operator, tipos anulables, las cadenas de texto largas (heredoc), o más generales como "TryParse vs. Parse", "Obtener Guids en .Net", o frikadas como "¿Incrementos, autoincrementos o sumas?". Y mención especial para la serie de doce posts técnicas de spam, un tema que también ha interesado bastante a los lectores.

Publicado en: http://www.variablenotfound.com/.
viernes, 28 de diciembre de 2007
Imagen de la firma del contratoAunque hace varias semanas que el rumor saltó a la blogosfera, hoy han confirmado la noticia en una rueda de prensa conjunta: a partir del próximo 1 de enero Stallman formará parte de la plantilla de Microsoft en Redmond.

La nota de prensa publicada por Microsoft recoge, textualmente, los siguientes párrafos:
"Microsoft siempre apuesta por el talento, y Richard Stallman es uno de los más reputados ideólogos del mundo del desarrollo del software."
[...]
"Sin duda, se trata de una de las incorporaciones más importantes a la compañía de los últimos años, por lo que no hemos escatimado en recursos. Las negociaciones las han llevado a cabo directamente Gates y Ballmer, los dos máximos directivos, lo que demuestra la magnitud de la apuesta estratégica que se está llevando a cabo"
Por su parte, Richard Stallman, que nunca ha destacado por su aprecio a la multinacional, justifica la decisión en su blog:

"En realidad nuestras posturas nunca han estado muy alejadas, aunque veíamos las cosas desde perspectivas diferentes. Microsoft, al igual que GNU y el conjunto del movimiento Open Source, pretende hacer llegar el software a todo el mundo y hacer que sea un bien universal."
[...]
"Hay más puntos en común que diferencias, sólo era cuestión de sentarnos y dialogar sobre hacia dónde podíamos caminar juntos"

Gates y Stallman en la rueda de prensaEn principio Stallman encabezará una nueva división en Microsoft destinada al análisis y evaluación de soluciones de software libre para el segmento SOHO (Small Office, Home Office) y grandes corporaciones, así como a dirigir la adaptación de ciertos componentes del microkernel de Linux a Windows Server 2012 (codename "MindBreaker"), que se lanzará al mercado en unos años y del que ya están disponibles vía MSDN algunos whitepapers y documentos muy muy preliminares.

Este movimiento forma parte de la estrategia de acercamiento de Microsoft al mundo del software libre, como se lleva viendo algún tiempo. Los acuerdos entre Microsft y Novell, la publicación del código fuente de .NET Framework y la gran cantidad de líneas de actuación que están promoviendo así lo demuestran.

Y por cierto, se dice que el próximo en la lista de Most Wanted People de Microsoft y con el que hay conversaciones bastante avanzadas (de nuevo, pues ya las hubo hace tiempo) es Miguel de Icaza, líder del proyecto Mono, aunque él todavía no ha declarado nada al respecto. Otros en la lista son el mismísimo Linus Torvalds, creador del primer núcleo de Linux, firme candidato a liderar el área de arquitectura de servidores y servicios, y Vinton Cerf, considerado el padre de internet, para el puesto de Technical Chief Developer de la línea de productos Internet Explorer.

Habrá que esperar para ver a qué conduce esta reorientación en la estrategia que se viene observando desde hace unos meses, y sobre todo en qué se traduce la fiebre por los fichajes de figuras del mundillo. El tiempo lo dirá.

Actualización 29/12
Nota para despistados, que haberlos, haylos: obviamente la noticia no es real, se trata de una broma del día de los inocentes.
Por cierto, hay muchos comentarios simpáticos en mi blog en geeks.ms.


Publicado en: www.variablenotfound.com.
lunes, 24 de diciembre de 2007
Árbol de NavidadPara conocer si un equipo remoto tiene un puerto abierto existen multitud de técnicas. Hace tiempo describí una muy potente llamada idle scan y hoy, haciendo honor a la fecha en que nos encontramos, describiremos el escaneo "Xmas Tree" (árbol de navidad).

Esta técnica consiste en enviar un segmento TCP al puerto deseado del dispositivo a investigar con los bits FIN, URG y PUSH activos. Esto hace que el byte de flags contenga "00101001", lo cual parece ser que recuerda a las luces de un árbol de navidad, y de ahí su nombre. Imaginación y espíritu navideño que no falte. ;-)

Cuando la víctima del escano recibe este segmento, según dictan las directrices marcadas por el protocolo,

  • si el puerto está cerrado, devuelve un segmento con el bit RST activo, indicando que se resetee la conexión en cliente.
  • si el puerto está abierto, ignora el paquete recibido y no responde nada.
Atendiendo a la respuesta (o ausencia de ella), el atacante puede determinar el estado del puerto que está investigando de una forma realmente silenciosa, puesto que no inicia ninguna conexión (como los sondeos SYN, que inician un 3-way-handshake), y sorteando a veces filtros que no esperan este tipo de combinaciones en los flags.

Sin embargo, como aspectos negativos, podemos decir que es bastante sencillo de filtrar y detectar, y que ponen al descubierto la dirección del atacante, por lo cual es conveniente realizarlos desde zombies o intermediarios. También es complicado determinar la veracidad del resultado, puesto que:

  • la respuesta puede ser la misma (o sea, ninguna) si un puerto está abierto o si el paquete ha sido interceptado por un elemento de seguridad (como un firewall).
  • también un puerto puede parecer cerrado sin estarlo debido a una interpretación errónea de la RFC.
En cualquier caso, podemos realizarlo de forma muy sencilla utilizando la herramienta nmap (si usas alguna distribución de linux basada en Debian, como Ubuntu, puedes descargar e instalarla haciendo un apt-get install nmap.). El escaneo lo realizaríamos con la orden (siendo w.x.y.z la dirección IP de la víctima):
nmap -sX w.x.y.z

Ah, por cierto, ¡feliz navidad!

Publicado en: http://www.variablenotfound.com/.
miércoles, 19 de diciembre de 2007
Hace unos días me topé con los Diez Mandamientos del Abogado, el célebre decálogo formulado por el jurista uruguayo Eduardo J. Couture, donde se recogen una serie de normas éticas y de conducta que deberían guiar las acciones de estos profesionales.

Me llamó la atención porque muchas de estas líneas son totalmente aplicables a otros ámbitos y colectivos, y por supuesto al mundo del desarrollo de software, dado que contiene perlas como: "Estudia, puesto que el Derecho evoluciona constantemente", o "Piensa, puesto que el Derecho se aprende estudiando pero se ejerce pensando".

Sin embargo, el que me hizo reflexionar fue el décimo:

10. AMA TU PROFESION. Trata de considerar la abogacía de tal manera, que el día en que tu hijo te pida consejo sobre su destino, consideres un honor para ti proponerle que se haga abogado.

Y es que la pregunta es: ¿estamos tan satisfechos de nuestra profesión como para aconsejar a un hijo, al que se supone que debemos desearle lo mejor del mundo, dedicarse a ella?

No son pocos los profesionales del desarrollo de software que, bien por circunstancias laborales, personales, falta de vocación u otros motivos, reniegan continuamente, y a veces no sin razón, de este mundillo. Y es que con mucha frecuencia se trata de un trabajo mal pagado, muy duro, con horarios imposibles, estrés continuo, necesidad de actualización de conocimientos frecuente, y escaso reconocimiento social.

Así está el patio como está. Cada vez más gente que huye dando el salto a otras profesiones, las matrículas en informática por los suelos, los ingenieros en continua protesta (;-)) ... en fin, un panorama nada alentador para el futuro.

A pesar de esto, yo soy de los que estarían encantados de que alguno de mis hijos (hijas, en este caso) se dedicara al mundo del desarrollo de software, siempre, eso sí, que consiguieran apasionarse por ello. Nunca se la recomendaría como una salida profesional más, pues creo que al igual que es una dedicación fascinante para el que le gusta, estoy seguro de que debe ser una auténtica pesadilla para el que no disfrute creando software.

Probablemente dedicándose a esto no conseguirán nunca hacerse ricas, ni famosas, ni llegar todos los días pronto a casa... pero bueno, tampoco siendo médicos, ni abogados, ni taxistas. Y, en cambio, tendrían por delante una profesión (y muchas veces hobby) donde volcar toda su creatividad y talento, la satisfacción de la investigación y aprendizaje continuos, de crear software que ayuden a otros a trabajar, estudiar o pasar buenos ratos de ocio... en fin, un universo de posibilidades.

¿Y tú, recomendarías a tu hijo que se dedicara al mundo del desarrollo?

Publicado en: www.variablenotfound.com
martes, 18 de diciembre de 2007
Hace unos días Rosario C. realizaba, a través de un comentario en el post "Llamar a métodos estáticos con ASP.Net Ajax", una consulta sobre un problema con el se había topado al intentar retornar DataSets desde un método de página (PageMethod) de ASP.Net Ajax, un tema tan interesante que vale la pena escribir un post en exclusiva.

Recordemos que los métodos estáticos de página son una interesante capacidad que nos ofrece este framework para poder invocar desde cliente (javascript) funciones de servidor (codebehind) de una forma realmente sencilla. Además, gracias a los mecanismos de seriación incluidos, y como ya vimos en el post "Usando ASP.NET AJAX para el intercambio de entidades de datos", es perfectamente posible devolver desde servidor entidades o estructuras de datos complejas, y obtenerlas y procesarlas directamente desde cliente utilizando javascript, y viceversa.

Es es ahí donde reside el problema con los DataSets: precisamente este tipo de datos no está soportado directamente por el seriador JSON incorporado, que es el utilizado por defecto, de ahí que se genere una excepción como la que sigue:

System.InvalidOperationException
A circular reference was detected while serializing an object of type 'System.Globalization.CultureInfo'.
en System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat)\r\n en System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat [...]

Pero antes de nada, un inciso. Dado que la excepción se produce en el momento de la seriación, justo antes de enviar los datos de vuelta al cliente, debe ser capturada en cliente vía la función callback especificada como último parámetro en la llamada al método del servidor:

// Llamada a nuestro PageMethod
PageMethods.GetData(param, OnOK, OnError);
[...]


function OnError(msg)
{
// msg es de la clase WebServiceError.
alert("Error: " + msg.get_message());
}
 
Aclarado esto, continuamos con el tema. La buena noticia es que el soporte para DataSets estará incluido en futuras versiones de la plataforma. De hecho, es perfectamente posible utilizar las librerías disponibles en previews disponibles en la actualidad. Existen multitud de ejemplos en la red sobre cómo es posible realizar esto, aunque será necesario instalar alguna CTP y referenciar librerías en el Web.config. Podéis echar un vistazo a lo descrito en este foro.

Esta solución sin embargo no es muy recomendable en estos momentos, puesto que estaríamos introduciendo en un proyecto librerías y componentes que, en primer lugar, están ideados sólo para probar y tomar contacto con las nuevas tecnologías, y, en segundo lugar, las características presentadas en ellos pueden modificarse o incluso eliminarse de las futuras versiones.

Existen otras formas de hacerlo, como la descrita en siderite, que consiste en crear un conversor justo a la medida de nuestras necesidades extendiendo la clase JavaScriptConverter, aunque aún me parecía una salida demasiado compleja al problema.

Sin embargo, la solución que he visto más simple es utilizar XML para la seriación de estas entidades, lo que se puede lograr de una forma muy sencilla añadiendo al método a utilizar un atributo modificando el formato de respuesta utilizado por defecto, de JSON a XML.

He creado un proyecto de demostración para VS2005, esta vez en VB.NET aunque la traducción a C# es directa, con una página llamada DataSetPageMethods.aspx en el que se establece un PageMethod en el lado del servidor, con la siguiente signatura:

<WebMethod()> _
<Script.Services.ScriptMethod(ResponseFormat:=ResponseFormat.Xml)> _
Public Shared Function ObtenerClientes(ByVal ciudad As String) As DataSet
 
Este método estático obtendrá de la tradicional base de datos NorthWind (en italiano, eso sí, no tenía otra a mano O:-)) un DataSet con los clientes asociados a la ciudad cuyo nombre se recibe como parámetro.

Como podréis observar, el método está precedido por la declaración de dos atributos. El primero de ellos, WebMethod(), lo define como un PageMethod y lo hará visible desde cliente de forma directa. El segundo de ellos redefine su mecanismo de seriación por defecto, pasándolo a XML. Si queréis ver el error al que hacía referencia al principio, podéis modificar el valor del ResponseFormat a JSON, su valor por defecto.

Desde cliente, al cargar la página rellenamos un desplegable con las distintas ciudades. Cuando el usuario selecciona un elemento y pulsa el botón "¡Pulsa!", se realizará una llamada asíncrona al PageMethod, según el código:

function llamar()
{
PageMethods.ObtenerClientes($get("<%= DropDownList1.ClientID %>").value , OnOK, OnError);
}
 
La función callback de notificación de finalización de la operación, OnOk, recibirá el DataSet del servidor y mostrará en la página dos resúmenes de los datos obtenidos que describiré a continuación. He querido hacerlo así para demostrar dos posibles alternativas a la hora de procesar desde cliente los datos recibidos, el DataSet, desde servidor.

En el primer ejemplo, se crea en cliente una lista sin orden con los nombres de las personas de contacto de los clientes (valga la redundancia ;-)), donde muestro cómo es posible utilizar el DOM para realizar recorridos sobre el conjunto de datos:

var nds = data.documentElement.getElementsByTagName("NewDataSet");
var rows = nds[0].getElementsByTagName("Table");
var st = rows.length + " filas. Personas:  br />";
st += "<ul>";
for(var i = 0; i < rows.length; i++)
{
st += "<li>" + getText(rows[i].getElementsByTagName("Contatto")[0])+ "</li>";
}
st += "</ul>";
etiqueta.innerHTML = st;
 
En el segundo ejemplo se muestra otra posibilidad, la utilización de DOM para crear una función recursiva que recorra en profundidad la estructura XML mostrando la información contenida. La función javascript que realiza esta tarea se llama procesaXml.

Como se puede comprobar analizando el código, utilizar la información del DataSet en cliente es necesario, en cualquier caso, un conocimiento de la estructura interna de est tipo de datos, lo cual no es sencillo, por lo que recomendaría enviar y gestionar los DataSets en cliente sólo cuando no haya más remedio.

Una alternativa que además de resultar menos pesada en términos de ancho de banda y proceso requerido para su tratamiento es bastante más sencilla de implementar sería enviar a cliente la información incluida un un array, donde cada elemento sería del tipo de datos apropiado (por ejemplo, un array de Personas, Facturas, o lo que sea). La seriación será JSON, mucho más optimizada, además de resultar simplísimo su tratamiento en javascript.

El proyecto de demostración también incluye una página (ArrayPageMethods.aspx) donde está implementado un método que devuelve un array del tipo Datos, cuya representación se lleva también a cliente y hace muy sencillo su uso, como se puede observar en esta versión de la función de retorno OnOk:

function OnOK(datos)
{
var etiqueta = $get("lblMensajes");
var s = "<ul>";
for (var i = 0; i < datos.length; i++)
{
s += "<li>" + datos[i].Contacto;
s += ". Tel: " + datos[i].Telefono;
s += "</li>";
}
s += "</ul>";
etiqueta.innerHTML = s;
}
 

Por último, comentar que el proyecto de ejemplo funciona también con VS2008 (Web Developer Express), aunque hay que abrirlo como una web existente.

Publicado en: www.variablenotfound.com.


Enlace: Descargar proyecto VS2005.