Aunque su licencia no permite redistribuir los binarios resultantes para evitar que posibles versiones alternativas del framework circulen por ahí, es muy interesante, sin duda, ver las "tripas" de esta nueva criatura.
Y, por cierto, también carga en Visual C# 2008 Express Edition...
Publicado en: http://www.variablenotfound.com/.
Concretamente, se trata de una adaptación de Phil Haack para la CTP2 de una aplicación creada inicialmente por Brad Abrams que muestra un catálogo de productos categorizado, tomados de la clásica base de datos NorthWind (para SQLServer/Express), y permite la creación, edición y eliminación de los mismos (CRUD); en otras palabras, una mini-aplicación completa. El acceso a datos se realiza mediante Linq, y las clases del Modelo se han generado con el diseñador Linq2SQL.
Aparte de la adaptación, he aprovechado para retocarla un poco, y le he añadido algunas funcionalidades y detalles que no estaban implementados. Faltan algunos flequillos, como las validaciones de formularios que todavía no he visto cómo se resuelven en el framework, pero bueno, lo que hay es una base interesante para comenzar o seguir profundizando en esta tecnología.
Podéis descargar el proyecto desde el enlace que encontraréis más abajo. Una vez descomprimido el archivo, abrid la carpeta desde Visual Web Developer Express (opción "Abrir > Abrir sitio web" o "File > Open web site" si tenéis aún la versión en inglés) y listo, podéis pulsar F5 para ejecutar.
Por cierto, no sé si funcionará bien con las versiones "pro" de Visual Studio 2008. Agradecería que si alguien lo prueba en este entorno, me lo comentara.
Enlaces: Proyecto NorthWind Demo para ASP.NET MVC (~2MB)
Publicado en: http://www.variablenotfound.com/.
Publicado por José M. Aguilar a las 9:50 p. m.
Etiquetas: asp.net, aspnetmvc, desarrollo, programación, web
Se trata de un entorno de desarrollo integrado (IDE) para la plataforma .NET en el que el equipo del proyecto Mono anda trabajando desde hace varios años. Su objetivo inicial era facilitar una herramienta libre y gratuita para Linux, MacOS e incluso Windows, que permita la creación de aplicaciones en C# y otros lenguajes .NET, aunque después ha evolucionado hasta convertirse en una plataforma extensible sobre la que podría encajar cualquier tipo de herramienta de desarrollo.
- Se trata de un entorno muy personalizable, permitiendo la creación de atajos de teclado, la redistribución de elementos en pantalla o inclusión de herramientas externas.
- Soporta varios lenguajes, como C#, VB.Net o C/C++ o incluso Boo y Java (IKVM) a través de plugins externos.
- Ayuda en la escritura del código (auto-completar, información de parámetros... al más puro estilo intellisense).
- Incluye herramientas de refactorización, como renombrado de tipos y miembros, encapsulación de campos, sobreescritura de métodos o autoimplementación de interfaces.
- Ayudas en la navegación a través del código, como saltar a las declaraciones de variables, o búsquedas de clases derivadas.
- Diseñador de interfaces para aplicaciones GTK# y soporte para librerías de widgets.
- Control de versiones integrado, con soporte para Subversion.
- Pruebas unitarias integradas, utilizando NUnit.
- Soporte para proyectos ASP.Net.
- Servidor web integrado (XSP) para pruebas.
- Explorador y editor de bases de datos integrados (aún en beta).
- Integración con Monodoc, para la documentación de clases.
- Soporte para makefiles, tanto para generación como para sincronización.
- Soporte para formatos de proyecto Visual Studio 2005.
- Sistema de empaquetado que genera tarballs, código fuente y binarios.
- Línea de comandos para generar y gestionar proyectos.
- Soporte para proyectos de localización.
- Arquitectura extensible a través de plugins.
Información mucho más detallada, eso sí, en inglés, en la web del proyecto.
Publicado en: http://www.variablenotfound.com/.
Publicado por José M. Aguilar a las 11:58 a. m.
Etiquetas: .net, desarrollo, herramientas, mono, noticias
Una unión es muy similar a una estructura de datos (
struct
en C# o Structure
en VB.Net), salvo en un detalle: sus componentes se almacenan sobre las mismas posiciones de memoria. O visto desde el ángulo opuesto, una unión podríamos definirla como una porción de memoria donde se guardan varias variables, habitualmente de tipos diferentes. Veamos un ejemplo clásico que nos ayudará a entender el concepto, en un lenguaje cualquiera:union Ejemplo
{
char caracter; // suponiendo char de 8 bits
byte octeto; // un byte ocupa 8 bits
};
Si declaramos una variable x del tipo Ejemplo, estaremos reservando un espacio de 8 bits al que accederemos desde cualquiera de sus miembros, como vemos a continuación:
x.caracter = 'A';
x.octeto ++;
escribir_char (x.caracter); // mostraría 'B'
escribir_byte (x.octeto); // mostraría 66
Pero espera... ¿memoria?... ¿almacenamiento de variables?... ¿pero existe eso en .Net?... Pues sí, aunque lo más normal es que no nos tengamos que enfrentar nunca a ello pues el framework realiza estas tareas por nosotros, hay escenarios en los que es necesario controlar la forma en que la información es almacenada en memoria, como cuando se esté operando a bajo nivel, por ejemplo creando estructuras específicas para llamar al API de Windows, o para facilitar el acceso a posiciones concretas de la información.
Desde la versión 1.1 de la plataforma .Net, disponemos del atributo StructLayout, que nos permite indicar en estructuras y clases cómo queremos representar en memoria la información de sus miembros. Básicamente, podemos indicar que:
- la información se almacene como el framework considere oportuno (
LayoutKind.Auto
) - que se almacene de forma secuencial, en el mismo orden en el que han sido declarados (
LayoutKind.Sequential
). - que se almacene donde le indiquemos de forma explícita (
LayoutKind.Explicit
). En este caso, necesitaremos especificar en cada miembro la posición exacta de memoria donde será guardado, utilizando el atributoFieldOffset
.
Es este último método el que nos interesa para nuestros propósitos. Si adornamos una estructura con
StructLayout(LayoutKind.Explicit)
e indicamos en cada uno de sus miembros su desplazamiento (en bytes) dentro del espacio de memoria asignado a la misma, podemos conseguir uniones haciendo que todos ellos comiencen en la misma dirección.Pasemos a vamos a verlo con un ejemplo en C#. Se trata de una unión a la que podemos acceder tratándola como un carácter unicode, o bien como un entero de 16 bits con signo. Los dos miembros, llamados
Caracter
y Valor
están definidos sobre la misma posición de memoria (desplazamiento cero) en el interior de la estructura:using System.Runtime.InteropServices;
using System;
namespace PruebaUniones
{
[StructLayout(LayoutKind.Explicit)]
public struct UnionTest
{
[FieldOffset(0)] public char Caracter;
[FieldOffset(0)] public short Valor;
}
class Program
{
public static void Main()
{
UnionTest ut = new UnionTest();
ut.Caracter = 'A';
ut.Valor ++;
Console.WriteLine(ut.Caracter); // Muestra "B"
Console.ReadKey();
return;
}
}
}
Ahora usaremos VB.NET para mostrar otro ejemplo un poco más complejo que el anterior, donde usamos una unión para descomponer una palabra de 16 bits en los dos bytes que la componen, permitiendo la manipulación de forma directa e independiente de cada una de las dos visiones del valor almacenado en memoria. Para el ejemplo utilizo una unión dentro de otra, aunque no era estrictamente necesario, para que veáis que esto es posible.
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Explicit)> _
Public Structure Union16
<FieldOffset(0)> Dim Word As Int16
<FieldOffset(0)> Dim Bytes As Bytes
End Structure
<StructLayout(LayoutKind.Explicit)> _
Public Structure Bytes
<FieldOffset(0)> Dim Bajo As Byte
<FieldOffset(1)> Dim Alto As Byte
End Structure
Public Class Program
Public Shared Sub main()
Dim u As New Union16
u.Word = 513 ' 513 = 256*1 (Byte alto) + 1 (byte bajo)
u.Bytes.Alto += 1
Console.WriteLine("Word: " & u.Word) ' Muestra 769 (3*256+1)
Console.WriteLine("Byte alto: " & u.Bytes.Alto) ' Muestra 3
Console.WriteLine("Byte bajo: " & u.Bytes.Bajo) ' Muestra 1
Console.ReadKey()
Console.ReadKey()
End Sub
End Class
He encontrado un uso muy interesante para esta técnica en Xtreme .Net Talk, donde se muestra un ejemplo de cómo acceder a los componentes de color de un pixel de forma muy eficiente a través de una unión entre el valor ARGB (32 bits) y cada uno de los bytes que lo componen (alfa, rojo, verde y azul).
En cualquier caso no se recomienda el uso de uniones salvo en casos muy concretos, y siempre conociendo bien las implicaciones que puede tener en la estabilidad y mantenibilidad del sistema.
Pero bueno, ¡está bien al menos saber que existen!
Publicado en: http://www.variablenotfound.com/.
Publicado por José M. Aguilar a las 9:30 p. m.
Etiquetas: .net, c#, nivel alto, programación, vb.net
Una vez descargado el paquete (poca cosa, menos de un mega), procedí a instalarlo, apareciéndome la siguiente ventana de error:
Esto, además, se confirma en el documento de notas de la versión:
“The new releases provide Visual Studio templates that are not supported in Visual Web Developer 2008 Express Edition. For example, you cannot create an MVC application or Silverlight .xap files by using Visual Web Developer 2008 Express Edition.”
En otras palabras, que la segunda CTP, al igual que la primera, incluye plantillas que no son válidas para la versión Express de Visual Web Developer. Qué contrariedad.
Y es cierto que no está soportada, pero esto no implica que los que utilizamos las versiones light de los entornos de desarrollo estemos condenados a no probar esta nueva tecnología; de hecho es perfectamente posible, aunque no contaremos con todas las ayudas que sí vienen de serie para las versiones más "pro".
Una vez finalizada la instalación, encontré en Google varias páginas (por ejemplo aquí y aquí) donde se facilitaban plantillas, basadas en las originales, que nos permitirían probar la primera CTP sobre la versión express. Lamentablemente, los cambios realizados en la plataforma desde entonces hacen incompatibles estas plantillas con la CTP 2, aunque es posible hacerlas funcionar simplemente siguiendo los pasos detallados en esta página.
Para que no tengáis que perder el tiempo en ello, he creado una plantilla de proyecto Web (en C#) para Visual Web Developer Express 2008 que podéis descargar desde aquí.
Si queréis probar un poco esta tecnología, una vez instalada la segunda preview del ASP.Net MVC Framework, descargad la plantilla y guardarla, sin descomprimir, en la carpeta "Visual Studio 2008/Templates/ProjectTemplates". Lo habitual es que encontréis esta carpeta en "Mis documentos".
Iniciad Visual Web Developer 2008 Express, cread un nuevo sitio web en C# seleccionando la plantilla que habéis incluido, llamada "MVCWebSite", así:
Esto creará un proyecto con el web.config correctamente configurado y la estructura de carpetas ideal para una aplicación web de este tipo, lista para salir andando. Por cierto, si al compilar el proyecto os aparece algún problema de referencias a ensamblados de la Preview, sólo debéis añadir a mano (botón derecho sobre el proyecto, añadir referencias) las DLL's que encontraréis en la carpeta donde se haya instalado la CTP, que en mi caso es "C:/Archivos de programa/Microsoft ASP.NET MVC Preview 2/Assemblies"
Y ya no hay nada más que hacer. Si pulsáis la tecla F5, se compilará y en pocos segundos tendréis funcionando un sitio web MVC, con un controlador y algunas vistas, las cuales usan una MasterPage para componer el esqueleto de las páginas. Además, una de ellas, "Links", muestra cómo obtener un parámetro (la lista de enlaces) desde el controlador.
¡Hala, a disfrutarlo!
Publicado en: http://www.variablenotfound.com/.
Publicado por José M. Aguilar a las 8:30 p. m.
Etiquetas: asp.net, aspnetmvc, desarrollo, programación, trucos, web
Por ejemplo, dado el siguiente código en el interior de una página ASP.NET, ¿cuál sería la forma correcta de comentarlo?
<script>
var count = <%= borrarRegistros() %>
alert("Borrados: " + count + " registros");
</script>
Una primera opción podría ser utilizar la sintaxis Javascript de la siguiente forma:
<script>
/*
var count = <%= borrarRegistros() %>
alert("Borrados: " + count + " registros");
*/
</script>
Sin embargo, aunque podría valer en muchas ocasiones, también puede introducir unos efectos laterales considerables. Nótese que aunque el código Javascript (cliente) esté comentado, la función
borrarRegistros()
sería invocada en el lado del servidor, y su retorno introducido dentro del comentario. De hecho, la página enviada a cliente mostraría un código fuente similar al siguiente (imaginando que el retorno de la función fuera el valor 99):<script>
/*
var count = 99;
alert("Borrados: " + count + " registros");
*/
</script>
Tampoco valdría para nada incluir todo el bloque de script dentro de un comentario HTML (<!-- y -->), por la misma razón que antes. Además, en cualquiera de estos dos casos, estaríamos enviando al cliente la información aunque sea éste el que la ignora a la hora de mostrarla o ejecutarla y, por supuesto, estaríamos ejecutando la función en servidor, lo cual podría causar otros efectos no deseados, como, en nuestro ejemplo, eliminar los registros de una base de datos.
Afortunadamente, ASP.NET dispone de un mecanismo, denominado Server Side Comments (comentarios en el lado del servidor), que permite marcar zonas y hacer que se ignore todo su contenido, sea del tipo que sea, a la hora de procesar la página:
<%--
<script>
var count = <%= borrarRegistros() %>
alert("Borrados: " + count + " registros");
</script>
--%>
En este caso ni sería ejecutada la función del servidor ni tampoco enviado a cliente el código HTML/Script incluido.
Publicado en: http://www.variablenotfound.com/.