ASP.NET Core paso a paso – Introducción

Es momento de empezar a hablar de ASP.NET Core, por lo que este es el primer post de una serie denominada “ASP.NET Core paso a paso” – bien Mostaza Merlo – en donde vamos a ir viendo en detalle las distintas características del mismo.

En esta primer entrega vamos a comentar de que se trata este framework y cuales son sus principales características. Luego, a partir de las siguientes entradas ya vamos a meternos en cuestiones técnicamente más puntuales.

Sigue leyendo

Anuncios

One ASP.NET

Para quienes llevan un buen tiempo programando con tecnologías .NET recordaran que aya por el 2001 Microsoft sacaba al mercado algo llamado .NET Framework y acto seguido una nueva tecnología llamada ASP.NET. En aquellos años Internet empezaba a jugar un papel cada vez mas importante y era el momento de entrar en ese mercado. Y ASP.NET fue pensado justamente para atraer a los desarrolladores de aplicaciones de escritorio al desarrollo de páginas-aplicaciones web. Para que el cambio fuese lo mas transparente posible para los developers, ASP.NET adoptó el concepto de WebForms: formularios web donde podíamos arrastrar controles y con un simple “doble click” bindear eventos a los mismos y programarlos en el code behind (una forma de desarrollo muy parecida a la de WinForms).

Luego de un largo tiempo, a principios de 2009, aparece dentro de ASP.NET el patrón MVC y con él ASP.NET MVC 1 (una gran alegría para muchos de los desarrolladores web que esperábamos un cambio en el framework para que sea más orientado a la web!).  A medida que avanzaron los años este framework fue creciendo y con el aparecieron las versiones 2, 3, 4 y recientemente la versión 5.

Pero ASP.NET no solo se conforma de estos dos frameworks (Web Forms y MVC), con los grandes avances en el mundo web, en 2012 se añaden nuevos frameworks a la familia: Web API, SPA y SignalR (tengo pendiente un post sobre el mismo).

Ahora bien, aunque todos forman parte de la familia ASP.NET, generalmente se los suele identificar como proyectos independiente entre sí, sin relación uno con el otro. Esta visión no es correcta y con One ASP.NET se quiere reforzar esta idea.

La idea tras One ASP.NET es tener un único proyecto ASP.NET que podemos customizarlo a partir un conjunto de tecnologías web:

One ASPNET

One ASPNET

Por eso con Visual Studio 2013 cuando vamos a crear un nuevo proyecto web nos vamos a encontrar con una única plantilla “ASP.NET Web Application“:

ASP.NET Web Application

ASP.NET Web Application

Este cambio claramente refuerza el concepto de una única aplicación ASP.NET.

Una vez que creamos el proyecto se nos pedirá que elijamos las tecnologías con las que vamos a trabajar:

Seleccionando las tecnologías ASP.NET con las cuales trabajar.

Seleccionando las tecnologías ASP.NET con las cuales trabajar.

También podemos configurar de forma unificada aspectos como autenticación y testing unitario.

Algunos podrán decir que esto es simplemente un paso “extra” en la selección del template de proyecto a utilizar, sin embargo tras esta idea hay una nueva visión que pretende integrar este conjuntos de tecnologías bajo una única plataforma y finalmente borrar ese concepto que tenemos de proyectos independientes e incompatibles entre sí.

Por último recomiendo el post de José Manuel Alarcon hablando al respecto!

Abrazos!

ASP.NET MVC y Knockout : ViewModel

Una situación muy común que nos encontramos cuando comenzamos a trabajar con Knockout y ASP.NET MVC es la inicialización del modelo de KO (estructura JS) a partir del modelo de la vista (objeto C#). Una alternativa es inicializar el modelo de KO por medio de una llamada ajax al servidor (por ejemplo invocar un servicio WebAPI que nos devuelva el modelo ya serializado). Sin embargo como explica Eric Hexter en este excelente post, la experiencia de carga de la página por medio del renderizado del servidor (server side rendering) al parecer sigue siendo la más óptima.

Por lo tanto tenemos por un lado un renderizado inicial del lado del servidor utilizando un modelo de vista para tal propósito y por el otro lado tenemos KO con su propio modelo. La pregunta es cómo transformamos el viewmodel de ASP.NET MVC al viewmodel de KO sin utilizar llamas Ajax?

Investigando un poco encontré una simple solución propuesta por Eric Hexter (ver enlace de arriba). Lo que él propone es que simplemente convirtamos el modelo de la vista en un objeto Json dentro del código javascript de la página. En el ejemplo utilizaremos el view engine Razor para tal fin.

Manos a la obra!

En primer lugar vamos a crear el método de extensión ToJson() que nos permitirá representar objetos de .NET en formato JSON:

JsonExtension

JsonExtension

Por medio de esta extensión vamos a tener disponible el modelo de la vista en formato JSON, lo que nos posibilitará utilizarlo en nuestra lógica del lado del cliente (código javascript). Ahora lo que necesitamos es mapear el objeto JSON a los objetos observables que utiliza KO. Quien nos permite realizar tal actividad es el siguiente plugin de KO: KnockoutJS Mapping plugin  (disponible por medio de Nuget):

PM> Install-Package Knockout.Mapping

Veamos qué tan simple es su uso (continuamos con el ejemplo del post anterior):

Serializando el view model.

Serializando el view model.

Algunos puntos importantes:

  • Referencias a las librerías de KO y KnockoutJS Mapping plugin.
  • Generamos la representación JSON del modelo de la vista (del servidor) por medio del método de extensión ToJSon() y lo escribimos en el script por medio del helper HTML Raw.
  • El resto debería ser historia conocida 😉

Bien, finalmente tenemos el cuerpo del documento HTML:

Estructura HTML

Estructura HTML

Y la generación – mock – del modelo (en este ejemplo en el método de acción Index del controlador Home):

Método de acción Index

Método de acción Index

Corremos la aplicación y deberíamos obtener el siguiente resultado:

Resultado :)

Resultado 🙂

Como pueden ver esta es una forma muy simple de bindear el modelo de la vista del servidor al modelo de la vista del cliente.

Espero que les sea de utilidad!

Routing en WebAPI [quickly post]

Hace unos días, un colega me comentó acerca de un problema que tenía con el mecanismo de routing de WebAPI en un proyecto ASP.NET MVC 4. Me comento que se había basado en el primer post que escribí de la serie Web API, en el cual había utilizado un proyecto ASP.NET MVC 3.

Revisando el código generado en ambos proyecto, descubrí que dicho mecanismo había cambiado de una versión a la otra (sobre todo la ubicación en donde se definen las reglas de ruteo).

En proyectos ASP.NET MVC 4 la definición de dichas reglas esta a cargo de la clase WebApiConfig:

WebApiConfig

WebApiConfig

 Esta clase posee el método Register(HttpConfiguration config) el cual es utilizado para definir las reglas de routing que son especificas de Web API:

Agregando una nueva regla de ruteo.

Agregando una nueva regla de ruteo.

Por lo tanto, si necesito generar una nueva regla para los servicios expuestos con Web API, el lugar indicado es este. Hagamos un ejemplo sencillo para que quede claro. Vamos a agregar una nueva entrada llamada “NameApi” que permite al usuario utilizar URIs con el siguiente formato:

http://localhost:301283/api/values/1/sebis

Hecho esto, vayamos al controlador ValuesController (el cual hereda de ApiController) y  agreguemos un nuevo método GET (el hace provecho de esta nueva regla):

Get Method

Get Method

Ahora ejecutemos e invoquemos la URI (escrita unas líneas mas arriba) para corroborar que el servicio nos retorna el valor correcto:

Resultado obtenido del servicio

Resultado obtenido del servicio

Espero que les sea de utilidad.

Implementando características de OData con ASP.NET WebAPI

En esta nueva entrega sobre ASP.NET Web API vamos a hablar sobre las características que este soporta del protocolo Open Data Protocol (de ahora en mas OData).

Open Data Protocol

Open Data Protocol

Antes de comenzar, vamos a realizar una pequeñísima introducción a Open Data Protocol.

OData es un protocolo abierto – open protocol – creado por Microsoft para exponer datos como servicio. Este se basa en estándares conocidos de Internet como HTTP, Atom (AtomPub) y JSON. Como todo protocolo de servicios, uno de los fines principales es poder independizar los datos de la aplicación o sitio web que los utiliza. Los clientes que consumen servicios a través el protocolo OData pueden hacerlo bajo formatos como Atom, JSON o XML plano, pero además incluyendo características como paginación, ordenación y filtrosquerys -.

Otra característica interesante de OData es que nos permite exponer y acceder a información de una gran variedad de fuentes, incluyendo, bases de datos relacionales, sistemas de archivos, sistemas de gestión de contenidos y sitios web tradicionales.

Escenarios de despliegue de OData

Escenarios de despliegue de OData

Ahora bien, de todas las características que ofrece OData, la que nos interesa en este momento es la utilización de convenciones URI que nos permitirán, entre otras cosas, realizar operaciones como navegación, filtrado, orden y paginación de datos en la solicitud de un recurso.

URI Components

URI Components

La utilización de estas convenciones nos permiten, desde la misma URI del recurso, especificar query options que serán aplicadas al momento de obtener un recurso. Podemos ver en el gráfico anterior – URI Components – que las opciones de consultas se especifican al final de la URI.

Ejemplos de query options son:

  • $filter : permite aplicar filtros sobre el resultado.
  • $orderby : permite ordenar por alguna condición el resultado
  • $top : permite recuperar un cierto número de resultados.
  • $skip : permite saltear un cierto número de resultados.

Vayamos a un ejemplo, si quisiera obtener la lista de clientes ordenadas por nombre, debería invocar al servicio utilizando la siguiente URI:

http://localhost:[port]/api/clientes?$orderby=Nombre

Ahora bien, ASP.NET Web API trae soporte para un subconjunto de características del protocolo OData. Una de ellas es que podemos trabajar con las convenciones URI que trabajaran en la interacción con los controladores de nuestra API.

Para trabajar con ellas simplemente debemos modificar el tipo de datos de la respuesta de nuestro método. Recordaran que en post anteriores el método retornaba un objeto IEnumerable:

Método de acción Get() retornando un IEnumerable

Método de acción Get() retornando un IEnumerable

En este caso debemos vamos a modificar la firma y el cuerpo del método para que retorne un objeto IQueryable:

Método de acción Get() retornando un IQueryable

Método de acción Get() retornando un IQueryable

Tal como menciona MSDN, el motivo de esta cambio es que la interfaz IQueryable hereda la interfaz IEnumerable, por lo que si representa una consulta, se pueden enumerar los resultados de esa consulta (la enumeración provoca la ejecución del árbol de expresión asociado a un objeto IQueryable). Es tarea del framework armar la consultas correctamente a partir de las query options enviadas en la URI.

Realizado el cambio, vamos a consumir el servicio como lo veníamos haciendo normalmente utilizando la siguiente URI:

http://localhost:[port]/api/clientes
Datos obtenidos del servicio

Datos obtenidos del servicio

Podemos observar que los resultados vienen en el mismo orden que los habíamos agregamos en el array (es decir, sin estar ordenados por alguna condición). Ahora solicitemos el mismo recurso, especificando que vengan ordenados por el atributo nombre:

http://localhost:[port]/api/clientes?$orderby=Nombre
Datos obtenidos del servicio utilizando las convenciones de URL

Datos obtenidos del servicio utilizando las convenciones de URL

Como vemos, utilizando las convenciones URI, es muy simple establecer condiciones-acciones-funciones en la obtención de los recursos! 🙂

Pero eso no es todo, también podríamos trabajar con paginación y filtros. Simplemente debemos agregar en la URI la query correspondiente de acuerdo a nuestras necesidades, algunos ejemplos:

http://localhost:[port]/api/clientes?$filter=Nombre eq ‘Jous’
  • Filtrar utilizando operadores lógicos:
http://localhost:[port]/api/clientes?$filter=Nombre eq ‘Sebis’ or Nombre eq ‘Jous’
http://localhost:[port]/api/clientes?$top=3&$skip=0

También tenemos disponibles un gran conjunto de opciones de query dentro de las cuales podemos encontrar: Select, Top, OrderBy, Expand, Format, DateTime Functions, Math Functions, Type Functions y muchísimas otras más.

Para finalizar, quería comentarles que OData dispone de un conjunto de API’s de creación y consumo de Servicios OData para trabajar desde el lado del cliente con dispositivos mobiles (WP7, Android, iOS), app webs (Silverligth, ASP.NET, HTML 5 + Javascript, Java, PHP, Ruby) y web CMS (Joomla, Drupal). Y también desde el lado del servidor con custom servers (.NET Server, Java, PHP, Node.JS),  databases (SQL Server, MySql, Azure Data) y cloud app (App Engine, Azure).

Espero que les sea de utilidad.

Nos vemos pronto!

ASP.NET Web API: Validando con Global Action Filters

En esta cuarta entrega sobre ASP.NET Web API veremos como aplicar validaciones a nivel global del proyecto. Si observamos la forma en que manejamos los errores del modelo en el método de acción Post(), podemos identificar un patrón común para todas las validaciones:

Validación del modelo

Validación del modelo

Por lo tanto, porque no gestionarlo de manera global,y despreocuparnos de este tema. ASP.NET MVC nos proporciona un mecanismo para esto, y son los Global Action Filters que nos permiten ejecutar lógica antes o después de un método de acción (sobre este tema ya habíamos hablamos en este post).

Momento de definir el filtro de acción global que llamaremos ValidationActionFilter:

Definición del filtro de acción ValidationActionFilter

Definición del filtro de acción ValidationActionFilter

Acto seguido, registrar el filtro de acción en el método Application_Start() del archivo Global.asax:

Registrando el filtro de acción

Registrando el filtro de acción

Finalmente limpiamos el método de acción Post():

Método de acción Post()

Método de acción Post()

Probemos nuevamente el formulario, y las validaciones deberían actuar de la misma forma:

Validaciones del formulario

Validaciones del formulario

Espero que les haya servido y en próximos post vamos a continuar con más características de ASP.NET Web API.

ASP.NET Web API – Aplicando Validaciones

En esta tercera entrega acerca de ASP.NET Web API veremos como podemos aplicar validaciones dentro de nuestros servicios. Al igual que con ASP.NET MVC, Web API utiliza el Defaul Model Binder para realizar las validaciones, lo cual es una excelente noticia para quienes trabajamos con el framework.

Arranquemos!… el primer paso será agregar los atributos de validación a la clase Cliente, utilizando la librería DataAnnotations para tal fin:

Aplicando los atributos de validación al modelo

Aplicando los atributos de validación al modelo

Hecho esto, tenemos que ambas propiedades del modelo serán “requeridas” (obligatorias) y que el nombre de usuario tendrá como máximo 4 caracteres de longitud. Aclaración: agregué un nuevo atributo – User – a modo de hacer un poco mas completo el ejemplo.

Ahora viene lo interesante, vayamos al método de acción Post() y agreguemos la lógica necesaria para validar que los datos del cliente que llegan del servicio sean correctos:

Método de acción Post() redefinido

Método de acción Post() redefinido

Como verán, hicimos algunos cambios respecto a como a la definición del método de acción Post() de la entrada anterior. Ahora, previo a la creación del cliente, tenemos que validar que el modelo sea correcto – ModelState.IsValid – y en el caso de serlo, agregar de alguna manera los errores a la respuesta HTTP para notificarle al cliente. La forma de hacerlo es consultando las propiedades del ModelState que posean errores para recuperar los “mensajes de error” de las mismas. Luego creamos un objeto del tipo JsonArray – recuerden incluir el namespace System.Json – al cual agregar esta información. Una vez hecho todo esto, armamos la respuesta HTTP que vamos a devolver, incluyendo el código de estado HTTP 400 – Bad Request (el cual vamos a usar para identificar cuando la validación fue incorrecta) y los mensajes de error serealizados.

Momento de ir a la vista y agregar: un nuevo campo de texto para permitir la carga del nombre de usuario y un div donde vamos a visualizar los errores que pueden producirse en la creación del cliente:

Modificando la vista

Modificando la vista

Llego el momento de trabajar en el script, de forma tal que procese el resultado de las validaciones en caso de que las mismas no hayan sido correctas. Lo primero será modificar la función crearCliente():

Modificando la función crearCliente() del script Clientes.js

Modificando la función crearCliente() del script Clientes.js

Como pueden observar, uno de los cambios que hicimos en la función fue agregar una nueva función de callback en los parámetros. Esta nueva función llamada callbackFail se invocará solamente cuando ocurran errores en la validación del modelo, es decir, cuando el valor del código de estado – statusCode – devuelto por el servicio sea HTTP 400 – Bad Request. Para trabajar con los errores, debemos consultar a la propiedad responseText que recibimos en el objeto xhr – del tipo XmlHttpRequest – devuelto por el servicio (es importante serializarla antes de enviarla a la función de callback).

Pueden inspeccionar el resultado del servicio, cuando el modelo no es correcto, y observar la propiedad responseText con el arreglo de los errores:

Resultado del servicio cuando el modelo no es correcto

Resultado del servicio cuando el modelo no es correcto

Ok, llego el momento de modificar el evento click del botón “Crear”:

Modificando el evento click del botón "Crear"

Modificando el evento click del botón “Crear”

Bien, en este punto simplemente lo que hacemos es recibir el array con los mensajes de error y “dibujarlos” en el div que creamos en la vista para tal fin. Queda en ustedes ver la mejor forma de visualizar los errores :).

Probemos lo hecho:

Consumiendo los servicios desde nuestra app

Consumiendo los servicios desde nuestra app

Resumiendo, podemos ver que el manejo de las validaciones no difiere demasiado de la forma en que lo veníamos haciendo en los proyectos ASP.NET MVC. Simplemente tenemos que modificar el formato en que vamos ha devolver las mismas adaptándonos a los estándares REST.

En próximos post vamos a seguir viendo otras características de Web API.