Webcast. Segunda Charla con los expertos: Todo lo que quisiste saber sobre SharePoint, pero no te atreviste a preguntar

Desde SUGES y el resto de grupos latinoamericanos de SharePoint os proponemos una nueva edición de Charla con los Expertos de SharePoint de habla hispana el próximo 10 de abril a las 15:00 (horario de Londres). En esta ocasión como novedad tendremos un cambio de plataforma tanto a nivel de registro para el chat como para asistir el mismo:

Para el registro, accede a Eventbrite: http://charlasharepoint.eventbrite.com/?aff=blogadiaz

El Webcast será con Lync Online y para facilitar vuestra asistencia, gracias a nuestra compañera Vielka Rojas disponemos de un pequeño how-to para participar en la reunión utilizando Lync: http://vkrojas.wordpress.com/2014/02/26/como-atender-una-reunion-con-lync-web/

Preparen las preguntas que quedan 10 días para esta sesión.

 

SharePoint. Despliegue de una Single Page Application (SPA)

Una SPA o Single Page Application es una aplicación web que se ejecuta siempre en la misma página, buscando mejorar la experiencia del usuario que no sufre la navegación entre páginas o las tan odiosas recargas de página o Postback. Combinando HTML5, CSS y JavaScript se va renderizando el contenido, posiblemente pre-cargado, que el usuario solicita en cada momento de una forma más dinámica, sin necesidad de navegar o cambiar la URL base de acceso a la aplicación. Por si no os habéis dado cuenta, SharePoint 2013 usa este concepto, lo podemos ver cuando accedemos a un sitio de colaboración, la mayoría de los enlaces están bajo la URL start.aspx y no recargan la página, tan solo se renderiza el contenido que solicitamos.

La idea es ¿Por qué no usar este concepto de aplicación para implementar nuestras soluciones de SharePoint? Los desarrolladores de SharePoint siempre nos hemos quejado porque incluir buenas prácticas o patrones de diseño en nuestras soluciones es altamente complejo, pero no imposible, y os lo voy a demostrar.

Existen diversos Frameworks JavaScript que nos permiten implementar una SPA, como Knockout, Angular o Backbone. Por ejemplo, Backbone nos permite aplicar el patrón MVC (Modelo-Vista-Controlador) y es posible hacerlo en una Aplicación o Solución de SharePoint.

Para los que no conozcan este patrón, básicamente y de una forma rápida, distribuimos nuestro código en tres patas:

  • Modelo que representa los datos de dominio o la lógica de negocio
  • Vista que nos permite visualizar el modelo
  • Controlador que recibe las acciones del usuario y actualiza el modelo

 

Con Backbone es muy sencillo implementar el Modelo, las Vistas y el Controlador, que en Backbone lo representa las Rutas, empaquetar todo en un fichero JavaScript de aplicación y desplegarlo en SharePoint. Adiós a nuestro código espagueti y demos la bienvenida al maravilloso mundo del buen código.

Usando Backbone y el servicio REST de SharePoint seremos capaces de crear aplicaciones SharePoint y que nuestro código cumpla con los estándares actuales del mercado. Veamos un pequeño ejemplo:

Modelo

Item = Backbone.Model.extend({

defaults: function () {

return {

id: -1,

title: null

}

}

});

Vista

AppView = Backbone.View.extend({

 

el: $(«#app»),

 

events: {

«click #addItem»: «addItem»

},

 

addItem: function () {

var item = {

title: this.newItemName.val()

};

 

itemList.create(item);

 

this.newItemName.val(»);

},

 

initialize: function () {

this.newItemName = this.$(«#itemName»);

 

this.listenTo(this.model, ‘change’, this.render);

this.listenTo(this.model, ‘add’, this.render);

},

 

render: function () {

$(«#itemList»).html(«»);

if (this.model.length) {

for (var i = 0; i < this.model.length; i++) {

var view = new ItemView({ model: this.model.at(i) });

$(«#itemList»).append(view.render().el);

}

}

}

});

 

ItemView = Backbone.View.extend({

template: _.template($(‘#item-template’).html()),

 

initialize: function () {

this.listenTo(this.model, ‘change’, this.render);

this.listenTo(this.model, ‘destroy’, this.remove);

},

 

render: function () {

this.$el.html(this.template(this.model.toJSON()));

return this;

}

});

Controlador

var router = Backbone.Router.extend({

routes: {

»: ‘home’,

‘new’: ‘viewNew’

},

home: function () {

itemList = new ItemSet();

 

itemList.fetch({ data: { page: ‘no’ } });

 

var app = new AppView({ model: itemList });

app.render();

},

viewNew: function () {

 

}

});

Os recomiendo echar un vistazo al proyecto Backbone.SharePoint que añade una capa de abstracción entre SharePoint y nuestro modelo.

¿Cómo desplegar una SPA en SharePoint?

Tenemos varios modos de despliegue para este tipo de aplicaciones en SharePoint:

  • Mediante el nuevo modelo de Aplicación de SharePoint, en cualquiera de sus modos de alojamiento. La URL de acceso a la aplicación sería la URL de la Aplicación.
  • Con una página desplegada en el PageLayout de SharePoint. La URL sería http://sitio/_layouts/15/SPA/app.aspx
  • Con una página desplegada con un módulo en una biblioteca o en el root de SharePoint. Con una URL parecida a http://sitio/app.aspx o http://sitio/aplicaciones/app.aspx que desde el punto de vista del usuario, aparenta una mejor integración con lo que conoce como su SharePoint.

La idea es que el usuario acceda a una URL donde empezamos a hacer la magia y ejecutamos nuestra aplicación SPA mediante JavaScript, que utilicemos el servicio REST de SharePoint como back-end con los datos almacenados en listas o bibliotecas y que la experiencia de usuario sea similar a una aplicación de escritorio, tal como SharePoint 2013 implementa en algunos casos.

 

Saludos a todos…

NuGet. Repositorio local de paquetes

Desde hace ya algunas versiones de Visual Studio, tenemos una herramienta disponible, llamada NuGet, que nos permite administrar los paquetes de librearías de .NET, asociados a nuestro proyecto o solución de código.

Desde la consola de NuGet podemos buscar e instalar las librearías necesarias para el desarrollo de nuestra solución. Estas librearías pasan por agregar referencias a ensamblados, añadir ficheros JavaScript, plantillas de proyectos, y un largo y numeroso mundo de posibilidades. Estas librerías se obtienen, por defecto, del repositorio oficial nuget.org que mantiene la fundación Outercurve patrocinada por Microsoft, entre otras compañías que colaboran con las galerías de código abierto que gestionan.

Pero no nos quedemos sólo con este repositorio y aprovechemos el potencial que nos ofrece para publicar en un repositorio local las librearías que usamos en nuestros desarrollos. Si, esas librearías de acceso a datos, de gestión del Blob Storage de Azure o de consulta de SharePoint. ¿Por qué no las empaquetamos y las ponemos a disposición de todos los proyectos? De una forma simple, podríamos gestionar versiones, controlar requisitos, configuraciones, etc.

Este repositorio de paquetes NuGet puede ser una carpeta local o de red o un servidor de NuGet, como si del repositorio oficial se tratara. Por ejemplo, una opción muy válida sería tener una carpeta en TFS donde se publican los paquetes, con lo que cada desarrollador podría tenerla sincronizada y configurar el repositorio como carpeta local.

 

Para crear un paquete podemos utilizar la aplicación de NuGet.exe o un Explorador de Paquetes, con lo que nos podríamos plantear incluir en nuestro servidor de Builds la generación del paquete NuGet correspondiente a la versión actual de nuestra librearía, con un comando tan sencillo como:

nuget pack MyProject.csproj Prop Configuration=Release

Este comando, crea un paquete NuGet con los ensamblados y sus dependencias del proyect MyProject.csproj, pero deberíamos de pensar en más y en un paquete podemos incluir lo siguiente:

Al final, vamos completando nuestro repositorio local con las librearías más empleadas y manteniendo un control de versiones de la misma

 

Aprovechemos todas las ventajas que nos ofrece NuGet para gestionar nuestras librearías y las librearías de terceros. Con esto, cuando corrijamos un bug, tendremos una notificación de actualización, como las obtenemos del repositorio oficial, y mejoraremos nuestros procesos de desarrollo.

 

Saludos a todos…

SharePoint 2013. Una Provider-Hosted que no es una Provider-Hosted

Como ya sabemos todos, SharePoint 2013 implementa un nuevo modelo o paradigma de desarrollo denominado Aplicaciones. En este nuevo modelo se ha pensado bastante en la seguridad y el acceso a la información de SharePoint y es por esto por lo que sólo podemos usar el modelo de objetos de cliente (CSOM), con las limitaciones que esto conlleva.

 

Teniendo claras estas limitaciones, se abre un mundo de posibilidades donde nos encontraremos todo tipo de desarrolladores (no sólo los que sabemos SharePoint) y en el que incluimos la necesidad de movilidad y las soluciones implementadas en la tan beneficiosa nube. En Encamina este concepto lo llamamos SharePoint Everyware, buscando la sinergia entre «Ágil» y «Enterprise» y aprovechando SharePoint como capa de servicio para las Aplicaciones que nos demandan los clientes.

El reto que se nos plantea es: ¿Cómo podemos saltarnos esas limitaciones pero manteniendo el concepto y diseño de Aplicación?

Adrián Díaz y un servidor llevamos unos días haciendo pequeñas pruebas de concepto, buscando una arquitectura desacoplada, al igual que las Aplicaciones, pero que nos permita el uso del modelo de objetos de servidor (SSOM), patrones del tipo Repository o Service Locator, TDD o Integración Continua.

Planteamos dos modelos:

  1. Usar un servicio WCF instalado dentro de SharePoint con Microsoft.SharePoint.Client.Services y que este sea nuestro punto de entrada REST para las peticiones, lo que nos obliga a buscar algún modo de meter un contenedor de dependencias dentro del proceso de SharePoint.
  2. Usar Web Api en una aplicación web externa a SharePoint (los intentos de modificar las tablas de enrutamiento y poner Web Api dentro del ciclo de vida de las llamadas de SharePoint no obtuvieron buenos resultados) que nos permita trabajar independientemente de nuestra capa de servicio, que para la mayoría de los casos será SharePoint, y en la que sería muy sencillo implementar las buenas prácticas que esperamos en nuestros desarrollos, similar al concepto Provider-Hosted que tenemos en Aplicaciones.

¿Qué problemas nos encontramos?

  • En el servicio WCF no sería sencillo ser independientes de SharePoint e implementar un contenedor de dependencias nos obliga a tener un HttpModule recibiendo todas las peticiones de SharePoint y gestionando el ciclo de vida de este contenedor.
  • ¿Qué pasaría si necesitamos tener una capa de servicio que obtenga información de SharePoint y de un repositorio externo, por ejemplo, un servicio en Azure o una base de datos? ¿Tenemos claro que vamos a meter esas llamadas dentro del proceso de ejecución de SharePoint? Es posible, pero nunca me ha gustado hacer esas cosas dentro del código que se ejecuta en SharePoint.
  • Si usamos Web Api, ¿qué hacemos con la autenticación? ¿cómo garantizamos la seguridad de acceso al servicio y que las llamadas a SharePoint se hagan con el contexto del usuario adecuado? Si implementamos Autenticación Integrada, obligamos a realizar doble autenticación a los usuarios, una en SharePoint y la otra en la Web Api pero ¿y si estamos en un ordenador o Tablet fuera de dominio? Está claro que no podemos acceder a la Web Api sin tener las credenciales ni la autenticación del usuario frente a SharePoint.

Posibles soluciones

Para el caso del WCF, tenemos varios ejemplos que nos permiten gestionar (siempre mediante un HttpModule) estos contenedores con Ninject o Autofac, y el problema de hacer llamadas a servicios externos es más algo personal que una limitación técnica.

La solución para la Web Api no es tan simple. Pensemos en el modelo que intentamos replicar, el Provider-Hosted (de ahí el título de este post). Cuando SharePoint hace una llamada a una Aplicación siempre le pasa la información del contexto actual y un Token que permite abrir un contexto de cliente sin necesidad de tener las credenciales del usuario. Tenemos disponible una clase, TokenHelper, que tiene los métodos para leer los Token y abrir un ClientContext, pero nosotros necesitamos un contexto de servidor y no de cliente. Si conseguimos salvar este problema y recibir algún tipo de Token que permita abrir un contexto de servidor, espera, ¿no podemos abrir un SPSite usando la URL del Site y un objeto SPUserToken? Pues va a ser que sí, ahora toca obtener ese Token desde las distintas interfaces de usuario de nuestra Aplicación y dárselo a la Web Api para que pueda hacer peticiones a SharePoint en nombre del usuario.

Estaba claro que obtener el Token tampoco iba a ser sencillo y que no lo íbamos a tener directamente en el contexto de JavaScript de SharePoint pero si en el contexto de servidor: SPContext.Current.Web.CurrentUser.UserToken. Tenemos que ser capaces de enviar ese Token a cualquier llamada a la Web Api para que instancia un contexto de servidor con el usuario actual de SharePoint, pero ¿cómo? Si lo que queremos es que, al igual que el modelo de aplicaciones, en SharePoint no tengamos código de servidor o tengamos lo mínimo indispensable.

WCF al rescate! Bajo la seguridad de SharePoint, desplegamos un servicio WCF que devuelve única y exclusivamente el Token del usuario actual, que usaremos para hacer las llamadas a la Web Api. Algo tal como lo pintamos en el siguiente esquema:

 

  1. Nuestra Aplicación, que puede estar en SharePoint o no, necesita hacer primero una petición al servicio de WCF que le devuelva el Token del usuario actual. Para el caso de que no estemos en el contexto de SharePoint, esa llamada conlleva un proceso previo de autenticación de usuario en SharePoint.
  2. El servicio WCF obtienen el SPUserToken del usuario actual y se lo devuelve a la Aplicación.
  3. Hacemos la llamada a la Web Api, enviando correctamente serializado el SPUserToken para que este pueda abrir un contexto de servidor con las credenciales del usuario actual.

Al final, nos hemos encontrado con un proceso muy similar al que se ha implementado en las Aplicaciones de SharePoint y hemos construido una No-Provider-Hosted adecuada al paradigma de desarrollo que queremos implementar y necesario para nuestro SharePoint Everyware.

 

Saludos a todos…

Off Topic. Realizar cosas importantes desde el lugar donde más nos gusta vivir

Para los que ya me conocen, vivir en Tenerife es importante para mí, y aunque sea un punto flotante del Atlántico, eso no quiere decir que no piense en dejar mi granito de arena en el mundo y hacer cosas importantes.

Con esta filosofía me han acogido en Encamina, un gran familia que quiere hacer cosas importantes para el planeta pero desde su ciudad, Sagunto.

 

Después de unos grandes 8 años en General de Software, empiezo este nuevo reto en Encamina aportando mi ADN a su proyecto de ser líderes en el ecosistema Microsoft para el ámbito nacional y ser, algún día, un referente internacional en soluciones y servicios de nicho a través de la nube.

Agradecer a todos los compañeros y amigos de GSC, que tantos años me han soportado y espero que sepan que pueden contar conmigo para todo lo que pueda ayudar.

Trabajaré desde casa, aunque mi base operativa será Sagunto, y espero cumplir con las expectativas que han puesto en mí y conseguir superar todos los retos que tenemos en marcha en Encamina.

 

Saludos a todos…