ASP.NET 5, Owin y Katana

Con todo esto del ASP.NET5, ASP.NET 4.6, MVC6, DNX, DNX Core, etc. No queda muy claro donde encajan ciertos componentes que antes ya nos resultaban familiares. Como el caso de Owin y Katana que, con el anuncio de ASP.NET 5, no supe donde quedaron o qué iba a pasar con ellos.

Afortunadamente el equipo de ASP.NET documentó el tema y solo tenía que buscar un poco.

Con la información obtenida en el articulo me quedaron claras algunas cosas:

  • En el repositorio de Katana ya habían dicho que la siguiente versión sería parte de “vNext” y que el proyecto se movería de codeplex a GitHub, en el mismo repo de ASP.NET. Además renombraron todo para alinearlo con ASP.NET 5 y la versión sería de nuevo la 1.0.katanaroadmap
  • Con esta movida no solo cambiaron de nombre las cosas, también cambió el cómo funcionaban, es el caso del IAppBuilder, que ahora es IApplicationBuilder, y que usa un AppFunc diferente. O el IOwinContext, que ahora es HttpContext.
  • Si hay forma de usar los viejos (Katana 3.0) middlewares en ASPNET 5.

Algo de código

Hasta aquí he comentado lo que entendí de aquel articulo. Pero unas cuantas lineas de código nos mostrara que quiere decir esto y nos aportará nuevas dudas.

¿Cómo luce un middleware hoy?

Para crear un middleware compatible con el pipeline de Katana basta con definir una clase que use el AppFunc y tenga un método Invoke, algo de la forma:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;

namespace MisMiddelwares
{
    using AppFunc = Func<IDictionary<string, object>, Task>;

    public class DebugMiddleware
    {
        private readonly AppFunc _next;

        public DebugMiddleware(AppFunc next)
        {
            _next = next;
        }

        public async Task Invoke(IDictionary<string, object> enviroment)
        {
            var path = (string) enviroment["owin.RequestPath"];
            Debug.WriteLine("--Incoming request. Path: " + path);
            await _next(enviroment);
            Debug.WriteLine("--Outgoing request. Path: " + path);
        }
    }
}

¿Cómo se usa un middleware hoy?

El middleware anterior lo podemos integrar en el pipeline de Katana 3.0 de manera muy, muy sencilla:

    using Owin;
    using MisMiddlewares;
    public class Startup
    {        
        //... Configure Web API for self-host. 
        var config = new HttpConfiguration();
	appBuilder.Use<DebugMiddleware>();
        appBuilder.UseWebApi(config);      
    }

Si quisiéramos agregar nuestro middleware usando la forma app.UseXXX, deberíamos agregar una clase estática al ensamblado del middleware, agregar una dependencia a Katana (Microsoft.Owin) y usar el siguiente código

namespace MisMiddlewares
{
    using Owin;

    public static class DebugMiddlewareExtensions
    {
        public static void UseDebug(this IAppBuilder app)
        {
            app.Use<DebugMiddleware>();
        }
    }
}

Usar mi middleware en ASP.NET 5

Ahora viene lo nuevo, en un proyecto de ASP.NET 5 (DNX) vamos a intentar usar el middleware que acabamos de crear. Para ello lo primero que haré será remover el dnxcore50 de la sección frameworks del project.json, esto porque no lo usaré y necesito una referencia al middleware (cproj). Una vez hecho esto agrego una referencia al proyecto (con todo lo que hace por detrás), esto lo hago solo para ver que pasaría en el caso de querer reutilizar el componente sin tener que escribir nada más, además de ver que tiene el nuevo Katana que nos permita reutilizar lo anterior.

En el startup vemos que el nuevo IApplicationBuilder aún expone un método Use, pero con una firma muy diferente para el AppFunc que no nos sirve en nuestra anterior implementación. Podríamos intentar construir uno (AppFunc) a partir de este, o mejor aún, usar lo que ya tiene Katana vnext (el vnext se lo puse yo :P) para esto. En el articulo hay un enlace a un repo que contiene un ejemplo, algo engorroso, que muestra cómo hacerlo. Pero en ese mismo repositorio hay otro ejemplo un poco más claro. Partiendo de este ejemplo, si queremos usar de nuevo nuestro middleware empezaremos por instalar el paquete Microsoft.AspNet.Owin, que nos expone el método UseOwin, y, en la clase Startup ya podemos agregarlo al pipeline:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseOwin(addToPiepline =>
            {
                addToPiepline(next =>
                {
                    var middleware = new DebugMiddleware(next);
                    return middleware.Invoke;
                });
            });

Inquietudes

Con esta implementación me queda la inquietud de cómo harán las personas que mantienen este tipo de proyectos para dar soporte a las aplicaciones DNX y a las tradicionales, cómo será el tema del código compartido… o si será algo automático

Ejemplo

He dejado el código de este artículo aquí

Espero les sea de utilidad esta breve aclaración

Hasta el próximo post.

ASP.NET 5, Owin y Katana

[ASP.NET] Simplificando los controladores

Hace unos días Juanma publicó un tweet con un articulo que me resultó interesante. En este se describe como “mejorar” el código de las aplicaciones web escritas en lenguajes orientados a objetos y sobre frameworks MVC usando “técnicas” un poco más cercanas a un paradigma funcional, y describe, además, lo difícil de adaptar el mundo stateless de la programación web (server side) a lo que propone un diseño orientado al dominio.

Me pareció interesante, además, porque en las últimas semanas he estado replanteándo como hago yo este tipo de desarrollos… en un nuevo proyecto. Siempre que puedo trato de cambiar en algo el como escribo y organizo mi código, casi siempre influenciado por lecturas (libros, blogs, twitter), conferencias, y demás, y me han llevado por escribir aplicaciones como lo planteaba el libro negro de la Arquitectura Orientada al Dominio con Tecnologías Microsoft, si, con todo y los cien ensamblados. He escrito aplicaciones con todo el código en los controladores o, en el mejor de los casos, llamando a clases que “encapsulan” estos procedimientos, pero igual, todo muy acoplado. He escrito aplicaciones con modelos de dominio anémicos y un montón de servicios que inyecto en los controladores, con y sin repositorios, etc. Pero ahora quise probar algo que vi en el blog de Bogard, quien propone usar el patrón mediador para escribir aplicaciones que usen un modelo CQS. Incluso creó una librería para resolver los Handlers de las consultas y comandos, con una que otra cosa de más, llamada MediatR, que se integra bien con y sin contenedores de dependencias.

En resumen, lo que se busca con CQS es separar las consultas de las escrituras, para simplificarlo podríamos verlo como los GET y los POST en nuestras aplicaciones, y con la aplicación del patrón mediador es tener una única dependencia en los controladores (el mediador) y que sea este ultimo quien resuelva que hadler hace que.

Para ilustrar mejor esta definición veamos un ejemplo:

    public interface ICommand<out TResult> { }

    public interface ICommandHandler<in TCommand, TResult> where TCommand : ICommand<TResult>
    {
        Task<TResult> HandleAsync(TCommand command);
    }

    public class AddItemCommand : ICommand<AddedItemViewModel>
    {
        public AddItemCommand(Guid itemId, Guid storeId)
        {
            ItemId = itemId;
            StoreId = storeId;
        }

        public Guid ItemId { get; private set; }
        public Guid StoreId { get; private set; }
    }

    public class AddItemHandler : ICommandHandler<AddItemCommand, AddedItemViewModel>
    {
        private readonly IApplicationDbContext _context;

        public AddItemHandler(IApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<AddedItemViewModel> HandleAsync(AddItemCommand command)
        {
            var itemId = command.ItemId;
            var storeId = command.StoreId;
            var store = await _context.Stores.FirstAsync(s => s.Id == strtoreId);

            //Todas las reglas del dominio al dominio.
            var item = store.ShipItem(itemId);
            //...
            
            _context.SaveChanges();
            var resp = new AddedItemViewModel
            {
                Location = item.Location,
                //...
            };
            return resp;
        }
    }

Podemos detenernos aquí y recibir en el constructor del controlador cuantos handlers deseemos y usarlos en los métodos de acción que los requieran, o, si queremos ir más allá, podemos crear un objeto que resuelva y llame al handler adecuado a partir del comando, para esto crearemos un mediador o usamos MediatR. De hecho podemos detenernos en el Command y “encapsular” allí, acoplado o no, toda la funcionalidad de dicho comando y ser felices, todo depende de nuestra aplicación, sus requerimientos, y la facilidad para testear el código que deseemos.

Con esto habré transcrito aquí lo que entendí de la serie de artículos de Bogard, así que iré un poco más allá y voy a discutir algo que vi hace un tiempo en un video del buen Greg Young.

Greg Young afirma que la magia, en el código, es mala. Expone el caso de los dynamic proxy y de cómo nos explicarían eso a los desarrolladores junior, o cómo entendemos la magia de los frameworks que usan en un proyecto cuando recibimos los fuentes. Habla de los contenedores de dependencias y su magia, nos habla de buscar una interfaz común y cambiar nuestro problema con el fin de evitar la magia. Muestra una implementación de comandos y consultas, en lago similar a la que ya vimos… en fin, es un buen video y estoy seguro que algo aprenderás como lo hice yo.

Revisando la implementación anterior

Viendo el código de nuestro command handler vemos que la interfaz común nos indica que habrá un parámetro de entrada y uno de salida con un única acción: procesar el comando. Todo lo que necesitemos para llevar a cabo esta acción lo pasaremos como parámetro al constructor, y el único estado que contendrá esta clase serán dichas dependencias. Si no hay más estado que dichas dependencias y la interfaz común solo expone una acción con una entrada y una salida… ¿no luce esto como una función?

Ya Mark Seemann había escrito sobre el tema, y en español, Juanma también nos compartió sus opiniones.

En este caso me inclino a pensar un poco más funcional, es decir, darle todo lo necesario a la función para que haga su trabajo y no tener un estado que no aporta mucho en el objeto. Así las cosas podríamos olvidarnos de las interfaces y usar solo funciones:

    public class AddItemCommandHandler
    {
        public static Func<AddItemCommand, IApplicationDbContext, IAzure, Task<AddedItemViewModel>> Handle = HandleBody;

        private static Task<AddedItemViewModel> HandleBody(AddItemCommand command, IApplicationDbContext context, IAzure azure)
        {
            throw new NotImplementedException();
        }
    }
    public class RemoveItemCommandHandler
    {
        public static Func<AddItemCommand, IApplicationDbContext, Task<RemovedItemViewModel>> Handle = HandleBody;

        private static Task<RemovedItemViewModel> HandleBody(AddItemCommand command, IApplicationDbContext context)
        {
            throw new NotImplementedException();
        }
    }

El problema de ahora pasar como parámetro todas las dependencias a nuestros métodos es que hemos roto la interfaz común que habíamos logrado. Así que, ¿cómo lo conseguimos?

Aplicación parcial de funciones

La aplicación parcial de funciones es algo muy común en la programación funcional, podemos verla como la función resultante de llamar a una función sin todos sus argumentos. La manera más fácil de entenderlo es mediante un ejemplo:

    Func<int, int, int> Multi = (a, b) => a * b;
    Func<int, int> DosPor = a => Multi(a, 2);
    DosPor(3); // 6 😛

Haciendo uso de la aplicación parcial de funciones podemos pasar los parámetros extra (repositorios, contexto, loggers, helpers) para trabajar con una función que reciba un solo parámetro, el command, y recuperar así nuestra interfaz común.

Ok, ¿y cómo se resuelven los Handlers?

Ya no tenemos interfaces para inyectar y resolver desde el mediador. Pero podemos usar un contenedor de Comandos (un diccionario) para usarlos desde el controlador. ¿No es este un acoplamiento con dicho contenedor que hará más difícil testear mis controladores? te preguntarás, sí, si deseas hacerle test unitarios al controlador lo “mejor” sería sacarle una interfaz a esta dependencia (pero no me gusta hacerle unit testing a los controladores…)

¿Cómo queda este contenedor de comandos?

    public class ApplicationCommands
    {
        private static readonly Dictionary<Type, Func<ICommand, Task<IResult>>> Handlers = new Dictionary<Type, Func<ICommand, Task<IResult>>>();

        public static void Register<T>(Func<T, Task<IResult>> handler) where T : ICommand
        {
            if (!Handlers.ContainsKey(typeof(T))) Handlers.Add(typeof(T), command => handler((T)command));
        }

        public static async Task<IResult> HandleAsync(ICommand command)
        {
            return await Handlers[command.GetType()](command);
        }
    }

La interfaz ICommand la tenemos desde la primera implementación, pero ahora no será genérica y nos servirá de marker interface. Y la interfaz IResult tendrá dos métodos que uso para eso de mostrar mensajes de error y ayuda. La definición de las interfaces es:

    public interface IResult
    {
        void AddHttpInfo(HttpViewModelInfo info);
        IList<HttpViewModelInfo> GetHttpInfo();
    }

    public interface ICommand { }

Ya podremos cargar nuestro contenedor de comandos haciendo algo como:

            ApplicationCommands.Register<AddItemCommand>(
                async command => await AddItemHandler.Handle(command, new ApplicationDbContext(), new AzureManager()));

¿Y cómo se maneja el ciclo de vida de los objetos?

Al manejar un diccionario estático con los comandos no se puede registrar una instancia con ciclo de vida por request, lo que estaría por request es el comando, pero el dispose de, por ejemplo, el DbContext queda fuera de nuestro control. Por lo que no sé si convendría más usar un contenedor por request, es decir, reconstruirlo para cada controlador o actualizar la entrada en el diccionario (agradezco sugerencias en los comentarios) :S

Para verlo más claro vamos a cargar los applications commands para el Web Api:

    public class WebApiCompRoot : IHttpControllerActivator
    {
        public IHttpController Create(
            HttpRequestMessage request,
            HttpControllerDescriptor controllerDescriptor,
            Type controllerType)
        {
            if (controllerType == typeof(ShippingController))
            {
                var context = new ApplicationDbContext();
                var azureContext = new AzureContext();
                ApplicationCommands.Register<AddItemCommand>(async command => await AddItemHandler.Handle(command, context, azureContext));
                request.RegisterForDispose(context); //Ciclo de vida por request
                return new ShippingController();
            }
            return (IHttpController) Activator.CreateInstance(controllerType);
        }
    }

Si ejecutamos así el primer request funcionará perfecto. Pero para los siguientes no se creará un nuevo context y recibiremos la excepción indicando que ya se ha hecho Dispose. Podemos entonces reescribir la entrada en el diccionario en el ApplicationCommands o crear un contenedor por request y pasarlo a cada controlador.

Notas

En esta entrada solo mostré el uso de comando y no de consultas, pero la idea es la misma.

“¿No deben los comandos ser de tipo void (Action)?” eso dicen, pero noté que siempre quiero informar algo y si no es así, siempre puedes crear un IResult Unit, como el de F#

Ese código se ve horrible, ¿por qué no usas mejor un lenguaje funcional? Si, ya me lo han dicho y espero estar hablando sobre el tema pronto.

Espero les sea de utilidad, y si tienen feedback, bienvenido!

Hasta el próximo post.

[ASP.NET] Simplificando los controladores

OWIN, Katana y open source projects

De seguro que al sol de hoy ya has oído hablar sobre la especificación OWIN — Open Web Server Interface for .NET y sobre la implementación de esta especificación por parte de Microsoft en el proyecto Katana, ya se ha escrito bastante sobre el tema y para los hispanohablantes ya el buen Eduard Tomas hizo una reseña de como ha venido evolucionando ASP.NET y su visión de una futura evolución no monolítica del Framework.

En pro de la flexibilidad y la portabilidad

En la actualidad en .net tenemos varios Frameworks para desarrollo web, unos de Microsoft (WebForms, MVC y Web API) y unas opciones open source como FubuMVC, OpenRasta, NancyFX, entre otros. Con estos Frameworks desarrollamos nuestras aplicaciones, y para que puedan “correr” empleamos hosts y servidores Web, como el poderoso IIS, el IIS Express o algún tipo de Self Hosting empleando un HttpListener/TCP Listener/Web Socket. Y aquí es donde surge la principal meta de la especificación OWIN, desacoplar servidor y aplicación.

OWIN describe como los componentes de un Http pipeline deben comunicarse, para esto emplea dos componentes principales, el primero es el entorno, este es un diccionario de la forma IDictionary que llenará el servidor compatible con OWIN con los datos de entorno, con las claves que se detallan en la especificación. Y la responsabilidad de actualizar este diccionario con nuevos valores y de escribir el response body será entonces del Framework o la aplicación.

El segundo componente es el Application Delegate, esta será la abstracción principal entre todos los componentes de una aplicación, tomando el diccionario de entorno y definiendo una tarea a realizar, su firma es de la forma Func, Task>. Como se puede notar, el que la tarea a realizar sea una Task ya nos hace ver una prometedora asincronia :D.

Con estas simples abstracciones podemos escribir componentes que cumplan la especificación y “encadenarlos”  con otros componentes, reemplazar nuestro web server por uno mas ligero o robusto, emplear el host que mejor se ajuste, tener componentes mas granulares para la autenticación p. ej. y así tener lo que necesito y como lo necesito, sin ninguna dependencia extra, dándonos no solo las ventajas de poder reemplazar los componentes mas fácilmente, sino una posible mejora en el performance, pues como digo, solo usas los componentes que necesitas. Además, como estos componentes no dependen el uno del otro podríamos fácilmente encontrar un host para Mono y movernos hacia allá sin tener que reemplazar/cambiar nada/ningún componente.

A diferencia de un todo, esta modularidad nos brinda la ventaja de poder evolucionar constantemente cualquiera de nuestros componente sin tener que realizar, me atrevería a decir que, ningún trabajo en los demás.

Katana

La especificación de OWIN es dirigida por la comunidad de desarrolladores de .net, un esfuerzo conjunto de la comunidad de usuarios para presentar una nueva forma de hacer las cosas. La implementación de esta especificación por parte de Microsoft lleva el nombre de KATANA, una serie de componentes de OWIN, el proyecto es open source,  e incluye componentes de infraestructura como servidores y hosts, componentes para autenticación, Frameworks como SignalR y Web API.

El como implementar Katana ya es un tema muy documentado, así que no profundizare en este aspecto.

Open source projects

Cuando leía esta fascinante iniciativa lo primero que se me vino a la mente fue… escribiré mi propio servidor con juegos de azar y mujerzuelas, es muy sencillo 😛

        static void Main(string[] args)
        {
            const string msg = "Hola, yo soy tu server";
            const int port = 1450;
            var server = new TcpListener(IPAddress.Any, port);
            server.Start();
            Console.WriteLine("Servidor en linea...");
            while (true)
            {
                var socket = server.AcceptSocket();
                byte[] responseMessage = Encoding.ASCII.GetBytes(msg.ToCharArray(), 0, msg.Length);
                socket.Send(responseMessage);
                socket.Disconnect(false);
            }
        }

image

Pero ok, mejor olviden mi propia implementación y los juegos de azar, mejor olvídenlo todo y veamos verdaderas implementaciones hechas por la comunidad.

NOWIN

El primer proyecto de código abierto que clone fue NOWIN, según el autor, su implementación es de dos a tres veces mas rápida que HttpListener (paff sencillo) y Node JS (esto son palaras mayores :P). Implementar una aplicación con Nowin es bastante sencillo (En el código fuente  esta el mismo ejemplo):

    class Program
    {
        static void Main(string[] args)
        {
            var builder = ServerBuilder.New().SetPort(1450).SetOwinApp(Sample.App);
            using (builder.Start())
            {
                Console.WriteLine("Listening on port 1450. Enter to exit.");
                Console.ReadLine();
            }
        }
    }
    public class Sample
    {
        public static Task App(IDictionary arg)
        {
            var req = new Owin.Types.OwinRequest(arg);
            var resp = new Owin.Types.OwinResponse(req);
            if (req.Path == "/")
            {
                resp.StatusCode = 200;
                resp.AddHeader("Content-Type", "text/plain");
                resp.Write("Hello World!");
                return Task.Delay(0);
            }
            var p = Path.Combine(@"c:\Aplicacion", req.Path.Substring(1));
            if (File.Exists(p))
            {
                resp.StatusCode = 200;
                resp.AddHeader("Content-Type", "text/html");
                return resp.WriteAsync(File.ReadAllBytes(p));
            }
            resp.StatusCode = 500;
            return Task.Delay(0);
        }
    }

Lo que necesité:

image

Como luce:

image

Empleando Katana – Microsoft Hosting

En el ejemplo anterior con nowin no había una clara distinción del host y el server, pues cumplía el mismo objetivo. Veamos ahora una implementación con un componente de Katana, Microsoft.Owin.Hostin, es decir, no estamos haciendo uso de todos los componentes de katana, solo de lo que necesito! porque yo ya tengo mi server!… no es genial?! empleemos además un Web Api como framework, simplemente buscamos el Web Api OWIN en nuget y lo instalamos. Los paquetes en este ejemplo:

image

El código:

    class Program
    {
        static void Main()
        {

            var options = new StartOptions();
            options.Port = 1450;
            options.ServerFactory = "NowinWebServer";
            using (WebApp.Start(options))
            {
                Console.Write("Server en linea, puerto : {0}", options.Port);
                Console.ReadKey();
            }
        }
    }
    public class HolaMundoController : ApiController
    {
        public string Get()
        {
            return "Hola!!";
        }
    }
    public class Startup
    {
        public void Configuration(IAppBuilder builder)
        {
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute("Default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
            builder.UseWebApi(config);
        }
    }

El resultado:

image

Y la mejor parte de todas es que no hay espacio a resultados mágicos inesperados! te puedes descargar los fuentes de Katana y ver que pasa tras la cortina.

Como Nowin, he visto una implementación de  Mark Rendle llamada Flux un server para .net y mono que no usa HttpListener o Fleck una implementación de Web Socket server. Todas disponibles para jugar su uso.

Hay además implementaciones de Frameworks como el buen NancyFX y SignalR, tenemos componentes independientes de autenticación en el mismo proyecto Katana, que si al ver su código no te gustan, bien puedes mejorarlas y contribuir al proyecto o buscarte el que mejor se acomode a tus necesidades entre varias posibles opciones de la comunidad.

Opinión

Como yo lo veo con esto se marca un nuevo rumbo para el desarrollo Web (bueno me uno a Eduard y digo que no solo Web!) en .net, no solo por las ventajas que iniciativas como OWIN en si mismas proponen, sino por algo que ha ido evolucionando mucho en nuestra comunidad (.net) este tipo de cosas son muy normales en node js por ejemplo, donde hay varias opciones que puedes buscar en internet para resolver afrontar problemas, si pones npm “x cosa” en el buscador habrá al menos un loco en el mundo que ha subido un paquete que puedes descargarte y emplear para resolver tu problema. Para muchos desarrolladores de una plataforma tan robusta como lo es .NET esto también se ve como  un arma de doble filo, pues puede que ahora nos llenemos de millones de paquetes basura compatibles con OWIN que saber cual escoger se haga una tarea muy complicada (de hecho esto si pasa en node) o simplemente existan muchos paquetes con un mínimo de documentación… en fin, estos son skills que hacen que una comunidad sea fuerte, contribuir en proyectos open source no siempre es solo escribir código nuevo, se puede ayudar con implementaciones existentes, dando feedback o documentando.

Para quienes escribimos software corporativo y que aun no implementamos en producción nada fuera de un robusto IIS, pues repito, esto no supone el fin de IIS / System Web, para NADA! podemos tomar un IIS como nuestro hosting con KATANA, seleccionar los middlewares que necesitamos y los Frameworks a emplear con el mismo poder de siempre. De hecho en proyectos con VS2013 Preview ya vemos implementaciones con Katana 😀

El tema del licenciamiento es algo que me llama mucho la atención, si estas iniciativas buscan una mejora constante y hace énfasis en la portabilidad no emplees en tus aportes cosas como la que había hecho Microsoft con Katana! que había indicado (como en muchos otros paquetes de Nuget) una Windows-only Restriction, por fortuna anunció que en la versión 2, la que estará con VS2013 ya no tendrá esta restricción.

Entre colegas he visto muy parcializadas las opiniones frente a este tema, algunos alegan que nada es perfecto y querer hacer .net mas parecido a otros no es bueno… en fin, Microsoft parece no estar rompiendo nada hacía atrás y con iniciativas como esta, que repito, es de la misma comunidad de usuarios, se empiezan a dar mayores opciones, mas herramientas que podemos escoger para resolver nuestros problemas.

Si tienes alguna opinión sobre el tema no dudes en dejar tu comentario.

Bien, por ahora dejo el tema hasta aquí, ha sido un post teórico-practico-opinión, como para organizar un poco las ideas que esto trae y como lo veo yo, mas adelante espero escribir mas centrado en Katana, sus middlewares y la interacción con productos de la comunidad. 😀

Hasta el próximo post

OWIN, Katana y open source projects

[Windows Azure][IIS Express] ¿Por qué los Request se hacen con otro puerto?

Cuando trabajamos con el Windows Azure Compute Emulator (en entornos locales de desarrollo) podemos notar un comportamiento que de entrada puede parecer extraño, si nosotros especificamos un puerto para trabajar con nuestros sitios ¿por qué los Request se realizan con otro?

Sigo sin entender, muéstrame el código

Supongamos que tenemos un proyecto Web trabajando en el puerto 80:

Si revisamos el Request en uno de sus controladores podemos ver lo siguiente:

Ahora entra en juego Windows Azure y agregamos este site como un role para nuestro CloudService, al ejecutar se lanzará el Windows Azure Compute Emulator y veremos algo como lo siguiente:

Pero ¿por qué? Si revisamos el Compute Emulator UI veremos lo siguiente:

Pues parece que si está saliendo por el puerto 80 (esto es porque ese es el endpoint que viene definido en el role):

Pero… si damos un vistazo al IIS Express:

Vemos que ahora el sitio está trabajando en otro puerto 😮 Esto es porque cuando se despliega en el Development Fabric el emulador creara un balanceador para nosotros con el puerto 80 (este es el que se ve en el Detail Service), y se creará un WebSite para cada instancia del rol asignándole una IP con el formato 127.255.0.x, con el puerto inmediatamente disponible, es decir que si agrego otra instancia a mi Cloud Service se debería crear otra aplicación con dirección 127.255.0.1:81 por ejemplo:

Y lo que ocurre entonces es que el Request se hace con el puerto del sitio creado por el emulador (con la dirección del Balanceador), en este caso :81 y no el puerto del balanceador de carga. Si realizo la petición a la dirección que me ha generado el emulador para el Role:

¿Pero por que en la nube no pasa esto?

Este comportamiento solo sucede en el entorno local, porque cuando se despliega el CloudService sobre Windows Azure este corre sobre una Maquina virtual y el balanceador de carga corre en un host distinto a este, es decir, si es posible que los dos atiendan por el mismo puerto porque son host distintos.

Espero sea de utilidad la aclaración.

Hasta el próximo post.

[Windows Azure][IIS Express] ¿Por qué los Request se hacen con otro puerto?

[IIS Express] Configuration web for ASP.NET 4.5 failed

En una ocasión quise iniciar un proyecto asp.net MVC con Framework 4.5 y recibí el siguiente error:

En esa ocasión no estaba en mi maquina así que supuse que habían roto algo allí pero no era mi culpa :P, ahora me ha pasado en mi máquina y no se siente muy agradable, pues ahora es personal.

Historia

Como tal no existe un Framework 4.5, ya verán a que me refiero, si miramos en el Application pool de IIS veremos algo como lo siguiente:

Y si miramos el sistema de archivos (para usar el aspnet_regiis.exe) veremos lo siguiente:

En un blog de MSDN
esta esté buen artículo donde explican esta característica del versiona miento del Framework.

Teniendo presente esto surge la pregunta, y entonces porque Visual Studio se queja por la versión 4.5?

Si miramos IIS Express maneja un Application Pool en el archivo de configuración en la sección applicationPools

Hasta aquí ya se puede pensar en varias soluciones:

Solución 1

Pues muy simple, como la teoría dice que no existe diferencia en los Application Pools de aplicaciones creadas para Framework 4.5 basta con ubicar el Site en el archivo de configuración y agregar el atributo applicationPool indicándole que deseamos usar el Clr4IntegratedAppPool :

Solución 2

Ya sé que estarás pensando que hacer esto una y otra vez con cada uno de los proyectos puede ser tedioso, por fortuna en la sección de Sites podemos definir un elemento applicationDefaults, así:

Y con esto ya no tendrás que entrar a modificar cada site que se te cree.

Solución 3, bonus

En caso que pienses, hey! que tonto es Nicolás! (lo soy) porque no define la versión especifica del Framework en el Application Pool?, así?:

Con estos enfoques (el segundo) solucioné mi problema y ya no recibo más ese molesto error.

Espero les sea de utilidad.

Hasta el próximo post.

[IIS Express] Configuration web for ASP.NET 4.5 failed

[How To][IIS Express] Mismo Puerto y dominio para nuestros sitios

Introducción

Cuando desarrollamos aplicaciones para nuestros clientes (o para nosotros) en ocasiones resulta necesario por temas de trabajo en equipo e integraciones tener un dominio (o un alias) para nuestro desarrollo que sea común para todos los sitios que componen el proyecto y puede darse la situación de requerir usar un puerto específico para estos.

IIS Express

IIS Express es el servidor web seleccionado de manera predeterminada para nuestros sitios con Visual Studio 2012, este proporciona muchos beneficios combinando lo mejor de un IIS y de cassini en un solo servidor de desarrollo.

En su momento hablo sobre IIS Express Scott Guthrie explicando a manera de introducción que traía de nuevo este servidor.

Más información sobre IIS Express.

Todo lo referente a la configuración de este servidor lo encontramos en un archivo llamado applicationhost.config ubicado en la ruta […]\Documents\IISExpress\config.

Manos a la obra

Lo primero que necesitamos (si lo necesitas) es agregar un alias a nuestro archivo de host, este archivo se encuentra en C:\Windows\System32\Drivers\etc\host

image

Una vez creado, si hago un request a esa dirección se entenderá que estoy solicitando a localhost:

Ahora sobre nuestros sitios vamos a inidicarles que queremos trabajar con este dominio.

Si desplegamos la ventana de propiedades del site (alt + Enter) en el tab de Web indicaremos que deseamos hacer uso de ese nuevo dominio.

Si al intentar crear el directorio virtual para nuestro sitio recibimos este error:

Debemos abrir el archivo de configuración y crearlo a mano:

Una vez creado volvemos a nuestro Visual Studio e intentamos ejecutar, veremos que se inicia el IIS Express y notamos que está haciendo uso de la configuración que creamos:

Ahora a un segundo proyecto web vamos a definirle la misma dirección pero con un path diferente, desde Visual Studio:

Esto nos cambia el archivo de configuración, dejándolo así:

Si ejecutamos nuevamente desde el Visual Studio veremos lo siguiente:

Y si agregamos un método de acción que nos retorne un content para poder ver en que página estamos:

Atención especial al puerto 80

Si al ejecutar recibes un error informándote que el puerto 80 está siendo usado por otro proceso fíjate que en tu IIS este detenido o esté trabajando con otro puerto el Default Web Site si el problema persiste ejecuta el siguiente comando: netstat -o -n -a | findstr 0.0:80

Y termina el proceso con ese PID:

Espero les sea de utilidad

Hasta el próximo post.

[How To][IIS Express] Mismo Puerto y dominio para nuestros sitios

[ASP.NET MVC] Enlazando varios Modelos a un View

Esta es una situación común cuando estamos trabajando proyectos en el MVC Framework, y hay varias salidas como crear vistas parciales y unirlas en una única vista.

Sin embargo la solución que más me gusta es la de crear un ViewModel propio para cada una de las vistas que lo requiera, en principio puede sonar a mucho trabajo adicional, pero a decir verdad la flexibilidad que ofrece me ha gustado mucho. ¿En qué consiste? Pues simplemente en crear una clase adicional encargada de “unir” nuestras dos entidades de dominio, por ejemplo, supongamos que tengo dos entidades, estas son:

    public class ClassA
    {
        public int Id { get; set; }
        public string PropertyA { get; set; }
    }
    public class ClassB
    {
        public int Id { get; set; }
        public string PropertyB { get; set; }
    }

Ahora quiero crear una página donde pueda registrar datos de estas dos entidades, y es aquí donde crearemos nuestro ViewModel ClassCreateViewModel, una primera aproximación seria:

    public class ClassCreateViewModel
    {
        public ClassA ClassA { get; set; }
        public ClassB ClassB { get; set; }
    }

El controlador…

        public ActionResult Create()
        {
            return View();
        }

Y la vista la generamos sin escribir mucho código (no sé por qué hay gente que le sigue pareciendo improductivo MVC)

Hacemos algunas modificaciones y el código queda así:

@model MvcApplication1.ViewModels.ClassCreateViewModel


<meta name="viewport" content="width=device-width" />
Create

<script type="text/javascript" src="~/Scripts/jquery-1.7.1.min.js"></script><script type="text/javascript" src="~/Scripts/jquery.validate.min.js"></script>
<script type="text/javascript" src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
 @using (Html.BeginForm()) {
 @Html.ValidationSummary(true)</pre>
<fieldset><legend>ClassCreateViewModel</legend>
<div class="editor-label">@Html.LabelFor(model => model.ClassA.PropertyA)</div>
<div class="editor-field">@Html.EditorFor(model => model.ClassA.PropertyA)
 @Html.ValidationMessageFor(model => model.ClassA.PropertyA)</div>
<div class="editor-label">@Html.LabelFor(model => model.ClassA.PropertyB)</div>
<div class="editor-field">@Html.EditorFor(model => model.ClassB.PropertyB)
 @Html.ValidationMessageFor(model => model.ClassB.PropertyB)</div>
 <input type="submit" value="Create" /></fieldset>
<pre>
 }</pre>
<div>@Html.ActionLink("Back to List", "Index")</div>
<pre>

Luego desde el controlador simplemente hacemos las asignaciones y separaciones que correspondan.

Consideraciones y opiniones.

Personalmente no me gusta definir los ViewModels así, exponiendo una propiedad del tipo de cada uno de las entidades que quiero “unir”, prefiero crear estos ViewModels de una forma más explícita y poder acudir a beneficios como los DataAnnotations, y modelo y uso lo que realmente necesito sin tener que hacer “maromas” sobre los views para ocultar un campo, sino que con solo acudir a los Scaffold templates ya tenga vistas listas y con la validación que necesito. Entonces una segunda aproximación seria:

    public class ClassCreateViewModel
    {
        [Required]
        [Display(Name="Nombre Usuario")]
        public string PropertyB { get; set; }

        public string PropertyA { get; set; }
    }

Por lo general no me gusta decorar mis entidades de dominio con DataAnnotations, ya que me parece un medio para contaminarlas, si trabajo con EntityFramework prefio usar Fluent Api. Pero la comodidad de dataAnnotations es algo que no tiene ningún costo cuando lo trabajamos con los ViewModels y además nos genera varios beneficios.

Finalmente, y ya para terminar, no quiero que se confundan estos ViewModels con el ViewModel de MVVM, este patrón es más orientado a sistemas basados en eventos (EDP) y la Web no es uno de ellos, o bueno del lado de HTML5 en el cliente sí que se puede y ya hasta hay frameworks que nos ayudan a esto, Pero este no es el caso, todo se hace por el http.

Como siempre, quedo atento a sus comentarios.

Hasta el próximo post.

[ASP.NET MVC] Enlazando varios Modelos a un View