miércoles, 25 de noviembre de 2015

¿Qué es Bower? Breve tutorial para usarlo en tus proyectos

Hace un tiempo estuve optimizando un proyecto casero de app que hago desde hace unos meses con cordova. Lo típico, soy uno solo en el proyecto y dispongo de poco tiempo (mi tiempo libre que cada vez escasea más). Por tanto siempre voy dejando notas con los típicos "TODO" con temas y uno de ellos era usar bower para la gestión de librerías que uso en el proyecto.

Bower es un gestor de paquetes de ámbito cliente muy popular entre la comunidad javascript. Si trabajas con tecnologías Microsoft que sepas que está previsto que Bower esté integrado en Visual Studio en versión 2015 y también Grunt / Gulp que son librerías javascript que sirven para automatizar tareas javascript del tipo bundling y minificación de ficheros js. Por tanto tarde o temprano al pasar a ASP.NET 5.0 acabarás usando Bower. En caso que no trabajes con tecnologías Microsoft también podrías seguir los pasos del tutorial y usarlo en tu proyecto sin problema.

Como seguramente sabéis, Microsoft tiene su propio gestor de paquetes que es Nuget. Muchos diréis que Nuget es un gestor de paquetes de ámbito .net pero lo cierto es que también se usa para descargar paquetes javascript/css como Angular o Bootstrap. ¿Por qué MS apuesta por integrar Bower en Visual Studio si ya tiene Nuget? Bueno, opino que Microsoft se está sumando a la tendencia de la comunidad open source lo cual me parece genial. Bower, descarga los paquetes de Git Hub que es la comunidad más popular de repositorios open source. Es muy posible que plugins populares de Angular (por poner algún ejemplo) no existan en Nuget… ya que probablemente parte de desarrolladores de plugins javascript no tenga por costumbre subirlos también allí.

Bueno no me enrollo más y empiezo a detallar los pasos para usar Bower en un proyecto.

Si usas Visual Studio 2015 verás que dispones de cierta integración de Bower con el IDE. En caso que uses versiones anteriores o que no dispongas de Visual Studio podrías seguir estos pasos y usarlo para gestionar paquetes cliente.

Instalar Git (Windows)


Bower usa Git para descargar paquetes de GitHub. Se trata de seguir los pasos de instalación, nos dará a escoger entre varias opciones interesa poder usar Git desde la línea de comandos de Windows. En principio si hemos escogido la opción correcta no tendremos que preocuparnos de las variables de entorno.

Instalar Node


Necesitamos Npm (Node Package manager) para instalar Bower o actualizar la versión de la librería. Una vez instalado Node nos debería dejar lanzar este comando desde la línea de comandos de Windows. En caso que no reconozca el comando npm tendrías que crear manualmente el path en variables de entorno (no debería sucederte el instalable de Node se encarga).
 
npm install bower -g

Inicializar Bower en tu Proyecto


Se trata de abrir una línea de comandos, situarte en la root de tu proyecto y lanzar el siguiente comando.
 
bower init
En la siguiente pantalla te pide información sobre tu proyecto, asegúrate de definirlo como privado (a no ser que quieras subir tu proyecto a GitHub) y el resto puedes informar lo básico como ves en la imagen.


Al finalizar este paso deberías tener en la root de tu proyecto un fichero como .json como este.
{
  "name": "areaTIC Bower Introduction",
  "description": "",
  "main": "",
  "moduleType": [],
  "license": "MIT",
  "homepage": "",
  "private": true
}
Este fichero es donde tendrás que indicar que paquetes quieres que se incluyan en tu proyecto y puedes especificar una versión concreta.

Añadir o Actualizar un paquete


Si no usas Visual Studio has de hacerlo vía línea de comando, siempre que necesites añadir o actualizar una librería en tu proyecto tendrás que usar el comando bower install. Por ejemplo, si quieres añadir una versión concreta de Angular a tu proyecto lo podrías hacer con el siguiente comando:
bower install angular#1.4.7
Si quieres añadir la última versión:
bower install angular
Esto descarga la librería en la carpeta bower_components del proyecto. Adicionalmente si queremos dejar constancia en el fichero bower.json del paquete que se ha añadido al proyecto, hubiésemos pasado el parámetro --save.
bower install angular#1.4.7 --save
Actualiza automáticamente la dependencia en el fichero bower.json del proyecto.
{
  "name": "areaTIC Bower Introduction",
  "description": "",
  "main": "",
  "moduleType": [],
  "license": "MIT",
  "homepage": "",
  "private": true, 
  "dependencies": {
    "angular": "1.4.7"
  }
}
Otra opción, sería añadir la librería al bloque dependencies del fichero manualmente y usar el siguiente comando que se encarga de actualizar las librerías del proyecto con la última versión o la versión especificada en el fichero .json.
bower update
Si tienes Visual Studio 2015 instalado, se nota cierta integración con el IDE si abres el fichero .json con el editor y expandes el menú contextual sobre una referencia a un paquete en dependencies.


Para más info sobre comandos y la librería en general recomiendo consultar la doc. oficial.

Hasta aquí el post de hoy, espero sea de utilidad recordaros que aportaciones, dudas, comentarios y demás siempre son bienvenidos en areaTIC. Te animo a participar usando las redes sociales! Hasta la próxima!

miércoles, 19 de agosto de 2015

AngularJS, Cordova, Asp.net - Imagen cámara a api

Hoy veremos un ejemplo sobre cómo tratar una imagen tomada con el plugin de Cámara de PhoneGap y subirlo a una web api usando ng-resource de AngularJS.

La solución que aporto aquí es una opción entre varias posibles, en mi caso quería usar ng-resource para enviar la imagen y no tener que usar el plugin FileTransfer de Cordova / Phonegap. El ejemplo podría ampliarse y mejorarse para controlar el progreso de subida o cancelar una subida en curso… pero bueno comparto código por si a alguien busca algo sencillo que funcione sin demasiada floritura.

Para el código servidor de la API, he descargado este ejemplo de msdn y he aprovechado la parte de web api en concreto la implementación de la acción PostAsync del PicController. Veréis que la api espera contenido de tipo MultiPart Form/Data. Sobre el ejemplo he descartado la parte de AngularJS porque está más trabajado de lo que necesito en mi caso y en el ejemplo usa <input file> mientras que nosotros necesitamos subir un archivo obtenido de la cámara del dispositivo.

En mi escenario quiero enviar en la misma petición a servidor tanto la imagen como su información en el contexto de aplicación, es decir, un objeto pic que contenga información necesaria para clasificar la imagen en el contexto de mi aplicación.

Cliente – ng-Resource

El modo más sencillo de enviar contenido multipart-data a server es usando el objeto FormData de html (como harías en el ejemplo de msdn con <input file>). Con transformRequest podemos crearnos una función donde gestionamos la creación del form e incluimos tanto el fichero como la información.
     app.factory("PicResource", function ($resource) {
        return $resource(
          protocol + "://" + host + "/api/pic/:Id",
          { Id: "@Id" },
          {
              "update": { method: "PUT" },
              "save": {
                  method: 'POST',
                  transformRequest: function (pic) {
                      var formData = new FormData();
                      formData.append("file", pic);
                      formData.append("data", pic.model);
                      return formData;
                  },
                  headers: { 'Content-Type': undefined }
              }
          }
       );
    });


Cliente – Camera

Configuramos el plugin de cámara como data_url.
  function onPictureSucces(image) {
     image = dataURItoBlob("data:image/jpeg;base64," + image);
     image.model = "{'Name': 'test', 'Type':0, 'Default':false, 'ThumbnailURL':'' }";
     picResource.save(photofile).$promise.then(function (response) {
        alert('fichero subido ok');
     }, function (error) {
        alert('se ha producido un error al actualizar los datos');
     });
  }

  function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
       byteString = atob(dataURI.split(',')[1]);
    else
       byteString = unescape(dataURI.split(',')[1]);

       // separate out the mime component
       var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

       // write the bytes of the string to a typed array
       var ia = new Uint8Array(byteString.length);
       for (var i = 0; i < byteString.length; i++) {
          ia[i] = byteString.charCodeAt(i);
       }
       return new Blob([ia], { type: mimeString });
  }


Server

Al ejemplo que hago referencia al inicio de este articulo únicamente he añadido código para desearializar el json de Pic siguiendo las instrucciones del autor del ejemplo de msdn por tanto evito pegar aquí el código.

Espero a alguien le sea de ayuda, cualquier duda o comentario ya sabéis que siempre es bienvenido en areaTIC. Hasta la próxima!

martes, 14 de julio de 2015

Cordova, Android - Depurar en dispositivo

En el post anterior hablamos de Cordova y explicamos como configurar un entorno para generar una apk para un dispositivo Android. Si lo haces, te darás cuenta que dependiendo del modelo del teléfono no siempre funcionan bien todos los plugins. Por ejemplo en mi caso al hacer una foto con la cámara del teléfono desde la aplicación en un móvil Samsung (tiene un par de años) hace que la aplicación se cierre sin más información mientras que en un Xperia relativamente nuevo funciona correctamente.

Ante este escenario surge la necesidad de obtener más información sobre que está pasando y porque narices no funciona el mismo código en diferentes teléfonos!

Con cordova existe la posibilidad de lanzar la aplicación contra un emulador o bien directamente contra un dispositivo conectado vía USB al ordenador. Para ello tendremos que habilitar el teléfono para que permita la depuración USB. En dispositivos android actuales para llegar a esta opción (oculta) tienes que ir a Ajustes/Acerca del dispositivo y pulsar varias veces sobre la etiqueta con el número de modelo... esto hará que se habilite las developer options del dispositivo (depende del modelo, busca como hacerlo para tu móvil).

Una vez superado este punto si conectas el móvil por USB debería reconocerte el dispositivo e instalarte automáticamente el driver adb android... en caso que no se instale automáticamente busca por internet el driver adecuado para depurar con adb en tu dispositivo y fuérzalo.

Para asegurarte que todo está bien deberías poder reconocer el dispositivo si lanzas el siguiente comando:
C:\gd\client>adb devices
List of devices attached
1d178a61        device
A continuación con este otro comando verás como la aplicación ya se ejecuta directamente en el dispositivo conectado, ten en cuenta que en algunos teléfonos si la aplicación ha sido instalada previamente te obliga a desinstalarla antes de continuar:
cordova run android --device
Bien, si necesitas depurar código nativo java porque no está funcionando algún plugin o estás desarrollando alguno por tu cuenta lo mejor es que uses Eclipse con el ADT plugin o Android Studio.

Por otro lado para depurar javascript es algo más tedioso, seguramente podrías llegar a hacerlo pero ya digo que no sería sencillo. En este caso la estratégia es tirar de "chivatos" en un log que pueden ayudarte a localizar problemas. Con cordova tienes la posibilidad de escribir un log usando la instrucción console.log('bla bla'); en tu código js. Esto genera un registro que puedes consultar a la vez que usas la aplicación en tu dispositivo usando adb logcat. Puedes verlo si ejecutas el siguiente comando mientras deployas la aplicación en un dispositivo conectado vía usb.
adb logcat
Si lo haces verás que el log en runtime es completamente ilegible ya que recibes todo tipo de notificaciones que no te interesan, para centrarte en los mensajes de cordova te puede ser útil filtrar el contenido de eventos para que sólo se muestren los logs de Cordova.
adb logcat Cordova:D DroidGap:D CordovaLog:D *:S
Hasta aquí el post de hoy, espero te sea útil! Recuerda que puedes seguir areaTIC en las principales redes sociales, que vaya bien la semana!

lunes, 22 de junio de 2015

Cordova, apk Android

En el post de hoy explico los pasos necesarios para desarrollar una aplicación HTML/Javascript que se instale como una Apk en un dispositivo Android. Como sabéis para crear una aplicación nativa en android es necesario desarrollarla en java. Desde ya hace un tiempo existen frameworks javascript (open source) que permiten desarrollar una aplicación HTML y convertirla en apk. Uno de ellos, quizás el más extendido es Cordova / Phonegap que soporta más plataformas a parte de android entre ellas Windows Phone o IOS.

No necesitas un IDE para realizar la aplicación, aunque podrías usarlo. Comentar que Visual Studio (a partir de 2013) incorpora herramientas para trabajar con Cordova que te pueden facilitar bastante las cosas (punto para MS!).

Por otro lado, para desarrollar la aplicación HTML te recomiendo usar algún framework javascript como Angular aunque no es en absoluto un requisito obligatorio para Cordova... es simplemente por el hecho que si trabajas con Angular te obligarás a implementar algún tipo de patrón y seguir un orden de proyecto similar a lo que harías con C# y MVC (por poner un ejemplo). Otro punto positivo por el que recomiendo usar Angular en este ámbito es que trabaja a la perfección con bootstrap y hay infinidad de modulos open source de la comunidad que han creado componentes cliente listos para incluir en tu proyecto y usar. Llegado este punto si te planteas empezar con cordova te recomiendo echar un ojo a Ionic que integra angular, bootstrap y cordova... y ya existen templates de proyecto para Visual Studio.

Sea cual sea tu decisión, ahora te explicaré los requisitos necesarios para poder generar una apk a partir de tu aplicación HTML (entorno windows).

Necesitarás descargar e instalar cordova, para ello la opción más sencilla es usar node/npm y Git. Sigue los pasos de la documentación oficial, al finalizar la instalación de Cordova CLI si abres una línea de comando te debería reconocer el comando "cordova". En principio si lo instalas siguiendo la documentación oficial automáticamente se añade toda la configuración de variables de entorno. Cordova CLI es una utilidad que te permite crear tu aplicación cliente, añadir plataformas soportadas, gestionar los plugins de cordova, generar la aplicación, lanzarla contra un emulador, etc...

Una vez tenemos cordova CLI configurado instalaremos las herramientas necesarias para poder añadir la plataforma android a nuestros proyectos Cordova. Necesitaremos instalar la versión correspondiente del sdk de android y el jre de java (si descargas la última versión debería funcionarte). Para asegurarnos que lo hemos hecho bien al abrir una linea de comando debería reconocernos el comando java y android. Actualmente cordova va por la versión 5.0.x, en versiones anteriores era necesario instalar Ant ya que interviene en el proceso de build de la Apk, en la versión 5.0.0 no estoy seguro... yo lo he instalado por inercia.

El siguiente paso es crearnos un proyecto con cordova. Para ello hemos de situarnos por linea de comando en el directorio donde queremos generar la aplicación. Yo trabajo sin IDE tiro de CLI, imagino que Visual Studio se encarga de lanzar comandos por debajo pero en todo caso uno u otro tendrá que crear un nuevo proyecto en cordova con el siguiente comando.
cordova create MyProject com.example.mmyproject MyProject
El comando anterior ha creado una aplicación Cordova asociada al directorio donde tenemos el código HTML, dentro del directorio veremos la carpeta www donde ubicaremos nuestra aplicación HTML/js.



El siguiente paso es añadir android como platform con el siguiente comando.
cordova platform add android
Una vez creada la plataforma ya podríamos lanzar el siguiente comando para generar la apk. Esto genera una aplicación sin firmar en la ruta platforms/android/build/output.
cordova build android
Un paso importante para instalar la aplicación en un dispositivo android es firmar la aplicación. Para ello tendremos que ir a la carpeta donde tenemos java instalado (generalmente archivos de programa\java...) y generar un certificado con la utilidad keytool.exe.

Una vez generado el archivo .keystore recomiendo copiarlo en la ruta donde hemos creado el proyecto cordova. El encargado de firmar la aplicación será Gradle en cordova 5.0.0... para decirle a Gradle que tenemos un certificado y queremos firmar la aplicación cuando le pasemos el parámetro -release (al comando cordova build android) necesitaremos crearnos un archivo SigningDefault.properties en la ruta donde tenemos la plataforma de android del proyecto.

Si volvemos a generar la aplicación con el comando cordova build android --release automáticamente la apk quedará firmada y ya se podría instalar en un dispositivo android siempre y cuando habilites en el teléfono que admita apk que no han sido descargadas del market oficial (aplicaciones con origen desconocido).

Hasta aquí el post de hoy, si tienes conocimientos de HTML y javascript pero no conocías cordova ahora ya puedes hacer una app y montarte en el dolar jajajja. Ánimo y suerte! Como siempre recordar que cualquier duda, valoración, comentario o lo que os apetezca decir siempre es bienvenido en areaTIC. Que vaya bien!

martes, 5 de mayo de 2015

Api Management y Api DL (I) - Swagger, Swashbuckle, asp.net web Api

Estos días he estado investigando un poco sobre Api Management a raíz de un trabajo de análisis sobre varias herramientas de este tipo que hay en estos momentos en el mercado.

¿Qué es Api Management?

Es un sistema que facilita la publicación, control de versionado, distribución a subscriptores, monitorización tráfico de diferentes subscriptores y documentación de un conjunto de apis que maneja una compañía. Un sistema de api management por norma general también nos permite definir estrategias de cacheo, políticas de seguridad, analíticas.

Está claro que las api están revolucionando como las aplicaciones interactúan en los últimos tiempos y cada vez más compañías optan por estrategias de este tipo. Api Management nos proporciona un sistema centralizado para gobernar un ecosistema complejo de apis. Por tanto es normal que haya una gran variedad de fabricantes que han diseñado un producto que ofrece este tipo de servicios. Enumero algunos:

Azure, Akana, MuleSoft, Apigee, 3Scale, Ca Technologies, IBM Api Management, WSO2, Mashery, Layer7 (…)

La primera característica que queríamos valorar es como enfoca cada sistema la generación de documentación de uso de la api.

Quien habíamos trabajado con soap, recordamos el mítico wsdl que era un documento que servía a los consumidores de la api para saber que operaciones permite realizar el servicio y ver el modo de interactuar con cada operación. Además con soap existen herramientas para generar un cliente automáticamente en diferentes lenguajes. Bien, con la nueva tendencia REST están apareciendo estándares Api DL (Api definition Languaje) que equivalen a un wsdl en soap y/o frameworks que facilitan diseño, generación automática de documentación e integración de clientes. A continuación enumero algunos:

WADL, RAML, Swagger, Api Blue Print.

Quizás el más extendido en Swagger (o el que más me apetece probar). A continuación veremos cómo diseñar una api con Asp.Net y Swagger. Posteriormente la integraremos con algún producto de api management como el que ofrece Microsoft Azure.

En primer lugar creo una api sencilla con asp.net que se compone de un único recurso Alumno con el típico CRUD.
public class AlumnoController : ApiController
{
    // GET: api/Alumno
    public IHttpActionResult Get()
    {
        return Ok(MockData.Alumnos);
    }

    // GET: api/Alumno/5
    public IHttpActionResult Get(int id)
    {
        Alumno result = (from Alumno a in MockData.Alumnos where a.ID == id select a).FirstOrDefault();

        if (result != null)
            return Ok(result);
        else
            return NotFound();
            
    }

    // POST: api/Alumno
    public IHttpActionResult Post([FromBody]Alumno value)
    {
        MockData.Alumnos.Add(value);

        return Created(string.Format("alumno/{0}", value.ID),value);
    }

    // PUT: api/Alumno/5
    public IHttpActionResult Put(int id, [FromBody]Alumno value)
    {
        MockData.Alumnos[MockData.Alumnos.LastIndexOf(value)] = value;

        return Ok();
    }

    // DELETE: api/Alumno/5
    public IHttpActionResult Delete(int id)
    {
        Alumno toDelete = (from Alumno a in MockData.Alumnos where a.ID == id select a).FirstOrDefault();
        MockData.Alumnos.Remove(toDelete);

        return Ok();
    }
}
Este es el código que uso en clase Mockdata por si queréis seguir el mismo ejemplo, es una simple clase estática.
public static class MockData
{
    public static List Alumnos { get; set; }

    public static void InitData()
    {
        Alumnos = new List();
        Alumnos.Add(new Alumno() { ID = 1, Nombre = "Carlos" });
        Alumnos.Add(new Alumno() { ID = 2, Nombre = "Alba" });
    }
}
Hay varias opciones para integrar Swagger en asp.net web api, tras probar un poco me quedo con Swashbuckle. Para usar Swashbuckle en asp.net podemos añadirlo al proyecto mediante nuget.

Al añadir estos paquetes (swashbuckle.core y swashbuckle.ui) al proyecto veremos que se añade una clase de configuración al proyecto que nos servirá para controlar aspectos relacionados con la documentación de nuestra Api. Ahora a parte del apartado de documentación que ya viene incorporado en la plantilla de web api disponemos de otro apartado Swagger al que ya deberíamos poder acceder si vamos a http://apiUrl/Swagger.





En las imagenes si nos fijamos no compone bien el ejemplo de tipo de respuesta ni aparecen comentarios en las operaciones. Para que Swagger tenga en cuenta los comentarios y anotaciones que hacemos en el código de este tipo deberíamos activarlo en la configuración.
   c.IncludeXmlComments(GetXmlCommentsPath());
Por otro lado hemos de ir a propiedades del proyecto y en la pestaña compilar o build marcar la casilla "Xml Documentation File", veremos que automáticamente propone una ruta para el archivo de configuración. Copiala y se trata que te crees un método GetXmlComments() que devuelva la ruta completa de este archivo (el host también es necesario).

Ahora si vamos a la acción Get del controlador, introducimos comentarios en la firma del método y especificamos el tipo que se devuelve del siguiente modo:
    /// 
    /// Obtiene la lista completa de alumnos registrados.
    /// 
    /// Lista de alumnos registrados
    [ResponseType(typeof(List))]
    public IHttpActionResult Get()
    {
        return Ok(MockData.Alumnos);
    }
Si volvemos a mirar la ayuda vemos que aparecen reflejado.



No profundizo mucho más, si queréis más información sobre la integración de swashbuckle con asp.net web api podéis mirar su GitHub o bien este blog de donde he sacado los pasos para configurarlo. Si miras un poco el código comentado que hay en la clase de configuración de swagger te podrás hacer una idea de las posibilidades que ofrece para definir diferentes versiones, security... http://bitoftech.net/2014/08/25/asp-net-web-api-documentation-using-swagger/

En la segunda parte del post veremos la parte de api management donde usaré Azure como proveedor de este servicio. Como muchos otros fabricantes Azure soporta swagger para importar automáticamente la definición de la api que acabamos de crear, concretamente Azure soporta también WADL y no creo que tarden en añadir soporte para RAML (es una suposición mía, no he revisado doc oficial para ver si está previsto o no). Espero no tardar demasiado en acabar la segunda parte del post, últimamente con la llegada del buen tiempo cuesta un poco más dedicar el tiempo libre a la tecnología... es salir el sol y cambiar el portátil por la cerveza y olivas ;) jajjaja.

Hasta la próxima!! Recordar como siempre que puedes hacernos llegar a areaTIC todo comentario, critica, duda, aportación o lo que sea que será siempre bienvenido.

lunes, 27 de abril de 2015

Asp.net 5.0 Less - Visual Studio 2015

Entre las novedades de Asp.net 5.0 está la integración con Less y Saas. Ambos frameworks sirven para extender Css de modo que permita declara variables, funciones y en definitiva hace un poco más dinámico el trabajar con hojas de estilos y temas.

Less es un framework javascript y Saas está desarrollado originalmente en ruby, ambos compilan Css "extendidos", interpretan la lógica que hemos añadido y el resultado de la compilación es un Css plano que todos los navegadores entienden.

Para entenderlo mejor lo vemos con un ejemplo. Para crear un proyecto Asp.net lo mejor es que descargues Visual Studio 2015 Preview, abre nuevo proyecto, crea un archivo Less:


A continuación pega este código:
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;

#header {
  color: @light-blue;
}
El siguiente paso implica consiste en añadir el compilador less al proyecto, para ello usaremos NPM que es un gestor de paquetes javascript ampliamente conocido por la comunidad que también debuta en Visual Studio 2015. Editaremos package.json para añadir estas lineas:
"grunt-contrib-less": "^1.0.0",
"less": "^2.1.2"
Para descargar los paquetes vamos a la carpeta Dependencys del proyecto, vamos a la carpeta NPM y pulsamos botón derecho/restore packages. Si nos fijamos deberíamos tener los paquetes js en la carpeta NPM. Tenemos que añadir configuración para automatizar la compilación de estos archivos cuando compilemos el site. En este escenario interviene grunt.js que también debuta en Visual Studio. Se trata de añadir este bloque de configuración en grunt.initConfig({}).
//compilar less to css
less: {
    development: {
        options: {
            paths: ["importfolder"]
        },
        files: {
            "wwwroot/css/sample.css": "Less/Sample.less"
        }
    }
}
También en grunt.js pero fuera del ámbito initConfig() añadiremos esta otra línea:
grunt.loadNpmTasks("grunt-contrib-less");
Siguiente paso, nos vamos al menú VIEW/Other Windows/Task Runner Explorer.



Compilamos el proyecto, examinamos el código en cliente con el navegador y nos fijamos en que automáticamente se ha generado el archivo css plano.



Hasta aquí el post de hoy, recordaros que cualquier aportación o comentario en areaTIC es bienvenido. Que vaya bien!!

jueves, 26 de marzo de 2015

Remote Tools Visual Studio, Attach remote process

En ocasiones puede sernos útil depurar un proceso remoto desde Visual Studio. Por ejemplo, en mi caso hemos creado un assembly que contiene un membership personalizado y lo hemos configurado para que se use en varios sites. Con este sistema puedo depurar el código del assembly que se está ejecutando en la instancia de Sharepoint Server que está en otro servidor.

Es bastante sencillo, necesitarás Visual Studio 2013 y tienes que instalar las remote tools que las puedes descargar mediante este enlace.

Una vez lo tienes instalado sigue estos pasos:

  • Reinicia Visual Studio y carga el proyecto con el assembly que necesitas depurar en remoto.

  • Ves al menú debug -> Attach to process en Visual Studio.

  • En la siguiente pantalla en el campo Qualifier selecciona el servidor donde está el proceso al cual necesitas asociar el debugger.


  • Te pedriá credenciales de acceso, una vez introducidas puedes seleccionar el proceso que está ejecutando el assembly que vas a debuggar.

  • Selecciona el proceso que quieras depurar, en mi caso el site de Sharepoint se está ejecutando en IIS por tanto marco “Show processes from all users” y selecciono el proceso w3wp.exe.

  • Asegúrate en el campo Attach To de la imagen que está seleccionada la opción “Native”.

En este momento si todo ha ido bien el proyecto se inicia y empieza a cargar los símbolos, si añades un breakpoint en el código y no muestra ningún warning ya lo tienes… En mi caso al navegar por el site de Sharepoint cuando selecciono un usuario del membership o me autentifico, se para en los breakpoints.

Espera te sea útil, ya que estás aquí recuerda mirar el archivo de areaTIC tal vez puedas encontrar algún post interesante. Hasta la próxima!

jueves, 19 de marzo de 2015

Web Api DataContractSerializer error

Aviso a navegantes, esto es un post de batalla.

Escenario


Realizando llamadas a una webapi al devolver un tipo complejo tienes problemas de serialización y salta una excepción similar a esta.

'System.Data.Entity.DynamicProxies.XXX_7633E4D7A7997E6C5CA3E4205926A0AEB77203C4D81CA9E9B8FB1A1BFC64F93A' with data contract name 'XXX_7633E4D7A7997E6C5CA3E4205926A0AEB77203C4D81CA9E9B8FB1A1BFC64F93A:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Causa


Problema de serialización.

Solución


Cambia la firma del método para devolver un objecto de tipo IHttpActionResult (en general trabajando con apis todas las acciones deberían devolver un objeto que implemente esta interfaz). En la acción si te dispones a devolver Json cambia la respuesta por un código similar a este.
public IHttpActionResult Get()
{
   //Do Something
    return Json(responseObjectToSerialize);
}

Hay formas de controlar la serialización a partir de configuración de la api por si necesitas algún comportamiento especial a nivel de performance o controlar algún aspecto de la serialización… sino es así no te líes y aplica la solución de más arriba.

Otra consideración es que estamos devolviendo objetos, que siendo puristas, son entities que uso para el acceso a datos, por tanto no deberían viajar en la comunicación entre cliente y api.

Posiblemente hayas llegado a areaTIC Googleando a partir del texto de error… en ese caso espero que la solución que te paso ayude! Ya que estás aquí recuerda guardar nuestra url en favoritos que cuando estamos inspirados hacemos algún articulo interesante.

Que vaya bien!

lunes, 2 de marzo de 2015

Sharepoint, FBA, Custom Identity Provider

Estos días he estado haciendo unas pruebas de concepto para ver el modo más sencillo controlar y personalizar el proceso de autenticación de usuarios en Sharepoint 2013.

¿Para que podría servirte la información que comparto en este artículo?

  • Imagina que dentro de la infraestructura de aplicaciones o servicios que trabajas tienes un IDP y quieres integrar Sharepoint como un servicio más dentro de la plataforma. El mismo ejemplo aplica si en vez de tener el membership en un IDP quieres que persista en una base de datos SQL o un archivo XML o …

  • Quieres conocer un poco más sobre como funciona el proceso de autenticación de usuario en Sharepoint Server.

Antes de empezar a ver la propuesta sobre cómo hacerlo veamos algunos conceptos de security en Sharepoint.

En sharepoint cuando hablamos de autentificación no sólo se limita a usuarios, sino que las apps también necesitan autentificarse y por otro lado los servicios que corren en la granja también requieren autentificación a través del ecosistema de Sharepoint. En este post sólo nos centramos en autentificación de usuarios que acceden a un portal Sharepoint.

Cuando creamos una aplicación web desde la administración central podemos escoger entre Windows Claims, Form-Based Claims (FBA) o Trusted identity Provider (SAML trusted identity provider). A priori, la identidad está basada en claims en Sharepoint y para acceder necesitas un token. En esta versión ya no puedes configurar seguridad clásica (sin claims) mediante el site de administración, aunque podrías llegar a configurar mediante powershell seguridad clásica (Windows, Forms sin claims ya no está soportado en esta versión). Si lo hicieses ten en cuenta que hay servicios internos en Sharepoint que sólo soportan ya identidad basada en claims por tanto es posible que no todo funcione como debería si usas un tipo de autenticación clásica en 2013.

Sharepoint se encarga de convertir la identidad a claims una vez te autentificas contra la aplicación web en cuestión. Por ejemplo, si tenemos un site configurado como Windows Claims y marcamos que soporta NTML y Kerberos el usuario que acceda al site mediante un browser introducirá sus credenciales cuando el navegador las solicite, en primera instancia se realiza una autentificación contra el proveedor de identidad que en este caso sería windows (Active Directory, no ADFS!) y en segunda instancia Sharepoint internamente transforma la identidad a windows claims identity...

Si queréis información detallada consultar https://technet.microsoft.com/en-us/library/jj219571.aspx. Aquí podéis ver videos que muestran el proceso de autenticación para windows, fba o trusted idp. Matizar que en la versión Server OnPremise no es necesario configurar el rol ADFS en tu dominio local sino que en Sharepoint hay componentes capacitados para transformar WindowsPrincipal a ClaimsPrincipal y generar el token en cuestión (STS).

Bueno, ya estamos un poco más ubicados. Como has visto si quieres delegar el proveedor de identidad a un servicio externo a Sharepoint puedes hacerlo con los servicios de federación de sharepoint pero necesitarás que el proveedor de identidad soporte SAML y configurarlo para que se "entienda" con Sharepoint. Os paso un articulo donde explican como hacerlo en un Sharepoint 2013 onpremise y ThinkTeckture 2.0. En el escenario donde estoy trabajando se está desarrollando una plataforma de servicios donde hay un proveedor de identidad que no soporta SAML, así que en primera instancia lo que se nos ocurre es ver si es posible configurar un membership personalizado donde tengamos el control... esto nos permite controlar puntos clave como por ejemplo cuando Sharepoint pide validar las credenciales o cuando sharepoint accede al membership para mostrar una lista de usuarios, etc. Si tenemos control de estos puntos nosotros podemos implementar la comunicación contra el idp.

Básicamente lo que has de hacer es crear una aplicación web nueva o extender la que tengas por defecto configurándola para que acepte Forms Based Authentication desde la administración central. (No haría falta windows basic authentication!)


Por otro lado tendrás que crearte un assembly e implementar las clases abstractas MembershipProvider y RoleProvider (en mi caso sólo he implementado MembershipProvider). Si buscas en CodePlex CustomFBA verás ya ejemplos que puedes descargar desarrollados para 2010 pero que funcionan en 2013. Estos ejemplos dan persistencia al membership usando SQLServer que dado el caso podría ser lo que estés buscando...

El siguiente paso es modificar los archivos web.config de los 3 sites que intervienen en este proceso:
  • Configurar Form membership provider + people picker en la web configurada como FBA
  • Configurar Form membership provider + people picker en la web de administración central
  • Configurar Form membership provider en el site que hospeda el servicio STS

Ejemplo web.config (picker):
<PeoplePickerWildcards>
   <clear />
   <add key="AspNetSqlMembershipProvider" value="%" />
   <add key="areaticmembership" value="%" />
</PeoplePickerWildcards>
Ejemplo web.config (membership):
<system.web>   
  <membership defaultProvider="i">
      <providers>
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        <add name="areaticmembership" type="areaTICCustomFBA.areaTICCustomMembershipProvider, areaTICCustomFBA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=20a4d37db65e35ac" />
      </providers>
    </membership>
    <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
      <providers>
        <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      </providers>
    </roleManager>
</system.web>
Ten en cuenta que en el web.config de STS no existe la sección system.web, tendrás que crearla.

Para poder vincular el assembly con tu custom membership tendrás que firmarlo y obtener el código de assembly, si necesitas info sobre como hacerlo te dejo un enlace útil. Falta un paso que es copiar el assembly en los sites... te recomiendo registrarlo en la GAC del servidor/es.

Pues ya lo tienes, si todo ha ido bien al acceder al site te saltará la pantalla de login por defecto. Llegado a este punto te recomiendo configurar Visual Studio para depurar el proceso remoto de Sharepoint, puedes hacerlo instalando las herramientas de depurar en remoto con este enlace https://msdn.microsoft.com/en-us/library/bt727f1t.aspx. Una vez estés depurando el proceso remoto si en el formulario de inicio FBA seleccionas Forms Authentication, introduces unas credenciales y pones un breakpoint en el método ValidateUser podrás seguir el proceso.

Un tema adicional pero interesante es crearte un httpmodule en un assembly, firmarlo como has hecho con este del membership, registrarlo como httpmodule en el site FBA y a STS y entonces puedes poner breakpoints y comprobar el principal del request para ver como va "mutando" automáticamnente de tipo FormsPrincipal a ClaimsPrincipal. No aporta demasiado pero permite comprobar y entender lo que se explica en los videos de technet.

Hasta aquí el post, recuerda que puedes seguir areaTIC a través de las redes sociales y participar en cualquier debate con comentarios. Hasta la próxima!

martes, 3 de febrero de 2015

SQL Server: autenticación mediante un grupo de Active Directory

Como imagino ya sabéis

SQL Server

nos permite dos tipos de

autenticación

, Windows y

SQL Server

. Por temas de seguridad es recomendable utilizar

autenticación

de Windows así que en la mayoría de los casos te sueles encontrar que se van creando en

SQL Server

inicios de sesión para cada uno de los usuarios de Windows. Bien, esto funciona pero resulta bastante complicado de mantener, es más sencillo si creamos un grupo de

Active Directory

, creamos un inicio de sesión para este grupo en

SQL Server

y luego desde

Active Directory

añadimos/quitamos los usuarios que pertenecen al grupo. Si hay diferentes niveles de seguridad dentro de

SQL Server

crearemos distintos grupos en

Active Directory

y asignamos el usuario al grupo que le corresponda. Lo comentando anteriormente, además de ser más simple de gestionar, facilita los procesos de recertificación de usuarios si trabajamos dentro de normas como la

ISO 27001

.

A continuación os detallo los pasos que deberíamos dar:

  • Creamos un grupo en

    Active Directory

    , por ejemplo “Grupo Informatica”; asignamos a este grupo todos los usuarios que deban tener acceso a

    SQL Server

    .

  • Abrimos el SSMS, vamos al grupo Seguridad - Inicios de Sesión y creamos un nuevo inicio de sesión.

    SQL Server - Autenticacion AD, crear inicio de sesión

  • Nos aseguramos que esté seleccionada la opción "Autenticación de Windows" y pulsamos sobre el botón Buscar para localizar el grupo en cuestión.

    SQL Server - Autenticacion AD, buscar grupo

  • Pulsamos sobre “Tipos de objetos” y nos aseguramos que esté marcada la opción “grupos”; aceptamos.

    SQL Server - Autenticacion AD, seleccionar grupo

    SQL Server - Autenticacion AD,tipos de objetos

  • Pulsamos sobre ubicaciones y nos aseguramos que esté seleccionado “Todo el directorio”.

    SQL Server - Autenticacion AD, ubicaciones

  • Introducimos el nombre del grupo.

    SQL Server - Autenticacion AD, comprobar nombres

  • Pulsamos sobre “Comprobar nombres” para asegurarnos que la selección del grupo es correcta. Si lo es, nos aparecerá subrayado.

    SQL Server - Autenticacion AD, grupo seleccionado

  • Aceptamos y volvemos a la pantalla de inicio de sesión. Acabamos de configurar las características del nuevo inicio de sesión: roles, bases de datos con acceso, estado del inicio de sesión,… .

    SQL Server - Autenticacion AD, inicio de sesión creado

  • A partir de este momento todos los usuarios del dominio que pertenezcan al grupo “Grupo Informatica” tendrán acceso a

    SQL Server

    a través del inicio de sesión creado y con los permisos en él establecidos. La actividad en el servidor la veremos desglosada por usuario de dominio, no del grupo, lo que nos sigue permitiendo ver quién realiza cada acción. Tal como comentaba anteriormente, el configurar el acceso a través de un inicio de sesión y un grupo (o varios si hay diferentes niveles de acceso) es más fácil de mantener y controlar que el tener un inicio de sesión por cada usuario de dominio.

Si queréis obtener más información y detalles sobre los métodos de autenticación de

SQL Server

podemos acudir al siguiente artículo del MSDN . Y hasta aquí el artículo de hoy, espero que os pueda resultar útil; recordad que dentro de

areaTIC

podéis encontrar otros artículos interesantes, no dudéis en consultar nuestro archivo, también podéis seguirnos por RSS o las principales redes sociales (twitter, facebook, linkedin...).


LECTURAS RELACIONADAS RECOMENDADAS POR AREATIC.NET

martes, 27 de enero de 2015

VMware-Windows: No images are available

En un pc con windows 7, VMware versión gratuita me dispongo a crear una máquina virtual con Windows Server 2012. Al crear la máquina con la opción de crearla a partir de la ISO del sistema operativo a media instalación me sale esta pantalla con el mensaje No images are avaible:

areaTIC:VMware-Windows: No images are avaiable

Para solucionarlo y poder seguir con la instalación voy al menú de VMware, Player -> Manage -> Virtual Machine Settings (Ctrl + D). Una vez en la configuración, en la pestaña General sitúate sobre la opción "Floppy Disk" y en la sección connection selecciona la opción "Auto Detect".

areaTIC:VMware-Windows: No images are avaiable floppy solution

Si vuelves a arrancar la máquina debería dejarte seguir con la instalación.

Espero te sea de utilidad, recuerda que puedes seguir areaTIC si lo deseas en las principales redes sociales y todo comentario, aportación o corrección es bien recibida! Que vaya bien.

sábado, 17 de enero de 2015

Asp.Net WebApi: IOC, IdependencyResolver, N Tiers

A partir de la versión 2 del producto asp.net web api incorpora IdependyResolver. Esta interfaz nos permite realizar una implementación personalizada de un DependencyResolver y asignarlo a la configuración de la API.

Esto facilita usar un contenedor IOC en este tipo de proyectos implementando un dependency resolver. Hasta ahora los fabricantes de IOC tenían que proporcionar algun tipo de sistema para que el contenedor persistiese en el ciclo de vida de la aplicación web y se integrase en el pipeline de las peticiones para así poder inyectar los tipos necesarios al instanciar controladores.

Ahora podríamos implementar nuestro DependencyResolver usando un IOC container de terceros y asignarlo a la configuración de la api, de este modo es el mismo framework web api el que se encarga de gestionar la inyección de dependencia con ayuda del resolver.

Os paso un articulo donde está explicado como implementar la inyección de dependencia en controladores en una web api con unity. Aquí usan UnityResolver que puedes descargar de nuget.

Asp.net -> Dependency Injection

Este sistema, por defecto, propone registrar las dependencias de modo programático. Has de tener en cuenta que si la web api es la punta del iceberg de una arquitectura N Tier con varios niveles como una DDD podrías llegar a tener alguna limitación con este sistema que se plantea.

En una arquitectura de este tipo la api tendrá acceso a una capa de negocio y la capa de negocio tendrá acceso a una capa de datos.



Desde la api no tendrás acceso a la capa de datos, o no deberías!!. Si la configuración de las dependencias se está llevando desde el archivo webapiconfig.cs, allí necesitarás registrar el tipo explícitamente en el contenedor IOC (...) ¿Qué pasa si quieres registrar un tipo en el contenedor que pertenece a la capa de datos? Mírate este artículo, propone hacerlo con MEF y explica los pasos para hacerlo. Lo tengo implementado y funciona OK.

Developer.com -> Depedency Injenction Best Practices in an N Tier modular Application

En resumen, con este sistema que se plantea tendrías la configuración organizada de este modo:

WebApiConfig.cs -> public static void Register(HttpConfiguration config)
   //IOC
    var container = new UnityContainer();
    ModuleLoader.LoadContainer(container, ".\\bin", "areaTIC.*.dll");
    container.RegisterType<IGenericFacade<User>, GenericFacade<User>>();
    config.DependencyResolver = new UnityResolver(container);
ModuleInit.cs -> (tenemos un ModuleInit en cada nivel, aquí business)
    [Export(typeof(IModule))]
    public class ModuleInit : IModule
    {
        public void Initialize(IModuleRegisterType iocContainer)
        {
            //register types here.
            iocContainer.RegisterType<IGenericRepository<User>, GenericRepository<User>>();
        }
    }
En este ejemplo he usado Unity pero podrías usar otros, te paso una serie de artículos interesantes a modo de comparativa que podrían ayudarte en un momento determinado a escoger fabricante de IOC:

ElegantCode -> Comparativa IOC
Curah -> Unity Vs other IOC Containers

Espero os resulte útil el post, cualquier debate, apreciación, duda y demás ya sabes que puedes hacérnosla llegar a través de comentarios o redes sociales. Hasta la próxima!

viernes, 9 de enero de 2015

Asp.Net WebApi: Route con parámetros opcionales

Buenas, el articulo de hoy es cortito, conciso y posiblemente un poco trivial para quien esté acostumbrado a trabajar con webapi. Se explica como definir parámetros opcionales en una acción de un controlador tipo ApiController y como enrutarlos.

Imagina que necesitas enrutar esta acción:
[ResponseType(typeof (IEnumerable<UserFriendDTO>))]
public IHttpActionResult Get(int userId, bool? pending)
En primer lugar comentar que por defecto el template de proyecto WebApi que ofrece .net ya te enruta el Get con un parámetro Id (...) sin necesidad de definir ninguna ruta adicional. En este caso no me interesa filtrar un Get de UserFriend por Id del recurso sino que me interesa filtrar por UserId que es un atributo del recurso UserFriend y además me gustaría en algunas ocasiones decirle que sólo me devuelva las solicitudes pendientes de un usuario concreto...

En segundo lugar comentar que es un ejemplo poco RestFul, tal vez en este caso sería más correcto renombrar el recurso UserFriend a Friend y hacer algo así como Users/4/Friends?... pero bueno no lío más la cosa como ejemplo para el tema de opcionales en la acción ya valdría.

Tal y como tenemos esta acción nunca resolvería esta llamada, recibirás un Not Found.
api/UserFriend/4?pending=true
Veamos cual sería el modo correcto de hacerlo:
[ResponseType(typeof (IEnumerable<UserFriendDTO>))]
[Route("api/UserFriend/{userId}")]
public IHttpActionResult Get(int userId, bool? pending = null)
Esta acción queda asociada de este modo a estas 2 rutas:
api/UserFriend/4?pending=true
api/UserFriend/4
Ahora puedo decirle que me devuelva todas las solicitudes de un usuario concreto (sin pasar ningún valor en pending), que me devuelva sólo las pendientes (pending = true) o que me devuelva sólo las que están resueltas (pending = false).

Es importante que los parámetros opcionales los marquemos como nullable y además le asignemos un valor por defecto en la misma firma de la acción como veis en el segundo ejemplo.

Hasta aquí el primer articulo del año, recordar que podéis seguir areaTIC en las redes sociales y vuestros comentarios, criticas, correcciones o insultos (jajjaja) son bienvenidos.

Hasta la próxima!