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 ;)

18 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!
domingo, 28 de diciembre de 2008
Charla de Matt Gretz sobre el futuro de VB.NETTras algunos días de intenso debate, ayer quedó constituida SVBNet, la plataforma pro-salvación de Visual Basic, como movimiento independiente de la comunidad de desarrolladores de habla hispana aupa.net, cuyo objetivo es apoyar la continuidad del lenguaje y hacer presión para forzar un replanteamiento de su estrategia comercial.

Para el que todavía no esté al tanto de la historia, durante la segunda semana de diciembre ha tenido lugar en Dallas el encuentro de desarrolladores DevConn4, en el que Matt Gretz, destacado miembro del equipo de VB.NET, hacía público el Roadmap que Microsoft tiene previsto para este producto, que no trae buenas noticias para la gran comunidad de desarrolladores en Visual Basic, y que provocó un revuelo impresionante tanto en la sala del evento como en la blogosfera y medios especializados.

Resumidamente, el Roadmap prevé la progresiva desaparición de Visual Basic, mediante un plan de migración que facilitará los desarrolladores pasar a C# en un plazo de tres años. A partir de 2012 no se publicarán nuevas versiones de VB, por lo que, dado que el lenguaje no evolucionará para reflejar los cambios que sean introducidos a nivel de framework, lo llevará irremediablemente a su desaparición en no más de cinco años.

En líneas generales, el contexto actual y el panorama que nos espera, si nadie lo impide, es el siguiente:
  • Primero, durante años se han ido introduciendo mejoras en Visual Basic .NET hasta cubrir la mayoría de características del framework e igualarlo en potencia a C#, con objeto de hacer más suave el salto de un lenguaje a otro. Por ejemplo, la inclusión en el actual VB.NET 9 de tal cantidad de novedades y cambios respecto a versiones anteriores, responden claramente a estas necesidades.

    Hasta aquí, todo es correcto y aporta exclusivamente ventajas. El problema viene ahora.
     

  • La segunda gran acción podremos verla con el próximo Visual Studio 2010 y .Net 4.0, de los cuales ya es posible descargar previews. Para entonces, Visual Basic aparecerá con el nombre comercial VB# (VB Sharp), dando a entender que se trata de una versión de transición a C#, y en el que podremos encontrar el giro hacia una sintaxis más cercana a este lenguaje, como el uso de llaves en bloques (if, blucles while y for, etc.), estructuras compactas (como la sintaxis lambda o declaraciones menos verbosas), comentarios tipo C "/*", y otras lindezas que seguro que dejarán nuestro código VB bastante diferente al actual. Eso sí, para facilitarnos la vida, será el propio IDE el que nos ayude a acostumbrarnos a las particularidades sintácticas, sustituyendo sobre la marcha el código VB.NET tradicional por VB#.

    En esta fase también encontraremos los cambios que se van a producir en C# para dotarlo de algunas de las ventajas de Visual Basic, como los parámetros opcionales, con objeto de lograr una mayor confluencia y hacer más fácil la adopción del lenguaje por esta comunidad de desarrolladores.
     

  • La última parte del plan se llevará a cabo en 2012 con Visual Studio (codename Moonwalker), que se distribuirá con .NET framework 5.0 (aka Greengarden) y no vendrá acompañado de una nueva versión de Visual Basic, sino de un asistente de migración a C#. Para esas fechas, además, se prevé que la mayoría de desarrolladores de Visual Basic haya adoptado VB#, por lo que el salto será, en palabras de Matt, "no traumático".

Roadmap de VB.NET presentado en DevConn4

Finalmente, comentar que también hemos acordado el emblema de la plataforma pro-salvación de Visual Basic que podemos ir utilizando en nuestras páginas para dar difusión al movimiento hasta que tengamos lista la web oficial, que se prevé finalizada para primeros de año.

Logo Plataforma pro-salvación de Visual BasicSi eres simpatizante de la causa, programas o has programado en alguna versión de Visual Basic, y tienes blog o una página relacionada con el desarrollo, descárgate esta imagen (¡por favor, no hagas hotlinking!) y colócala en un lugar visible apuntando al futuro sitio web de la plataforma. Si el diseño no encaja en tu web, no te preocupes: en breve tendremos a nuestra disposición nuevos botones en tamaños menores (125 y 250 píxeles de ancho) y con ciertas variaciones estéticas y nuevos colores, e incluso versiones en Flash y Silverlight, según Raúl Mondo, el diseñador que está realizando este excelente trabajo.

Y no olvides que cuanto más difundamos esta iniciativa, más fuerza tendremos ante la multinacional para hacer que se replantee su estrategia.

¡Larga vida a VB.NET!

[Actualizado 29/12]
Obviamente la noticia no es real, se trata simplemente de una broma del Día de los Inocentes, pero en cualquier caso... ¡Larga vida a VB! :-D


Publicado en: www.variablenotfound.com.
domingo, 21 de diciembre de 2008
Hace tiempo que venía notando que mi equipo del trabajo no podía abrir algunos archivos .CHM. En lugar de mostrar el contenido, habitualmente textos de ayuda de aplicaciones o librerías, me regalaba este bonito error:
"Se canceló la navegación a la página web. Puede intentar lo siguiente: volver a escribir la dirección"

Error en archivo .CHM
El índice de contenidos funcionaba; el alfabético también; incluso la búsqueda por palabras se ejecutaba correctamente, pero sin embargo, al pulsar sobre una sección en el panel izquierdo, aparecía la pantalla anterior en lugar del contenido deseado.

Tras meses culpando al equipo o a la calidad de los archivos que ponen algunos a descargar, por fin me he dado cuenta de que se trata de una medida de seguridad para protegerse de contenidos procedentes de equipos remotos, todos ellos potencialmente diabólicos.

Al parecer, si el archivo de ayuda lo estás abriendo desde una unidad de red, probablemente no te dejará hacerlo, a no ser que indiques a tu equipo que se trata de una fuente de confianza (en el Centro de Ayuda y Soporte de Microsoft puedes encontrar distintas formas de hacerlo, tocando el registro de Windows). La solución más sencilla en este caso sería copiarlo a tu equipo.

Si el archivo de ayuda .CHM te lo has descargado de internet, tu equipo lo habrá bloqueado para evitar que algún código malicioso te cambie los planes del día, así que para acceder a su contenido debes desbloquearlo, accediendo a la opción Propiedades del menú contextual del fichero, y pulsando el botón Desbloquear, como se muestra en la siguiente captura:



Publicado en: www.variablenotfound.com.
martes, 16 de diciembre de 2008
NiftyDotNet redondeando imágenesEl otro día me topé, casi por casualidad, con una forma para crear imágenes con esquinas redondeadas sin necesidad de recurrir a Photoshop ni manipularlas desde la aplicación, simplemente usando NiftyDotNet.

La forma de conseguirlo es muy sencilla, y básicamente aprovecha la técnica utilizada por Nifty Corners Cube, la librería javascript encapsulada por NiftyDotNet, para crear el efecto de redondeo de los ángulos de elementos de bloque de una página Web.

Lo primero que debemos hacer es incluir la imagen en nuestra página dentro de la habitual etiqueta <img>, pero eso sí, dentro de un elemento contenedor, que es al que aplicaremos el efecto de redondeo:

<div class="fotonifty"
style="background: url(images/paisaje1.jpg) no-repeat top left;" >
<img src="images/paisaje1.jpg" alt="Magnífico paisaje" />
</div>
[...]

/* Estilos de la página */
<style type="text/css">
.fotonifty
{
width: 150px;
height: 150px;
margin: 10px;
}

.fotonifty img
{
display: none;
}
</style>
 
Fijaos que la etiqueta <img> sigue existiendo, conservando la semántica y características de accesibilidad del marcado, pero la estamos ocultando desde CSS definiéndole un display: none. La que se verá en la web es la definida como fondo del <div> en el estilo.

Observad también que hemos tenido que indicar el ancho y alto del <div>. Esto es absolutamente necesario para que éste tome el tamaño necesario para mostrar la imagen completa.

Ya sólo nos falta aplicar el efecto de redondeo deseado a los elementos <div class="fotonifty">. Con NiftyDotNet, basta con arrastrar y soltar el componente sobre nuestro formulario web, o bien introducir a mano el control, y establecer sus propiedades correctamente:
 <cc1:Nifty ID="Nifty1" runat="server" 
Selectors="div.fotonifty"
CornerSize="Big"
FixedHeight="true" />
 
La propiedad Selectors se ha establecido con el selector CSS que identifica los bloques a redondear, y CornerSize define el tamaño del borde. FixedHeight es necesaria, e indica que el proceso Nifty no debe modificar el alto del elemento, pues está definido a nivel de estilos.

En fin, un truco que puede ser especialmente interesante en contextos donde las imágenes que queremos mostrar redondeadas no forman parte del diseño base de una aplicación web, sino de los contenidos gestionados por los usuarios.

Imágenes redondeadas

Enlaces:Publicado en: www.variablenotfound.com.
domingo, 14 de diciembre de 2008
Editado [Abril/2009]: el proyecto está actualizado para la versión 1.0 de ASP.NET MVC Framework.

Una cascadaUna de las bases de la reutilización de código y mejora de productividad en el desarrollo de vistas ASP.NET MVC son los helpers, pequeños (o no tan pequeños) métodos de extensión de clases accesibles desde la página que nos permiten generar de forma automática código de uso común de marcado, maquetación o scripting, como XHTML, CSS y javascript.

ASP.NET MVC viene de fábrica con un buen conjunto de helpers, como los que podemos encontrar en el espacio de nombres System.Web.Mvc.Html, que nos facilitan la creación de elementos de la página y la introducción de ciertos automatismos. Por ejemplo, si en lugar de escribir en la Vista el código XHTML correspondiente a un cuadro de edición realizamos una invocación del helper, así: <%= Html.TextBox("name") %>, estaremos generando la etiqueta de forma totalmente correcta, y cargando el valor por defecto si en el ViewData existe una entrada con dicho nombre.

Sin embargo, es obvio que los helpers suministrados no cubren todo lo que vamos a requerir para desarrollar de forma productiva aplicaciones basadas ASP.NET MVC, ni siquiera una pequeña parte, por lo que lo lógico es que terminemos desarrollando nuestras propias funciones a base de generalizar las soluciones a problemas y distintos escenarios con los que nos vayamos encontrando.

Desde hace tiempo tenía interés por crear un helper medianamente complejo para ver los problemas con los que podía encontrarme... y no hay nada como un fin de semana climatológicamente desapacible para dedicarse a estos menesteres.

El resultado ha sido LinkDropDownLists, un helper para el framework ASP.NET MVC 1.0 (abril 2009), cuya función es enlazar de forma muy sencilla dos o más desplegables, recargando mediante Ajax (gracias a jQuery) los contenidos cuando alguno de ellos cambie. En otras palabras, se trata de un sistema de desplegables en cascada como el que describí hace unos meses en "Desplegables en cascada con ASP.NET MVC y jQuery", pero en formato helper, muy flexible y cómodo de utilizar, y adaptado a la versión disponible del framework.

Introducción

LinkDropDownLists es un método de extensión de la clase AjaxHelper, que nos permite "encadenar" entre sí un conjunto de desplegables, de forma que el cambio de valor de uno de ellos provoque, en cascada, la recarga del resto siguiendo el orden en el que han sido vinculados.

La recarga se realizará obteniendo los datos mediante una petición Ajax con jQuery a una acción del controlador desde el que se ha generado la Vista, que retornará los elementos en formato JSON, y serán introducidos automáticamente en el desplegable correspondiente.

Ampliar
El método LinkDropDownLists lo utilizaremos en la Vista para generar los scripts necesarios para realizar de forma automática la comunicación con el servidor cada vez que cambie un desplegable; la recepción de la llamada Ajax, por otra parte, requerirá una acción en el Controlador, que será la responsable de obtener la información desde el Modelo y retornarlos a la vista para materializarlos como elementos de los controles visuales.

La Vista

Para utilizar el helper, antes de nada hay que asegurarse de que jQuery está incluido en la vista o su página maestra. Dado que MVC framework desde su versión Beta 1 incluye esta librería en las plantillas por defecto, sólo es necesario referenciarla desde el código HTML, por ejemplo:
 <script src="/scripts/jquery-1.2.6.js" 
type="text/javascript"></script>
 
A partir de este momento, podremos utilizar sin problema el helper de la forma que se describe a continuación, siempre que haya sido incluido el espacio de nombres donde fue definido, por ejemplo usando la directiva de página Import Namespace="Jma.Mvc.jQuery.Extensions", o en la sección <namespaces> del archivo Web.config.

Dado que tanto las vistas que heredan de ViewPage o ViewPage<T> (en la práctica, todas) como los controles ViewUserControl, disponen de una propiedad de tipo AjaxHelper llamada Ajax, podremos invocar los métodos de extensión de dicho tipo desde el código ASPX o ASCX de forma muy sencilla:
<%= Ajax.LinkDropDownLists(...)%>
 
Vamos a mostrar algunos ejemplos de uso del helper LinkDropDownLists, imaginando un formulario en el que existe un desplegable llamado "Pais" (es decir, un <select id="Pais">), otro llamado "Provincia" y un último llamado "Ciudad", tales que un cambio en el primero debería forzar una recarga del segundo, y éste una recarga del tercero.

Utilizando el helper LinkDropDownLists, sólo sería necesario introducir el siguiente código en la vista:
 <%= Ajax.LinkDropDownLists(
new [] {"Pais", "Provincia", "Ciudad"}
)
%>
 
¡Ya está! Esto sería todo lo que habría que hacer en la capa cliente para conseguir enlazarlos. Como puede deducirse, mediante esta orden estaríamos creando una cadena de dependencia entre los tres desplegables, de forma que un cambio en cualquiera de ellos forzaría la recarga de los definidos tras él. El helper se encargará de generar el código script que este mágico comportamiento posible.

Pero compliquemos un poco más el escenario. Si, además, en el mismo formulario se encontrara otro conjunto de desplegables, podríamos enlazarlos entre sí usando la misma llamada, especificando en dos arrays independientes las distintas cadenas de vínculos, como sigue:
 <%= Ajax.LinkDropDownLists(
new [] {"Pais", "Provincia", "Ciudad"},
new [] {"Marca", "Modelo" }
)
%>
 
Y aún cabe una vuelta de tuerca más; si dependiendo de la selección en "Pais" fuera necesario cargar otro desplegable, digamos, "Idioma" que mostrara las lenguas usadas en el mismo, podríamos añadir una tercera cadena de enlaces en la que aparecería de nuevo el desplegable "Pais" vinculado al idioma:
 <%= Ajax.LinkDropDownLists(
new [] {"Pais", "Provincia", "Ciudad"},
new [] {"Marca", "Modelo" },
new [] {"Pais", "Idioma" }
)
%>
 
Como se puede deducir de los ejemplos, cada uno de los parámetros consiste en un array de strings que contiene los identificadores de los desplegables, en el mismo orden en que deben ser recargados. Estos controles pueden estar definidos en cualquier punto de la Vista, bien directamente en HTML o bien mediante el helper Html.DropDownList() incluido en el MVC framework.

Por último, el método LinkDropDownLists() dispone de un buen conjunto de sobrecargas, que nos permitirán modificar los siguientes aspectos de su comportamiento por defecto:
  • workingMessage: mensaje que muestra en el desplegable mientras se están obteniendo los datos del servidor.
  • errorMessage: mensaje a mostrar cuando se produce un error de conexión, o se lanza una excepción desde el servidor.
  • javascriptCallbackFunction: nombre de la función javascript que se ejecutará cuando se han obtenido datos del servidor y se ha recargado un desplegable.
  • actionName: nombre de la acción en el controlador (por defecto GetDropDownElements()).
  • imgSrc: URL de la imagen de progreso de carga mostrada durante la petición Ajax (por defecto, "/content/ajax-loading.gif").
  • mainFunctionName: nombre de la función principal que genera el helper (por defecto, loadDropDownList).

El controlador

En el lado servidor, necesitamos una acción en el controlador desde el que se esté lanzando la vista que sea la encargada de procesar las peticiones enviadas desde la capa cliente y retornar los elementos que poblarán el desplegable. Por defecto, esta la acción se llamará GetDropDownElements, aunque puede modificarse utilizando las sobrecargas del helper descritas anteriormente.

Para que pueda disponer de toda la información de contexto necesaria, a esta acción se le pasan los siguientes parámetros de forma automática desde la Vista:
  • source: el desplegable que ha cambiado.
  • value: el nuevo valor que ha tomado.
  • text: el texto mostrado en el desplegable.
  • index: el índice del elemento seleccionado.
  • target: el nombre del desplegable a cargar.

La firma del método deberá contener los parámetros que necesite de los anteriores, no siendo obligatorio ninguno de ellos. Las siguientes signaturas, por tanto, serían válidas, aunque la segunda permitirá acceder a más información sobre la situación en cliente al producirse la invocación Ajax:
 public ActionResult GetDropDownElements(string target) 
{ ... }

public ActionResult GetDropDownElements(
string source, string value,
string text, int index, string target)
{ ... }
 
Dentro de la acción, lo lógico será utilizar el Modelo para obtener los elementos que pueblen el desplegable target. Por ejemplo, si recibimos una petición indicando que debemos llenar el desplegable de provincias debido a un cambio de país (source=="Pais" && target=="Provincia"), deberemos realizar una consulta en el almacén de datos filtrando aquellas cuyo identificador de país sea el contenido en el parámetro value.

Si no encontramos datos para devolver, el retorno de la función será un string serializado en JSON, indicando el error. Este mensaje será mostrado como contenido del desplegable.
  ... 
return Json("No se han definido provincias para " + text);
 
En caso contrario, es decir, si disponemos de elementos para rellenar el desplegable, el retorno será una colección de objetos que deberán presentar las siguientes propiedades públicas:
  • Value: con el valor del elemento (el value del option).
  • Text: que contendrá el texto que será mostrado en el desplegable.
  • Selected: un booleano que indicará si el elemento deberá ser la selección por defecto una vez poblado el desplegable.
Para evitarnos demasiados esfuerzos ;-), una característica muy interesante de la que podemos hacer uso para crear los retornos es de los tipos anónimos, así:
  // Generando los elementos de forma manual...
List<object> elements = new List<object>();
elements.Add(new { Value = 1, Text = "Primero" });
elements.Add(new { Value = 2, Text = "Segundo" });
elements.Add(new { Value = 3, Text = "Tercero" });
elements.Add(new { Value = 4, Text = "Cuarto", Selected = true });
return Json(elements);

// O usando Linq...
var elems = from p in Model.ObtenerProvincias(value)
select new
{
Text = p.NombreProvincia,
Value = p.IdProvincia
};
return Json(elems);
 

Proyecto de demostración

Al pie del post hay un enlace a Skydrive desde donde podréis descargar un proyecto de demostración del helper LinkDropDownLists para ver algunas de sus características en funcionamiento:
  • una única página con dos grupos independientes de desplegables enlazados
  • algunos desplegables definidos mediante helpers y en HTML.
  • retorno de mensajes de error desde el servidor
  • captura de excepciones y errores de comunicación
  • función callback de notificación de llenado de desplegables
  • utilización de textos personalizados
En el propio proyecto encontraréis el código completo del helper en el archivo Extensions/jQueryExtensions.cs.

Ampliar

Enlaces: Descargar proyecto para Visual Studio 2008 SP1 + ASP.NET MVC 1.0.
(También funciona con Visual Web Developer Express 2008 SP1).


Publicado en: www.variablenotfound.com.
lunes, 8 de diciembre de 2008
Popurrí de tipos de gráficas permitidasPues tiene una pinta excelente el control para la generación de gráficas estadísticas Chart Control para ASP.NET 3.5, recientemente presentado en sociedad por Scottgu (con la habitual traducción en Thinking in .net).

Se trata de un componente con una versión específica para ASP.NET, válida para WebForms y MVC framework, y otra para Windows Forms, que permite generar gráficas estadísticas prácticamente de cualquier tipo, visualmente muy atractivas, realmente fáciles de utilizar en nuestas aplicaciones y, además, de forma gratuita.

Enumero características interesantes, o que me han llamado la atención (ambas cosas no están necesariamente unidas ;-)), del control para ASP.NET:
  • El control se renderiza en cliente con una etiqueta <img>.
  • Se puede forzar al control a generar las imágenes al vuelo o a almacenarlas físicamente en una carpeta.
  • Las imágenes generadas pueden ser cacheadas para mejorar el rendimiento.
  • Genera BMPs, JPGs, PNGs o EMFs.
  • Permite también usarlo con aplicaciones no ASP.NET 3.5 a través del modo "binary streaming", que fuerza a que el control elimine toda la salida HTML de la página donde se encuentra y retorne únicamente la imagen como resultado, de forma dicha página puede ser utilizada como source de un tag <img> en otro sitio.
  • Soporta eventos del tipo "PrePaint" y "PostPaint" para poder hacer retoques a mano sobre los resultados, como:
    void Chart1_PostPaint(object sender, ChartPaintEventArgs e)
    {
    e.ChartGraphics.Graphics.DrawString("Hola",
    new Font("Arial", 12f),
    Brushes.Black, 10, 10);
    }
     
  • 25 tipos de gráficas, muchas de ellas con vistas en tres dimensiones, en las que se puede modificar prácticamente todo: rotación, inclinación, sombras, etc.
  • Podemos crear imágenes con múltiples gráficas distintas, utilizar en ellas todas las series de datos que deseemos, con un número ilimitado de puntos.
  • Control total sobre los ejes en cuanto a escalado, visualización o etiquetado.
  • Posibilidad de añadir anotaciones, leyendas y otros elementos "extra".
  • Permite establecer datos enlazando el control a fuentes (binding), o de forma manual sobre el mismo utilizando los diseñadores o etiquetas ASP.NET.
  • Soporta mapeo de imágenes, posibilidad de capturar clicks sobre áreas para establecer comportamientos personalizados, o combinarlo con Ajax para enriquecer la experiencia de usuario.


Instalación

Antes de instalar, asegúrate que cumples el requisito previo básico, tener instalado Microsoft .NET Framework 3.5 SP1. Si no lo has hecho antes, ya sabes por dónde empezar ;-)

Una vez asegurado este punto, el siguiente paso es descargar Microsoft Chart Control, que incluye controles tanto para ASP.NET como para Windows Forms. Existe también, como descarga opcional, el paquete de idioma para Microsoft Chart Control, que contiene la localización del producto para otros idiomas.

Después, es una buena idea instalar el Add-on para Visual Studio 2008 que os facilitará el trabajo con el control desde este entorno de desarrollo, a base de diseñadores integrados. No olvidéis también bajaros también la documentación si váis a necesitar información detallada de las librerías incluidas.

Y, por último, para tomar conciencia del tipo de resultados que se pueden obtener con este control, el ideal es descargar los proyectos de demostración, que os permitirán ver y tocar una auténtica batería de ejemplos seguro muy útiles a la hora de usarlo en vuestros desarrollos, tanto ASP.NET como Winforms.

Prueba del Chart Control

Publicado en: www.variablenotfound.com.