Ilities

Los “ilities”, cuya traducción a nuestro idioma podría ser algo así como “ilidades”, son atributos que definen aspectos no funcionales y normalmente asociados con requisitos técnicos y cualidades de un sistema o componente software. El nombre viene del sufijo –ilidad, que, como podréis ver a continuación, es común a la práctica totalidad de ellos.

He encontrado en la Wikipedia una interesante (aunque no exhaustiva) relación ilidades, que podemos utilizar a la hora de intentar transmitir las características de un sistema… o simplemente para aparentar ser auténticos expertos en una reunión de trabajo 😉

  1. Accesibilidad, es decir, el hecho ser accesible a muchas personas, con independencia de sus características, dispositivos utilizados, etc.
  2. Reportabilidad, capacidad para monitorizar y registrar las acciones del usuario.
  3. Exactitud, grado de distancia desde los resultados ofrecidos por un sistema a los valores entendidos como reales.
  4. Adaptabilidad, facilidad que presenta un software para ser adaptado a necesidades concretas.
  5. Administrabilidad, indica la capacidad de un sistema o componente para ser administrado y gestionado.
  6. Asequibilidad, que indica que, atendiendo a su coste, el sistema puede ser adquirido o conseguido por los clientes.
  7. Auditabilidad, transparencia frente a sistemas de auditoría.
  8. Disponibilidad, grado en el que un sistema está disponible, operativo y funcional.
  9. Credibilidad, que es considerado subjetiva y objetivamente como una fuente de información fiable.
  10. Conformidad con estándares, grado de cercanía a las prácticas o técnicas aceptadas como estándares.
  11. Compatibilidad, que funciona en un escenario determinado, o permite sustituir otros sistemas equivalentes.
  12. Componibilidad, capacidad para combinar el software con otros elementos para componer sistemas no previstos inicialmente.
  13. Configurabilidad, esto es, que dispone de mecanismos que permiten configurar algunos aspectos de su comportamiento.
  14. Corrección, que indica que el software actúa conforme a sus especificaciones.
  15. Personalizabilidad, capacidad de un sistema para ser personalizado a las preferencias de sus usuarios.
  16. Degradabilidad, capacidad para mantener las funcionalidades básicas en condiciones adversas.
  17. Demostrabilidad, aplicable a aquellos sistemas cuyo funcionamiento puede ser demostrado.
  18. Dependabilidad, que define la probabilidad de que el sistema complete su misión, dado que estaba disponible en el comienzo de la misma.
  19. Desplegabilidad, capacidad de un software para ser desplegado en un escenario.
  20. Distribuibilidad, capacidad o facilidad de un componente o sistema para ser distribuido.
  21. Durabilidad, mantenimiento de las funciones con el paso del tiempo.
  22. Efectividad, o capacidad para lograr el efecto deseado.
  23. Eficiencia, capacidad para lograr el efecto deseado con el menor consumo posible de recursos.
  24. Evolucionabilidad, grado de facilidad con la que es posible hacer evolucionar un sistema para adaptarse a nuevas condiciones.
  25. Extensibilidad, capacidad de un software para ser ampliado con nuevas funciones sin modificar su estructura básica.
  26. Fidelidad, que ofrece precisión y confianza en la representación de la realidad.
  27. Flexibilidad, que puede adaptarse con facilidad a cambios en el entorno.
  28. Instalabilidad, facilidad para ser instalado en un entorno  determinado.
  29. Integridad, capacidad para evitar y sobreponerse a errores en la información que maneja.
  30. Intercambiabilidad, que indica que un componente puede ser sustituido por otro sin modificar aquellos que lo utilizan.
  31. Interoperabilidad, capacidad que tiene un sistema para intercambiar información con otro.
  32. Aprendibilidad, es decir, la capacidad que presenta un software para enseñar su propio manejo al usuario.
  33. Mantenibilidad, o facilidad con la que se puede corregir, modificar o ampliar un software.
  34. Gestionabilidad, facilidad para gestionar la complejidad de un sistema.
  35. Movilidad, posibilidad que tiene un sistema de funcionar en distintas ubicaciones geográficas.
  36. Modularidad, grado en el que un software está internamente dividido en bloques independientes.
  37. Nomadicidad, capacidad de un sistema para adaptarse de forma transparente a una situación de desconexión por cambio de ubicación-
  38. Operabilidad, capacidad de un software para funcionar y cumplir su misión.
  39. Portabilidad, la facilidad con la que un software puede ser transferido a otro entorno software o hardware.
  40. Precisión, nivel de detalle con el que un sistema es capaz de manejar información.
  41. Predictibilidad, grado de certeza del comportamiento del sistema ante un escenario determinado.
  42. Recuperabilidad, capacidad de un sistema de restablecer un nivel apropiado de servicio y recuperar sus datos en caso de producirse fallos.
  43. Fiabilidad, es la habilidad de un software para realizar sus funciones de forma correcta bajo unas condiciones determinadas.
  44. Repetibilidad, es la capacidad de generar el mismo resultado si no cambian las condiciones.
  45. Reproducibilidad, es el grado de precisión que se obtiene al intentar reproducir un comportamiento del sistema.
  46. Responsividad, velocidad con la que un sistema realiza una tarea, por ejemplo responder a la entrada del usuario.
  47. Reusabilidad, facilidad con la que un componente o sistema puede ser reutilizado para añadir funcionalidades o características en un nuevo sistema.
  48. Robustez, capacidad para continuar la operación aún en el caso de producirse errores inesperados.
  49. Seguridad, capacidad de un software para conseguir niveles aceptables de daños a personas, negocios, software, propiedades o entorno.
  50. Escalabilidad, facilidad con la que un sistema puede ser adaptado para satisfacer necesidades mayores de carga de trabajo.
  51. Uniformidad, grado de presentación como una estructura consistente, aunque el sistema incluya diversas tecnologías.
  52. Soportabilidad, que hace referencia a la habilidad del soporte técnico para dar soporte a los productos.
  53. Asegurabilidad, capacidad para asegurar distintos niveles de un sistema.
  54. Simplicidad, o ausencia de complicaciones y dificultades.
  55. Estabilidad, capacidad de un software para funcionar períodos del tiempo sin parar o funcionar incorrectamente.
  56. Comprobabilidad, el grado en el que un componente soporta la realización de pruebas para validar su corrección.
  57. Oportunidad, es decir, el hecho de estar disponible en el momento en el que debe estarlo.
  58. Ubicuidad, capacidad de un software para estar presente en todas partes, en cualquier momento.
  59. Comprensibilidad, facilidad con la que un software puede ser comprendido a los distintos niveles.
  60. Usabilidad, facilidad con la que un usuario puede utilizar un sistema software para conseguir un objetivo. 

Los términos originales estaban en inglés y algunos no eran fácilmente traducibles, así que en más de una ocasión he tenido que echar mano de la creatividad y patear a la RAE y todos sus integrantes ;-D

Publicado en: Variable not found.

xVal, validaciones automáticas para ASP.NET MVC

Mientras esperamos impacientes la llegada de ASP.NET MVC 2 con su flamante sistema integrado de validación de datos en cliente y servidor, xVal puede sernos de bastante utilidad al ofrecernos prácticamente las mismas funciones previstas para la versión 2, y alguna más 🙂

xVal es un framework para aplicaciones ASP.NET MVC 1.0 (y superiores) creado por Steve Sanderson, y presentado en sociedad el pasado 17 de septiembre, que permite validar la información almacenada en clases del modelo, tanto en el lado cliente como en servidor, de forma automatizada.

Su diseño es muy flexible, permitiéndonos elegir entre distintos marcos de trabajo para la validación en servidor (de serie soporta los atributos DataAnnotations, Castle Validator y NHibernate Validator, aunque se pueden crear proveedores personalizados) y librerías en cliente (inicialmente utiliza el magnífico plugin jQuery Validation).

Vamos a ver, paso a paso, cómo podemos comenzar a utilizarlo de forma inmediata en nuestras aplicaciones ASP.NET MVC 1.0, utilizando las restricciones DataAnnotations y la librería de validación para jQuery citada anteriormente.

1. Preparamos la infraestructura

En primer lugar, vamos a preparar el entorno para utilizar el framework de validación:

  1. Descargamos xVal desde CodePlex. Se distribuye en un fichero .zip que incluye tanto el ensamblado como archivos de soporte, así que lo descomprimimos en cualquier parte para tener los archivos a mano.
  2. Descargamos el plugin de validación de jQuery, por ejemplo, desde el CDN de Microsoft (¿qué es el Microsoft Ajax CDN?) y lo incluimos en la carpeta /scripts de nuestro proyecto. Otra posibilidad sería no descargarlo y referenciarlo directamente nuestras páginas, a gusto del consumidor 😉
  3. Añadimos a la carpeta /scripts del proyecto la librería xVal.jQuery.Validate.js presente en el raíz del comprimido de xVal. Este archivo, junto con el anterior, son imprescindibles para montar la validación automática en el lado cliente que veremos más adelante. Además, para que los mensajes aparezcan en nuestro idioma, copiamos también al mismo sitio el archivo xVal.Messages.es-ES.js, disponible en la carpeta “internationalization” del zip.
  4. Copiamos al directorio /bin de nuestra aplicación el ensamblado xVal.dll, o simplemente añadimos una referencia en el proyecto hacia dicho archivo, que encontraréis en el raíz del fichero comprimido que hemos descargado en primer lugar.
  5. Retocamos ligeramente el Web.config de nuestro proyecto para que sea incluido automáticamente el espacio de nombres xVal.Html en nuestras vistas, facilitando así el acceso a los helpers suministrados:
    <system.web>

      <pages>

         <namespaces>

            <!-- Añadir la siguiente línea -->

            <add namespace="xVal.Html"/>

        </namespaces>

      </pages>

    </system.web>

Los pasos comentados hasta el momento son genéricos, es decir, tendremos que realizarlos en todos los proyectos en los que vayamos a utilizar este framework de validación. Podría ser interesante, por tanto, crearnos una plantilla de proyecto en la que tengamos ya todo este trabajo realizado.

Diálogo 2. Definimos las restricciones con Data Annotations

Ahora vamos a definir, de forma declarativa, las restricciones que queremos imponer a las propiedades de las clases del modelo, utilizando los atributos denominado data annotations, distribuidos con .NET 3.5 y originalmente diseñados para trabajar con la tecnología Dynamic Data.

  1. Dado que vamos a declarar las restricciones utilizando los atributos data annotations, hay que añadir referencia en el proyecto a  System.ComponentModel.DataAnnotations.
  2. A continuación, tenemos que incluir en el proyecto un método que nos permita recorrer las anotaciones de las clases, ejecutarlas e ir generando los errores apropiadamente.  Este método lo utilizaremos más adelante, desde los componentes del Modelo, para comprobar si los valores presentes en las propiedades cumplen los requisitos impuestos por el dominio del sistema.

    El código es muy sencillo, el propio Sanderson nos facilita uno en el proyecto de demostración de xVal, que podéis copiar y pegar:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using xVal.ServerSide;

    using System.ComponentModel.DataAnnotations;

    using System.ComponentModel;

     

    namespace MyProject.Validation

    {

     public static class DataAnnotationsValidationRunner

     {

      public static IEnumerable<ErrorInfo> GetErrors(object instance)

      {

        var metadataAttrib = instance.GetType()

                                .GetCustomAttributes(typeof(MetadataTypeAttribute), true)

                                .OfType<MetadataTypeAttribute>().FirstOrDefault();

     

        var buddyClassOrModelClass = metadataAttrib != null ? 

                                        metadataAttrib.MetadataClassType:

                                        instance.GetType();

     

        var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass)

                                .Cast<PropertyDescriptor>();

     

        var modelClassProperties = TypeDescriptor.GetProperties(instance.GetType())

                                .Cast<PropertyDescriptor>();

     

        return from buddyProp in buddyClassProperties

                   join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name

                   from attribute in buddyProp.Attributes.OfType<ValidationAttribute>()

                   where !attribute.IsValid(modelProp.GetValue(instance))

                   select new ErrorInfo(

                                buddyProp.Name, 

                                attribute.FormatErrorMessage(string.Empty), instance);

      }

     }

    }

    Ojo, esto sólo tenemos que hacerlo cuando estemos utilizando DataAnnotations, como es el caso; si utilizamos otros frameworks como el de Castle o NHibernate no será necesario, puesto que incluyen ya implementaciones para realizar esta tarea.

  3. Marcamos las propiedades de la entidad del modelo con las restricciones a aplicar durante la validación. Podemos utilizar los atributos disponibles para restringir los valores permitidos en cada propiedad como Required , StringLength , Range  y otros (puedes ver la relación completa aquí).

    Un ejemplo podría ser el siguiente, en el que vemos varias restricciones aplicadas a las propiedades de la entidad:

    public class Recluta

    {

        [Required, StringLength(30)]

        public string Nombre { get; set; }

     

        [Required, StringLength(40)]

        public string Apellidos { get; set; }

     

        [Required, Range(1, 4)]

        public int Talla { get; set; }

     

        [Required, DataType(DataType.Date)]

        public DateTime FechaNacimiento { get; set; }

    }

    Sin embargo, muchos os preguntaréis qué ocurre cuando estas entidades de datos las generamos con herramientas automáticas, como el diseñador de Entity Framework. En estos casos, cada vez que generemos el modelo, las clases serían machacadas por las nuevas versiones, y nuestras anotaciones pasarían a mejor vida.

    Afortunadamente, existe la posibilidad de declarar una clase paralela (o, como la llaman, ‘buddy class’), en la que definiremos exclusivamente las propiedades a las que queremos añadir alguna anotación. Además, marcaremos la entidad original (aprovechando que la mayoría de estas herramientas automáticas las generan como parciales) indicando la clase que contiene los metadatos asociados a ésta:

    // Indicamos en la entidad original que los

    // metadatos se encuentran en 'ReclutaMedata'

    [MetadataType(typeof(ReclutaMetadata))]

    public partial class Recluta

    { 

        // Nada más que añadir aquí

    }

     

    // Definimos los metadatos para la entidad 'Recluta'

    public class ReclutaMetadata

    {

        [Required, StringLength(30)]

        public string Nombre { get; set; }

     

        [Required, StringLength(40)]

        public string Apellidos { get; set; }

     

        [Required, Range(1, 4)]

        public int Talla { get; set; }

     

        [Required, DataType(DataType.Date)]

        public DateTime FechaNacimiento { get; set; }

    }

    Como podéis observar, la entidad y la clase de metadatos son prácticamente iguales. Un poco anti-DRY sí que es, pero bueno.

3. Validamos en servidor

La propuesta de xVal para el lado del servidor consiste en desplazar la lógica de validación al modelo, dado que es éste el que normalmente impone las restricciones en los datos que han de estar presentes en las entidades del dominio. Una forma de realizarlo sería así:

  • por cada entidad, creamos un método que valide la información del mismo, primero invocando al ValidationRunner (el proceso de validación basado en anotaciones descrito anteriormente), y luego añadiendo aquellas reglas de negocio no incluidas en dichas anotaciones). Un ejemplo podría ser el siguiente:
    private void validar(Recluta recluta)

    {

        var errors = DataAnnotationsValidationRunner.GetErrors(recluta);

        if (errors.Any())

            throw new RulesException(errors);

     

        // Regla de negocio adicional: prohibido alistarse reclutas

        // con hermanos en el cuartel...

        if (tieneHermanos(recluta.Apellidos))

        {

            throw new RulesException("Apellidos",

                        "El recluta tiene hermanos ya alistados", recluta);

        }

    }

     
    Este método podría incluirse en la propia entidad Recluta, o bien donde se implemente la lógica de negocio asociada a la misma.
     
    En cualquier caso, como se puede observar, cuando se producen errores debido a un incumplimiento de las restricciones indicadas en las anotaciones, se lanza una excepción de tipo RulesException (facilitada por xVal) que contiene una descripción de los problemas encontrados. Asimismo, la existencia de otro tipo de problemas, hallados de forma programática, son lanzados también en una excepción del mismo tipo.
     
  • antes de realizar operaciones susceptibles de modificar el estado del sistema, tenemos que asegurarnos de que las entidades son válidas. Observad, por ejemplo, la implementación del método que nos permite añadir un recluta al sistema:
    public void Crear(Recluta recluta)

    {

        validar(recluta);

        reclutas.Add(recluta);

    }

    Si se producen errores en la validación, el método Crear() será interrumpido por la excepción RulesException lanzada desde validar(), y llegará finalmente hasta el Controlador, donde deberá ser procesada. 

  • desde el punto de vista del Controlador, podremos comprobar que el patrón a seguir es realmente sencillo, pues toda la lógica de validación la hemos desplazado al modelo.

    El siguiente código muestra los métodos de acción asociados a la creación de una entidad; el primero de ellos simplemente se encarga de mostrar la vista de edición sobre un objeto recién creado, mientras que el segundo obtiene los datos del recluta desde el formulario, e intenta realizar la operación de creación sobre el modelo:

    public ActionResult Create()

    {

        return View(new Recluta());

    }

     

    [AcceptVerbs(HttpVerbs.Post)]

    public ActionResult Create(Recluta recluta)

    {

        try

        {

            gestorDeReclutas.Crear(recluta);

        }

        catch (RulesException ex)

        {

            ex.AddModelStateErrors(this.ModelState, "");

        }

        if (!ModelState.IsValid)

            return View(recluta);

        else 

            return RedirectToAction("Index");

    }

    Como se puede observar, se capturan las excepciones de validación que se produzcan al realizar el alta, añadiendo al ModelState los errores que se estén informando en éstas y, en función de la validez de los datos, enviando al usuario a la vista correspondiente.
Y esto es todo. Con estas operaciones, ya tenemos las validaciones listas en el lado del servidor, pasemos ahora a solucionarlas en cliente.

4. Validamos en el cliente

Está claro que la validación en el lado del servidor es la que única que debemos hacer obligatoriamente; el lado cliente es sensible al equipo del usuario, que puede estar accediendo desde dispositivos sin javascript (o con esta característica desactivada), o incluso puede ser fácilmente manipulado, por lo que no podemos confiar en que los datos lleguen ya siendo válidos.

Sin embargo, ofrecer validación en cliente es una característica imprescindible hoy en día vistas a realizar interfaces muy usables, capaces de ofrecer al usuario feedback inmediato sobre sus acciones.

Con xVal, añadir en este punto validaciones en cliente es realmente sencillo, pues ya tenemos realizado prácticamente todo el trabajo, quedando simplemente:

  1. incluir las librerías script en las vistas donde vayamos a realizar la edición de las entidades del modelo. Si vamos a utilizarlas en muchos sitios, lo más fácil es añadirlas a la página maestra:
    <script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>

    <script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script>

    <script src="../../Scripts/xVal.jquery.validate.js" type="text/javascript"></script>

    <script src="../../Scripts/xVal.Messages.es-ES.js" type="text/javascript"></script>

  2. generar en la vista los scripts de validación de las entidades que nos interesen. En el siguiente código generamos la lógica para la entidad Recluta:
     
    <%= Html.ClientSideValidation<MiProyecto.Models.Recluta>() %>

        

5. ¡Y hasta aquí hemos llegado!

A lo largo de este post hemos recorrido los pasos necesarios para echar a andar el framework xVal en una aplicación ASP.NET MVC 1.0.

Faltan muchos aspectos por comentar, como la posibilidad de utilizar validaciones Ajax en servidor, permitir la localización en decimales, escribir nuestros propios atributos de anotaciones, etc., pero creo que este post ya es lo suficientemente extenso… ya lo veremos en otra ocasión.

Puedes descargar el proyecto de demostración desde Skydrive:

Publicado en: Variable not found.

Eliminar los encabezados X-AspNet* de las respuestas en ASP.NET MVC (y ASP.NET)

 

Si observamos las respuestas enviadas al cliente que solicita una página de un sitio web creado con el framework MVC, veremos que, además de los encabezados HTTP estándar, el sistema añade información sobre las versiones de ASP.NET y del propio framework MVC que estamos utilizando:

Encabezados X-ASPNet*

Esta información, además de consumir ancho de banda (poco, todo hay que decirlo, pero nada despreciable en sitios con tráfico muy alto), aportan información que posibles atacantes podrían utilizar para sacar provecho a vulnerabilidades conocidas de estos productos. En mi opinión, lo mejor es mostrar los menores detalles posibles al respecto.

Si queremos eliminar la pista correspondiente a la versión de ASP.NET sobre la que corre el sistema (X-AspNet-Version), bastaría con introducir en el web.config la siguiente declaración:

<configuration>

    <system.web>

        <httpRuntime enableVersionHeader="false" />

    </system.web>

</configuration>

Para eliminar, además, la información sobre la versión de ASP.NET MVC framework en ejecución (X-AspNetMvc-Version), tendremos que introducir el siguiente código para que se ejecute durante la inicialización de la aplicación, en el global.asax, indicando así que deseamos deshabilitar el envío de este encabezado:

protected void Application_Start()

{

    [...] // Otro código de inicialización

    MvcHandler.DisableMvcResponseHeader = true;

}

Y con eso basta. El resultado, el que sigue:

Encabezados sin información extra

Publicado en: Variable not found.

Fluent NHibernate 1.0 publicado

A finales del agosto, James Gregory anunció la publicación de la versión 1.0 de Fluent NHibernate, una librería que ofrece una ágil alternativa a los espesos archivos de configuración de NHibernate.

Su API permite configurar desde el código de una aplicación, de forma fluida la mayoría de las veces, los mapeos entre la estructura de una base de datos relacional y el modelo de objetos que utiliza. Así, evitaremos la manipulación de grandes archivos XML, a la vez que podremos beneficiarnos de la validación en tiempo de compilación y, por supuesto, de posibilidades como la refactorización y el intellisense durante el desarrollo.

El siguiente código muestra el mapeo de la entidad Cat con sus propiedades, algunas de ellas con restricciones, y relaciones con otras entidades a uno (References) y a varios (HasMany); el nombre de la tabla y campos en el modelo relacional es el mismo que el de las propiedades, gracias a la convención sobre configuración, lo que permite simplificar código respecto a su equivalente XML:

public class CatMap : ClassMap<Cat>

{

  public CatMap()

  {

    Id(x => x.Id);

    Map(x => x.Name)

      .Length(16)

      .Not.Nullable();

    Map(x => x.Sex);

    References(x => x.Mate);

    HasMany(x => x.Kittens);

  }

}

Como podemos observar, el equivalente XML es mucho más verboso:

<?xml version="1.0" encoding="utf-8" ?>  

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  

  namespace="QuickStart" assembly="QuickStart">  

 

  <class name="Cat" table="Cat">  

    <id name="Id">  

      <generator class="identity" />  

    </id>  

 

    <property name="Name">  

      <column name="Name" length="16" not-null="true" />  

    </property>  

    <property name="Sex" />  

    <many-to-one name="Mate" />  

    <bag name="Kittens">  

      <key column="mother_id" />  

        <one-to-many class="Cat" />  

      </bag>  

  </class>  

</hibernate-mapping>

Otra de las ventajas que aporta es el auto-mapping, que hace utilización intensiva del principio de convención sobre configuración para generar de forma automática mapeos de aquellas entidades que atiendan a unas normas preestablecidas (aunque modificables). El siguiente código muestra la forma tan sencilla de crear los mapeos de todas las entidades definidas en el espacio de nombres MiApp.Entidades, dentro del ensamblado donde se definió la entidad Producto:

var autoMappings = AutoMap.AssemblyOf<Producto>()

  .Where(t => t.Namespace == "MiApp.Entidades");

Además del mapeo objeto-relacional, el software abarca también la configuración del acceso a datos de NHibernate a través de su interfaz de programación. El siguiente código muestra la inicialización de la conexión a una base de datos SQL Server 2005, tomando la cadena de conexión del AppSettings y mapeando automáticamente las entidades que se encuentren definidas en un namespace concreto:
 
var sessionFactory = Fluently.Configure()

    .Database(MsSqlConfiguration.MsSql2005

      .ConnectionString(c => c.FromAppSetting("connectionString"))

    .Mappings(m => m.AutoMappings.Add(

      AutoMap.AssemblyOf<Producto>(type => type.Namspace.EndsWith("Entidades"))))

  .BuildSessionFactory();

Y por último, hay otra característica muy interesante vistas a la realización de pruebas unitarias sobre los mecanismos de persistencia. El código mostrado a continuación crea una instancia de la clase Empleado, la inserta en la base de datos, realiza una lectura de la entidad y la compara con la original, de forma automática:

[Test]

public void EmpleadoMapeaCorrectamente()

{

    new PersistenceSpecification<Empleado>(session)

        .CheckProperty(emp => emp.Id, 1)

        .CheckProperty(emp => emp.Nombre, "José")

        .CheckProperty(emp => emp.Apellidos, "Aguilar")

        .VerifyTheMappings();

}

Más información en la wiki del proyecto. Y las descargas, desde aquí.

Publicado en: Variable not found.

Grabación y materiales de la charla sobre MVC

 

Presentación ASP.NET MVCPues eso, que ya están disponibles para su descarga tanto la grabación del evento como los materiales utilizados durante la charla de ayer, organizada por Second Nug, en la que realizamos una introducción al framework ASP.NET MVC.

En los materiales se incluye tanto el PPT utilizado en la primera parte de la presentación como el código del proyecto que desarrollamos durante la segunda parte, el famoso sistema Aúpa!net ;-), en forma de solución para Visual Web Developer Express 2008 (SP1). Recordad que para poder ejecutarlo y jugar con él necesitáis instalar previamente ASP.NET MVC 1.0.

Gracias a todos los que pudisteis asistir al evento en directo (y en especial, los que aguantasteis hasta el final como auténticos campeones ;-)) … bueno, y a los que asistiréis aunque sea off-line ;-P

Enlaces:

Acceder a la grabación del evento

Descarga de materiales (.zip)

Publicado en: Variable not found.

Recordatorio: mañana, ¡a por ASP.NET MVC!

Sólo recordaros que mañana martes 6, a las 19:30 (GMT+2), estaré charlando sobre ASP.NET MVC en el evento on-line organizado por Second Nug.

Durante las dos horas de duración previstas veremos cómo crear una aplicación web completa con esta tecnología alternativa a Webforms, mientras vamos comentando técnicas, detalles y aspectos a tener en cuenta al desarrollar con ASP.NET MVC.

image

Nos os la perdáis, eh?! 😉

Enlaces:

Publicado en: Variable not found

Publicada la segunda preview de ASP.NET MVC 2

 

image Ayer mismo anunciaba Phil Haack la publicación de la segunda preview de ASP.NET MVC 2, que continúa profundizando en las mejoras que ya se incluyeron en la primera entrega.

Según se recoge en el documento de notas del producto, las novedades que podremos encontrar son:

  • Abstracción del proveedor de metadatos, que será útil para implementar nuestros propios sistemas de obtención de metainformación sobre las clases del modelo, aunque por defecto se utilizarán los atributos presentes en System.ComponentModel.DataAnnotations.
  • Abstracción del proveedor de validaciones del modelo, que nos permitirá utilizar mecanismos personalizados de validación durante el proceso de binding, que por defecto utilizará también las DataAnnotations.
  • Validación automática en cliente, que aunque permite la utilización de otros frameworks, la implementación por defecto utiliza el plugin jQuery Validation para generar en cliente la lógica de validación descrita en los metadatos de las propiedades del modelo. De momento, soporta las siguientes DataAnnotations:
    • StringLengthAttribute, para limitar el tamaño máximo de un campo texto.
    • RequiredAttribute, para indicar la obligatoriedad de introducir un valor.
    • RegexAttribute, que añade la restricción de obligado cumplimiento de la expresión regular indicada.
    • RangeAttribute, para especificar el rango de valores de un campo (por ejemplo, un entero).

    Dado que el model binder implementa las validaciones en servidor, parece que vamos en camino para ahorrarnos el trabajo sucio 🙂

  • Inclusión del filtro RequireHttpsAttribute, que aplicado a una acción, fuerza a que ésta sea invocada utilizando el protocolo HTTPS.
  • Inclusión del helper Html HttpMethodOverride, que permite sobrescribir el verbo HTTP enviado por el cliente en aquellos agentes de usuario que no soportan los verbos menos frecuentes (PUT, DELETE…), introduciendo un campo oculto que es detectado posteriormente.
  • Posibilidad de incluir áreas en un proyecto único, es decir, sin necesidad de crear proyectos independientes, facilitando además el registro de las mismas.
  • El atributo HiddenInputAttribute permite ahora especificar propiedades del modelo que deben ser renderizadas en cliente con un campo hidden.
  • Y otras mejoras, de las que selecciono sólo algunas:
    • Controller.Execute() lanzará una excepción cuando sea llamado más de una vez en la misma instancia. Dado que una instancia del controlador debe atender exclusivamente a una petición, es una medida que ayuda a prevenir problemas con contenedores IoC configurados para generar singletons, por ejemplo.
    • Inclusión de nuevos verbos HTTP, como PUT o DELETE para facilitar la creación de sistemas REST.
    • Soporte para el tipo de datos DataType.Password, haciendo que se rendericen como cuadros de edición de tipo password las propiedades que sean marcadas con este atributo.
    • Se ha establecido como editor para los booleanos anulables un desplegable con las opciones “No especificado”, “Sí” y “No”.
    • Mejoras de eficiencia, introduciendo una caché de expresiones compiladas para los helpers que utilizan sintaxis lambda fuertemente tipada.
    • (Podéis ver el resto en el documento de notas del producto).

De momento todavía no funciona con la beta de Visual Studio 2010, sólo con las versiones 2008 convenientemente servicepackeadas.

Enlaces:

Publicado en: Variable not found.