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!
domingo, 14 de marzo de 2010
ASP.NET MVC Estando todavía calentito el horno del que acaba de salir ASP.NET MVC 2, es curioso conocer algo sobre el próximo plato que están preparando Haack y su equipo: ¡ASP.NET MVC 3!

Ya se han publicado algunas de las líneas y objetivos que guiarán los futuros desarrollos y determinados detalles que probablemente serán incluidos, aunque obviamente todavía pueden variar sustancialmente. Las principales áreas de atención son en estos momentos:
  • aumentar la productividad de los desarrolladores,
  • facilitar aún más el uso de Ajax,
  • incluir mejoras arquitecturales,
  • y aumentar el rendimiento.
El aumento de productividad irá ligado a la introducción de un nuevo conjunto de helpers destinados a realizar tareas muy comunes en el desarrollo de aplicaciones web, como la implementación de rejillas de datos (grids) paginados.

Asimismo, se dará soporte a nuevos atributos de validación además de los ya incluidos en las anotaciones de datos de ASP.NET 4.

Otra línea en estudio es la introducción de herramientas basadas en línea de comandos, alternativas a las incluidas en Visual Studio.

Para facilitar el uso de Ajax se introducirán nuevos helpers que simplifiquen la implementación de escenarios habituales, como los controles de selección de fecha o cuadros de edición con auto-completado.
También se considera interesante ampliar los helpers existentes para permitir la actualización parcial de varias zonas de la página, e incluir soporte para plantillas en cliente, que permitan añadir el marcado muy rápidamente a datos retornados en formato JSON desde el controlador.

Desde el punto de vista arquitectural, se planea seguir flexibilizando el framework, permitiendo nuevos puntos de inyección de dependencias, como la instanciación de clases del Modelo desde el binder, o en filtros de acción.Piezas de un sistema

Se prevé también la creación de una factoría de controladores para MEF (Managed Extensibility Framework) que permitan ampliar las funcionalidades de un sistema mediante sus sencillos mecanismos de extensibilidad, sin necesidad de recompilar.

Se incrementarán también las herramientas de generación de andamiaje de aplicaciones, para acelerar la implementación de escenarios comunes, como los habituales CRUD.

Y respecto al rendimiento, el equipo está estudiando nuevas técnicas para mejorar el cacheo de respuestas, y soluciones como aumentar el control sobre el estado de sesión, permitiendo activarlo o desactivarlo para mejorar la eficiencia.

En cualquier caso, lo que sí ha dejado claro Phil es que ASP.NET MVC 2 será la última versión del framework con soporte para ASP.NET 3.5 SP1.

Fuente: Roadmap de ASP.NET MVC.
Publicado en: Variable not found.
Hey, ¡estoy en twitter!
jueves, 11 de marzo de 2010
¡ASP.NET MVC 2! Hace unos minutos en Twitter se propagaba la noticia de la disponibilidad de la versión final de ASP.NET MVC 2, que puedes descargar ya desde el sitio web de Microsoft.

Según se indica en el documento de notas de la revisión, y como era previsible, no se puede instalar en equipos con Visual Studio 2010 RC. Por lo demás, no se ha introducido ningún cambio destacable desde la anterior revisión, la segunda Release Candidate.

También se ha publicado el código fuente en CodePlex.


Publicado en: Variable not found.
martes, 9 de marzo de 2010
ASP.NET MVC 2El framework ASP.NET MVC 2 ha introducido un nuevo filtro llamado ChildActionOnly que, como su nombre indica, impide la ejecución del método de acción sobre el que se aplica, a menos que se trate de una “acción hija”.

Supongamos el siguiente código en el controlador, digamos, HomeController:

[ChildActionOnly]
public ActionResult Menu()
{
   Menu mnu = getMenuForThisUser();
   return PartialView(mnu);
}

imageAtendiendo a la ruta por defecto, una petición del tipo GET /Home/Menu generará una excepción, como la mostrada en la captura de pantalla adjunta.

¿Y qué significa eso en la práctica? Pues básicamente que la acción sólo puede ser invocada desde una vista utilizando los métodos Html.Action() y Html.RenderAction().

Ambos métodos, aunque formaban parte del ensamblado futures desde hace algún tiempo, han sido por fin incluídos en MVC 2, y están destinados a introducir en la vista actual el resultado de la ejecución de una “acción hija”, por ejemplo así:

<div id="mainMenu">
   <%= Html.Action("Menu") %>
</div>

La diferencia entre ambos es que Html.Action retorna un string con el resultado de la ejecución de dicha acción, mientras que Html.RenderAction() escribirá directamente la respuesta sobre el canal de salida (Response).

Publicado en: Variable not found.
Hey, ¡estoy en twitter!
domingo, 7 de marzo de 2010
ASP.NET MVC Esta es una respuesta rápida a una cuestión de Fred C., que me llega vía formulario de contacto en Variable not found, sobre un problemilla que también sufrí en algunas ocasiones, y he pensado que posiblemente pueda interesarle a alguien más, así que ahí va.

El escenario es el siguiente: tenemos en una vista un código para generar un enlace hacia una acción, como el mostrado a continuación:

<%= Html.ActionLink("Acceso externo",    // Texto del enlace
                    "Editar",            // Acción
                    "Productos",         // Controlador
                    new { id=Model.Id }) // Parámetros
%>

ActionLink() generanAl mostrarse la vista, ya en tiempo de ejecución, nos encontramos con que no se ha generado el enlace que pretendíamos, sino uno como el mostrado en la captura de pantalla adjunta, hacia la dirección/Home/Editar?Length=9.

En primer lugar, utilizando la ruta por defecto, vemos nos está llevando hacia el controlador “Home”, ¿pero no le habíamos dicho que era “Productos”?

Y en segundo lugar, ¿dónde está nuestro parámetro id? ¿De dónde sale ese parámetro Length con el valor 9?

La respuesta a este problema es bien sencilla aunque al principio puede provocarnos algún dolor de cabeza: estamos utilizando una sobrecarga incorrecta del método ActionLink().

Si observamos las distintas sobrecargas de este método, podremos comprobar que sólo una de ellas tiene una signatura compatible con la llamada que estamos utilizando:

public static string ActionLink(
    this HtmlHelper htmlHelper,
    string linkText,
    string actionName,
    object routeValues,
    object htmlAttributes
)
Así, cuando en el código anterior estábamos pasando al método el nombre del controlador, en realidad lo que hacíamos era indicarle los parámetros de la llamada. Eso explica el parámetro Length=9 en la URL: dado que le enviamos un string de 9 caracteres, simplemente se trata de una serialización de sus propiedades.

Y, por tanto, los parámetros de la llamada que estábamos especificando, lo hacíamos como parte de los atributos HTML. De hecho, si analizamos el código fuente de la página generada, encontramos que el parámetro “id” ha sido introducido como un atributo HTML del enlace:

<a href="/Home/Editar?Length=9" id="8">Editar este producto</a>

La forma de solucionarlo es bien fácil, sólo hay que utilizar la sobrecarga apropiada, como:

<%= Html.ActionLink("Editar este producto", 
            "Editar",                     // Acción
            new {                         // Parámetros
            controller="Productos", 
            id=Model.Id 
}
) %> 
 
// O Bien:
 
<%= Html.ActionLink(
             "Editar este producto", 
             "Editar",               // Acción  
             "Productos",            // Controlador
             new { id=Model.Id },    // Parámetros
             null                    // Atributos HTML
) %> 

En fin, que se trata de un pequeño despiste a la hora de codificar, propiciado a veces por la gran cantidad de sobrecargas y la información, algo confusa, ofrecida por Intellisense que nos puede hacer perder unos minutos muy valiosos.

¡Gracias, Fred, por participar en Variable not found!
Por cierto, ¡estoy en Twitter!
lunes, 1 de marzo de 2010
BaseKit Los chicos de BaseKit me han invitado, bueno, y a 20 de vosotros también ;-), a probar su nueva herramienta, actualmente en fase de beta privada (si quieres conseguir un pase, lee el final del post).

BaseKit es una aplicación totalmente on-line que permite a diseñadores crear sitios web completos sin necesidad de tener conocimientos de HTML, javascript y, si apuramos, incluso ni de CSS, rompiendo así la brecha que tradicionalmente divide el mundo del diseño y del desarrollo web.

Otra ventaja para los que no se sienten cómodos lidiando con compañías de hosting es que el servicio cuenta con su propio alojamiento; en un par de clicks, el sitio web que estemos editando pasará a estar disponible en internet. De hecho, el alojamiento será el único concepto por el que BaseKit cobrará a los usuarios en el futuro.

Crear nuevo sitio web en basekitLa primera prueba de la facilidad con la que se pueden crear sitios web la encontramos al comenzar a trabajar con BaseKit, cuando tendremos que decidir cómo queremos crear el sitio web: importando un archivo Photoshop, seleccionando una plantilla base predefinida, o basándonos en un sitio disponible en la galería.

La primera opción permite subir directamente archivos en formato PSD cuyos contenidos y estructura serán utilizados para generar automáticamente la plantilla de la página.

Las siguientes opciones permiten tirar de elementos prediseñados, como plantillas o incluso sitios web completos, disponibles en la galería de BaseKit. Estas galerías todavía no ofrecen gran cantidad de elementos prediseñados, pero se entiende que es debido a que el producto está aún en fase de pruebas.

En cualquier caso, independientemente del modo de inicio lo que tendremos a continuación es un completo editor en el que podremos editar la página de forma visual, en plan drag&drop, de forma realmente sencilla.

De momento hay un buen número de widgets con los que crear los contenidos de la página, y obviamente tienen planes de seguir añadiendo nuevas posibilidades.

Editor de BaseKit

La siguiente captura muestra la página “Variable not found en BaseKit”, creada en sólo unos minutos, donde se integra información procedente de feeds RSS, Twitter, imágenes de Flickr, Google Maps, e incluso vídeos embebidos:
Variable not found en Basekit
Bueno, pues como ya hice en otras ocasiones, los 20 primeros usuarios que me hagan llegar su dirección de correo electrónico vía comentario a este post, formulario de contacto, Twitter, Facebook, o en persona ;-), tendrán acceso durante 30 días para publicar todas las páginas que deseen, con hosting gratuito durante todo el 2010.

Para las pruebas debes utilizar Firefox 3.5.5 o superior; de momento BaseKit no soporta IE, aunque están trabajando en ello.

¡Venga, os espero!

Publicado en: Variable not found.
lunes, 22 de febrero de 2010
ASP.NET MVC 2 El sistema de validaciones integrado en ASP.NET MVC 2, basado en la especificación de restricciones utilizando los atributos definidos en el espacio de nombres System.ComponentModel.DataAnnotations, permite la introducción de mensajes de error personalizados, como en el siguiente ejemplo:

[Range(100, 230, ErrorMessage="La altura debe estar comprendida entre {1} y {2}")]
public double Height { get; set; }

Y otra posibilidad es externalizar estos mensajes a archivos de recursos, y crear versiones localizadas de los mismos:

[Required(
    ErrorMessageResourceName="CampoObligatorio",
    ErrorMessageResourceType = typeof(Resources.Mensajes))]
public string Name { get; set; }

De esta forma, todos los atributos mediante los cuales podemos indicar restricciones del modelo permiten la especificación de un mensaje de error descriptivo.

Sin embargo, hay dos tipos de errores de validación en los que no es tan obvia la forma de indicar el texto del mensaje, debido a que no se generan por restricciones especificadas en atributos, sino basados en el tipo de la propiedad.

Por ejemplo, supongamos el siguiente código, perteneciente a una entidad de datos:

public class Entidad
{
  public DateTime Fecha { get; set; }
  public int Numero { get; set; }
}

Aunque no hayamos indicado ninguna anotación que limite el contenido de sus dos propiedades, sí que existen de forma implícita dos condicionantes: el primero de ellos, que al tratarse de tipos valor no se admitirán valores nulos (o vacíos, a nivel de controles de formularios); y el segundo, que los valores introducidos deben ser convertibles a los tipos DateTime e int, respectivamente.

La siguiente captura de pantalla muestra un formulario de edición de la entidad en los que se han producido estos errores de validación:

Editando la entidad

Propiedades implícitamente obligatorias

El mensaje “The XX field es required” es el texto de error por defecto para las propiedades de tipo valor, implícitamente obligatorias, y es el mismo que aparece cuando utilizamos la anotación [Required] sin especificar ningún mensaje de validación.

Para modificarlo basta decorar la propiedad con dicho atributo y especificar en él el contenido del mensaje, o la forma de localizar el texto en los recursos de la aplicación, de la misma forma que haríamos con un tipo referencia, como un string.

public class Entidad
{
   [Required(ErrorMessage = "Campo obligatorio")]
   public DateTime Fecha { get; set; }
 
   [Required(ErrorMessage = "Campo obligatorio")]
   public int Numero { get; set; }
}

Dado que este código es algo anti-DRY, todavía podemos mejorarlo un poco creando nuestro propio atributo personalizado:

public class Entidad
{
   [Requerido]
   public DateTime Fecha { get; set; }
 
   [Requerido]
   public int Numero { get; set; }
}
 
public class RequeridoAttribute : RequiredAttribute
{
   public RequeridoAttribute()
   {
      this.ErrorMessage = "Campo obligatorio";
   }
}

¿Problemas con el cambio de tipo?

El otro error, “The value XX is not valid for YY”, es algo más complicado  dado que no existe ningún atributo en el que podamos indicar de forma explícita el mensaje a utilizar, como hemos hecho en el caso anterior.

Para sustituir el mensaje por defecto es necesario utilizar un archivo de recursos en el que tendremos que introducir el texto que queramos utilizar en estos casos. Para ello, añadiremos en primer lugar una carpeta de recursos globales:

Añadir una carpeta de recursos globales

Y en su interior un archivo de recursos, llamado por ejemplo Mensajes.resx, en el que introducimos un string con el nombre PropertyValueInvalid, cuyo valor será el mensaje de error que queremos mostrar cuando se produzca un error de conversión:

PropertyValueInvalid

Observad que el interior del mensaje {0} será sustituido por el valor incorrecto, y {1} por la descripción de la propiedad que está generando el error.

El último paso para que ASP.NET MVC framework reconozca dónde debe buscar este recurso es indicar en la inicialización de la aplicación el nombre del archivo (o clase) que lo contiene:

 
protected void Application_Start()
{
   ... // Otras inicializaciones
 
   DefaultModelBinder.ResourceClassKey = "Mensajes";
}

Tras aplicar estos cambios, si ejecutamos la aplicación podremos comprobar que hemos conseguido nuestros objetivos:

Validaciones con mensajes personalizados


Publicado en: Variable not found
Hey, ¡estoy en Twitter!