lunes, 27 de enero de 2014

Personalizar plantillas MVC que usa Visual Studio

A día de hoy Visual Studio incorpora plantillas que facilitan bastante el trabajo a la hora de generar controladores y vistas en un proyecto MVC. Estas plantillas en algunos casos permiten asociar un modelo y generan código a partir de los atributos de dicho modelo (scaffolding). Por ejemplo al crear un nuevo controlador, el asistente de Visual Studio nos deja seleccionar diferentes tipos.

Customizar plantillas MVC Visual Studio


El archivo que se genera ya incorpora los métodos para las acciones de listar, editar, crear y eliminar elementos. Por defecto crea los métodos con la firma pero sin implementar.

    public class AreaTICController : Controller
    {
        //
        // GET: /AreaTIC/
        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /AreaTIC/Details/5
        public ActionResult Details(int id)
        {
            return View();
        }

        //
        // GET: /AreaTIC/Create
        public ActionResult Create()
        {
            return View();
        }

     [...]
Editar estas plantillas puede sernos muy útil para unificar criterios de desarrollo entre el equipo y evitar tener que picar código cada vez que creamos un nuevo apartado. Se podría llegar a crear un controlador que ya incorpore código para el control de errores, paginación de las listas, acceso a datos, etc... Ídem con las plantillas de vistas, puede sernos muy útil personalizarlas.

A continuación veremos como editar estas plantillas para nuestro proyecto.

1) Crearemos dentro del proyecto MVC una carpeta CodeTemplates.

2) Buscamos las plantillas al directorio donde está instalado Visual Studio en la máquina. Lo más sencillo para localizar la plantilla que necesitamos es fijarnos en el identificador para el tipo de plantilla al crear el elemento con el asistente de Visual Studio. Por ejemplo para el controlador que he añadido en el ejemplo el identificador es MVCControllerWithActions (sin el Scaffolder).

Customizar plantillas MVC Visual Studio


3) Copiamos la carpeta entera en CodeTemplates que hemos creado en el primer paso. Si nos fijamos en el contenido de la carpeta hay 2 archivos con extensión ".t4". Uno contiene código c# y el otro vb. En mi caso, una vez copiada la carpeta a CodeTemplates elimino el .vb y me quedo con el .cs dentro de mi proyecto.

4) Editamos el archivo controller.cs.t4 añadiendo un parámetro string page al método Index().
namespace <#= Namespace #>
{
    public class <#= ControllerName #> : Controller
    {
        //
        // GET: <#= (!String.IsNullOrEmpty(AreaName)) ? ("/" + AreaName) : String.Empty #>/<#= ControllerRootName #>/
        public ActionResult Index(string page)
        {
            return View();
        }

   [...]
Con esto ya tendríamos la plantilla editada, Visual Studio antes de buscar en el directorio donde están instaladas las plantillas en la máquina comprobará si hay una carpeta CodeTemplates en el proyecto. En caso que tengamos allí una plantilla para el tipo de archivo que hemos seleccionado, cogerá la plantilla del proyecto en vez de la del directorio de Visual Studio.

Hasta aquí el artículo de hoy. Como siempre animaros a participar, abrir debates, dudas, etc... Recordar que podéis seguir areaTIC en las redes sociales. Hasta la próxima!!

martes, 7 de enero de 2014

SignalR 2.0 en MVC - Ejemplo práctico Horse Race

El post anterior jugamos con el protocolo WebSockets y vimos como realizar un ejemplo en un proyecto ASP .NET MVC. Hoy adaptaremos el mismo ejemplo de la carrera de caballos usando SignalR 2.0.

SignalR en su versión 2.0 es un librería que aporta funcionalidades para gestionar conexiones bidireccionales entre cliente y servidor, en realidad no se puede decir que sea una alternativa a WebSockets sino más bien una librería que facilita este tipo de comunicación en entornos MS. Me explico, si recordamos las limitaciones de WebSockets, no siempre los navegadores aceptan este tipo de protocolo a nivel de transporte. Una de las ventajas que veo en SignalR es que nos aleja un poco del nivel de transporte y se encarga de determinar automáticamente que protocolo se usará en función de las características del cliente que accede a nuestra aplicación web.

En el post anterior, teníamos los siguientes elementos:
  • Controlador estandar para gestionar la vista principal donde se muestra la carrera
  • Vista con un canvas y 2 caballos
  • Script para gestionar la conexión WebSocket en cliente
  • Controlador "webApi" para gestionar la conexión WebSockets en servidor
  • Clase de negocio que gestiona la carrera en servidor

Podríamos partir del mismo proyecto web anterior o crear uno nuevo, lo único que cambiaremos es el script que teníamos en cliente para gestionar la conexión WebSockets y el controlador WebApi que gestiona la conexión WebSocket en server.

Para continuar con el ejemplo es necesario instalar el paquete de SignalR desde Visual Studio (2013) usando el siguiente comando desde la consola del administrador de paquetes de VS -> install-package Microsoft.AspNet.SignalR. Una vez ejecutado este comando si vamos a la carpeta Scripts del proyecto veremos que se han añadido las librerías jquery.signalR-2.0.1.js y jquery.signalR-2.0.1.min.js (la versión podría variar).

Vamos a crear el Hub en servidor. Crearemos una carpeta Hubs en nuestro proyecto, hacemos click botón derecho y seleccionamos "Agregar nuevo elemento" en el menú contextual. Veremos que nos aparece una opción SignalR entre las plantillas, nos situamos en el y seleccionamos tipo de archivo Clase de concentrador SignalR (v.2).
namespace HorseRace.SignalR.Hubs
{
  public class MyHorseRaceHub : Hub
  {
    public void init()
    {
      Race BusinessHorseRace = new Race();
      Task tRace = BusinessHorseRace.InitHorseRace();
      while (!tRace.IsCompleted)
      {
        Thread.Sleep(50);
        List<int> positions = BusinessHorseRace.GetMovement();
        Clients.Caller.message(System.Web.Helpers.Json.Encode(positions));
      }
    }
  }
}
Como veis el código en servidor se simplifica bastante usando SignalR. El siguiente paso es iniciar el Hub que acabamos de crear cuando arranque el site. Si estamos trabajando con MVC 5.0 y Visual Studio 2013 automáticamente al crear el proyecto se añade una clase en la root StartUp donde añadiremos código para mappear e configurar nuestros hubs. En caso de no estar usando la versión 2013 de Visual Studio os tendréis que crear una clase plana vosotros mismos con el siguiente código y asegurarse que se llama desde global.asax al iniciar la aplicación.
[assembly: OwinStartupAttribute(typeof(HorseRide.SignalR.Startup))]
namespace HorseRace.SignalR
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}
Vamos con la parte cliente. Como comentábamos al principio del post sólo tendríamos que cambiar el script de conexión al websocket por el siguiente script:
    $(function () {
        var conexion = $.connection.myHorseRaceHub;

        conexion.client.message = function (message) {
            var positions = $.parseJSON(message);
            initField();
            drawHorseBlanco(positions[0], yC1);
            drawHorseNegro(positions[1], yC2);
        };

        $.connection.hub.start().done(function () {
            $('#btnConnect').click(function () {
                conexion.server.init();
            });
        });
    });
Si pulsamos "Iniciar Carrera" ya tendríamos los caballos compitiendo de nuevo.

Con SignalR podríamos realizar un broadcast desde servidor a todos los clientes conectados de manera bastante sencilla.
En cliente sería añadir el siguiente código:
   conexion.client.broadcastMessage = function (message) {
      alert(message);
  };
En server, añadiría este código al inicio del método init que hemos creado en el Hub:
   Clients.All.broadcastMessage("nuevo cliente conectado");
Esto que nos ha costado 2 líneas de código con SignalR en el ejemplo anterior trabajando directamente con WebSockets se podría haber hecho pero nos hubiese dado más trabajo.

Hasta aquí el artículo de hoy, si alguien estuviese interesado en que le haga llegar el código que contacte conmigo vía linkedin o google. Recordaros, como siempre, que podéis seguir areaTIC en las redes sociales y comentar todo lo que creáis oportuno! Hasta la próxima!!