Microsoft Partner Network (MPN)

Como muchos de vosotros ya sabréis, el día 29 de Octubre se lanzo Microsoft Partner Network (MPN). Después de más de un año en transición, los nuevos niveles y los nuevos requisitos por competencias se exigirán a partir de esa fecha para los partners nuevos y para aquellos que tengan que renovar a partir de la fecha de lanzamiento del nuevo Partner Network (hasta la fecha de renovación se mantendrá el nivel y beneficios que se ostentará en el MSPP). MPN sustituye al antiguo Micrososft Partner Program (MSPP) que se lanzó hace 8 años.

Este cambio potencia la especialización y la diferenciación, y responde a la demanda, tanto de clientes, como de partners. El programa tiene los siguientes niveles: Gold, Silver, Subscription y Community, y 30 competencias (Virtualización, Business inteligence, Application Platform, ISVs…).

Hay cambios en cuanto a los requisitos de las competencias tanto para el nivel Silver (antiguo Certified) como para el nivel Gold. Desde el punto de vista de los ISVs supone la incorporación de nuevas certificaciones de productos válidas para los dos niveles.

Para conseguir la competencia ISVs en el nivel Silver se solicitará una aplicación certificada con uno de los siguientes test:

  • Windows 7 Platform Ready
  • Windows Server 2008 R2 Platform Ready
  • Windows Azure Platform Ready
  • SQL Azure Platform Ready
  • Microsoft Surface Test

Los test que hasta ahora tuvierais hechos serán validos para la competencia hasta Mayo de 2011, pero es momento de ir alineándose con los nuevos requisitos. Ya puedes realizar los nuevos Test a través de Microsoft Platform Ready de forma rápida, sencilla y sin ningún coste para el partner.

http://www.microsoftplatformready.com/spain/home.aspx

A parte de ISVs, hay otras competencias que permitirán la certificación de una aplicación para obtenerla en su nivel Silver.

  • Application Integration  =  Windows Server 2008 R2 Platform Ready
  • Data Platform  =  SQL Server 2008 R2 Platform Ready
  • Business Intelligent  =  SQL Server 2008 R2 Platform Ready
  • Content Management   =  Sharepoint Server 2010 Platform Ready (proximamente disponible)
  • Unified Communication  =  Unified Communicatios Platform Ready ( aun no disponible)

Para aquellos que queráis optar a la competencia Gold de ISVs los test que se solicitaran son:

  • Certified for Windows Server 2008 R2 o
  • Windows 7 Logo Test

En fin, si queréis más información, no dudéis en acceder a la url indicada anteriormente pero, si sois partners de Microsoft y todavía no os habéis puesto al día en cuanto a competencias se refiere, es una buena oportunidad para hacerlo.

StreetScene liberado en Codeplex

Hace ya unos meses os avanzaba la aparición de StreetCare, un sistema ideado, entre otras cosas, para permitir a los ayuntamientos ofrecer a sus ciudadanos los mecanismos necesarios para identificar problemas en sus calles. En su momento os expliqué algunas de sus características y las tecnologías que se utilizaron para llevar el proyecto a cabo, dejando los detalles para más adelante.

Ahora ha llegado el momento de comenzar a dar detalles técnicos de la implementación de StreetCare y, para ello, qué mejor que empezar ofreciendo el código fuente y la documentación de gran parte de la solución. Para ello, basta con que vayáis aquí y lo descarguéis vosotros mismos.

StreetScene es una versión reducida de StretCare que mantiene la misma esencia y tiene que servir para ayudar a todo aquél que quiera desarrollar algun proyecto basado en alguna de las tecnologías que aquí se utilizan, a hacerlo de una manera más simple y ágil.

Los elementos que podéis encontrar en StreetScene son:

  • Aplicación web con arquitectura ASP.NET MVC2 para la administración de los datos
  • Aplicación Silverlight 4 con arquitectura MVVM para la interfaz de usuario de los ciudadanos
  • Web Role de Azure para alojar la aplicación web.
  • SQL Azure para alojar los datos
  • Azure AppFabric Access Control V2 para proveer de mecanismos de autenticación

En breve comenzaré a publicar artículos con información de cada uno de los puntos anteriores pero, aquellos que estéis interesados en detalles sobre alguno de ellos, no dudéis en acudir al sitio web de Codeplex y descargar el código y la documentación.

Mesa redonda en Madrid sobre desarrollo en SharePoint

El pasado Miércoles, 2 de Febrero, y tal y como os avancé en este artículo, participé junto con otros MVPs de SharePoint en una mesa redonda organizada por nuestros amigos del MADNUG. En la figura, y de izquierda a derecha, podéis verme a mí, a Juan Carlos González, a Alberto Díaz y al maestro Gustavo Vélez.

madnug

Más allá de encontrarme con estos fantásticos compañeros y con otros miembros destacados de la comunidad técnica, que era para mí uno de los objetivos principales del evento, el debate fue de lo más interesante y se habló de aquellos aspectos que, en general, más preocupan a las personas que trabajamos con SharePoint de una o de otra manera.

Destacaron temas generales como el testeo, el despliegue de soluciones, la personalización gráfica o la conexión a sistemas externos y otros más particulares como la transaccionalidad de la plataforma. También hubo alguna consulta sobre arquitectura y sobre posibles patrones recomendables para utilizar cuando se desarrolla sobre SharePoint.

Si queréis ver la grabación del evento, la encontraréis aquí.

SPContext, using, RunWithElevatedPrivileges y demás…

Lo que os voy a explicar hoy no es nada nuevo. Mucho se ha escrito al respecto e incluso yo, seguramente, he escrito algún artículo sobre ello, pero el que se hable mucho de una cosa no implica que no sea importante o que no se tenga que ir recordando. El caso es que ayer, a partir de una consulta en un foro, recordé el que es, bajo mi punto de vista, el error que más comunmente cometemos los que desarrollamos sobre SharePoint, y pensé que sería un buen ejercicio escribir este artículo para ver si para todos aquellos que empiezan en esta tecnología (y todos aquellos que llevamos años pero que sistemáticamente cometemos una y otra vez el mismo error…) podría resultar de utilidad.

Comenzaremos por una cosa muy simple: estoy desarrollando un elemento web que tiene que acceder a información que se encuentra alojada en el sitio web donde reside dicho webpart. Lo primero que se plantea uno, es algo como lo del siguiente listado.

SPSite site = new SPSite(url);

SPWeb web = site.OpenWeb();

La variable url la habremos inicializado previamente con alguna información del contexto y lo único que tenemos que hacer es instanciar un objeto SPSite y un objeto SPWeb. Esto no es del todo incorrecto siempre que cuando acabemos de utilizar dichos objetos los eliminemos. Al final, lo que acabaríamos haciendo para trabajar de una manera apropiada sería algo similar a lo siguiente.

using (SPSite site = new SPSite(url))

{

    using (SPWeb web = site.OpenWeb())

    {

    }

}

Si conocéis el objeto SPContext o si lo habéis visto en el código de alguien, os puede pasar por la cabeza la idea de utilizarlo para hacer el código de arriba más ‘correcto’ y cambiarlo por:

using (SPSite site = SPContext.Current.Site)

{

    using (SPWeb web = site.OpenWeb())

    {

    }

}

Y ahí es donde lo romperíamos todo. Si os fijáis, ahora no estamos creando ninguna instancia de SPSite, sino que estamos haciendo una referencia al objeto de nuestro contexto, de manera que en cuanto salgamos del using y se ejecute el dispose estaremos eliminando un objeto que no deberíamos eliminar nunca. ¿Cómo arreglamos el código de arriba?

using (SPSite site = new SPSite(SPContext.Current.Site.ID))

{

    using (SPWeb web = site.OpenWeb())

    {

    }

}

¡Atención! fijáos que uso SPContext.Current.Site.ID y no SPContext.Current.Site.Url como parámetro de la constructora. Aparentemente el resultado es el mismo, pero cuando trabajamos en sitios extendidos la cosa varía un poquito. De todas maneras, si lo que tenéis que hacer es lo de arriba, podéis simplificarlo mucho y dejarlo tal que así:

SPWeb web = SPContext.Current.Web;

Pero aquí es cuando entra en juego nuestro amigo RunWithElevatedPrivileges. ¿Qué pasa cuando desde ese código necesitamos acceder a información con permisos elevados? Nada, que rodeamos el código de esta manera:

SPSecurity.RunWithElevatedPrivileges(delegate

{

    SPWeb web = SPContext.Current.Web;

});

Aquí lo volveríamos a romper todo, ya que el objeto SPContext es, como su nombre indica, una referencia al contexto de SharePoint, que está asociado al usuario autenticado independientemente de que el código se ejecute de manera elevada. La recomendación siempre es hacer uso del RunWithElevatedPrivileges sólo cuando sea estrictamente necesario y en el mínimo ámbito posible y, por lo tanto, todo nos empujaría a hacerlo de la siguiente manera.

using (SPSite site = new SPSite(SPContext.Current.Site.ID))

{

    using (SPWeb web = site.OpenWeb())

    {

        SPSecurity.RunWithElevatedPrivileges(delegate

        {

        });

    }

}

 

Aquí estaríamos cometiendo el mismo error. En el momento en que hemos creado la instancia del objeto SPSite estábamos trabajando en un contexto no elevado y, por lo tanto, así seguiremos siempre que hagamos referencia a éste. Si queremos tratar información de ese objeto SPWeb que viene de la instancia del objeto SPSite creada al inicio del código lo tenemos que hacer de la siguiente manera:

SPSecurity.RunWithElevatedPrivileges(delegate

{

    using (SPSite site = new SPSite(SPContext.Current.Site.ID))

    {

        using (SPWeb web = site.OpenWeb())

        {

        }

    }

});

Para finalizar, deciros que esto es sólo un ejemplo para un caso concreto. En general, trabajar con SharePoint, con su contexto y con la creación de objetos es algo que se tiene que hacer siguiendo ciertas normas. Os dejo un enlace que os puede resultar de interés: http://code.msdn.microsoft.com/SPDisposeCheck

Con esta utilidad podréis comprobar si estáis siguiendo correctamente las normas o no.

CRM 2011 Online ya disponible

Me vuelvo a meter en territorio enemigo para hablaros un poquito de CRM. Y es que hoy, y antes de que la versión Server aparezca, Microsoft ha lanzado la versión para la nube de CRM 2011. Esto deja clara la apuesta de la compañía por todo lo que a Cloud computing se refiere. En cualquier caso, y para aquellos que ya hemos tenido el placer de trastear un poco con el producto, es una gran noticia el que ya podamos disfrutar de la versión final para dejar de trastear y empezar a trabajar.

Os dejo más información aquí:

http://www.microsoft.com/Presspass/Features/2011/jan11/01-17CRMOnline.mspx

Desarrollo en sharepoint para desarrolladores mortales de .NET

El próximo miércoles 2 de Febrero participaré, junto con Gustavo Vélez, Juan Carlos González y Alberto Díaz, en un evento organizado por el grupo MadNUG, y que girará en torno a desarrollo sobre SharePoint. Aquí os dejo el enlace a la página de MadNUG donde se hace referencia a dicho evento.

http://madriddotnet.wordpress.com/2011/01/17/evento-desarrollo-en-sharepoint-para-desarrolladores-mortales-de-net/

Encontraréis ahí enlaces a la página de registro y a la zona online donde podréis ver el evento por Live Meeting.

CryptographicException: The data protection operation was unsuccessful

El haber estado los últimos años dedicándome mayormente a SharePoint ha hecho que me olvidase casi por completo de mi amigo IIS. El problema cuando pasa esto es que después vuelves a trabajar en una aplicación ASP.NET y en ocasiones ves muertos.

En el caso que me ocupa, una serie de razones que ahora no tienen relevancia me llevaron a una serie de decisiones que tienen menos relevancia aún, pero que desembocaron en cambiar el servidor web incorporado en Visual Studio 2010 por mi flamante IIS nuevo de trinca. Todo parecía ir bien hasta qué:

The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread’s user context, which may be the case when the thread is impersonating.

La primera reacción fue correr por la oficina como pollos sin cabeza. De funcionar todo perfectamente excepto un temita que ocasionó la serie de decisiones anteriormente citada pasamos a no poder autenticarnos en el sitio. Afrutanadamente la solución era más simple de lo que parecía y se reducía a lo siguiente:

  1. Abrir Internet Information Services
  2. Acceder, en la lista de application pools, a los advanced settings del pool de aplicaciones asignado a mi sitio web.
  3. Establecer a True el valor de la propiedad Load User Profile en la sección Process Model, tal y como muestra la figura:

image

  1. Continuar con lo que estábamos haciendo hasta entonces 🙂

Cumulative updates de Diciembre 2010 para SharePoint disponibles

Me hago eco de la información publicada por el amigo Juan Pablo referente a la disponibilidad de las actualizaciones mencionadas en el título del post y, para no ser repetitivo, os dejo simplemente el enlace para que veáis lo que contienen dichas actualizaciones así como los enlaces de descarga.

http://surpoint.blogspot.com/2011/01/cu-diciembre-2010-listos-para-moss-2007.html

Configuraciones de compilación en Azure

Hoy no os aburro con un artículo sino con una información de utilidad que os puede ahorrar un tiempo valioso en ciertas condiciones. El asunto en cuestión puede provocar una excepción como la siguiente a la hora de compilar un proyecto Silverlight alojado en una aplicación web para ser publicada en Azure.

The "CreateRiaClientFilesTask" task failed unexpectedly.
System.Web.HttpException (0x80004005): Could not load file or assembly ‘msshrtmi’ or one of its dependencies

La verdad es que, si llegáis a este error, poco os puedo ayudar salvo redirigiros a algún sitio como éste dónde se explica una posible solución. Lamentablemente, a mí no me ayudó y lo único que me salvó fue volver a un snapshot de la máquina virtual donde estaba desarrollando. Lo que sí os puedo decir (porque he sido capaz de reproducirlo) es lo que hizo que ese error apareciese.

El origen de la causa hay que buscarlo en que mi solución de Visual Studio contenía numerosos proyectos, de los cuales sólo quería que se compilasen algunos cada vez que recompilaba la solución. Para ello, como en otras muchas ocasiones, accedía al Configuration Manager de Visual Studio.

image

Una vez dentro creaba una nueva configuración asignándole un nombre para después seleccionar los proyectos que quería que contuviera dicha configuración.

image

El caso es que, por defecto, tenía marcada la opción “Create new project configurations”. Pues buen, nunca había tenido problemas con esto hasta ahora, y os explicaré lo que he visto hasta el momento.

Si no marcas esta opción, lo único que modificas es la solución, añadiendo una nueva configuración de proyectos a ser compilados. Por el contrario, si la marcas, editarás todos los proyectos para añadir la nueva configuración, y el resultado de la compilación se guardará en una nueva carpeta bajo la carpeta bin de tus proyectos.

El caso es que, en el caso que me ocupa actualmente: Silverlight alojado en una aplicación ASP.NET MVC2 incluida en un Web Role de Azure, marcar esta opción imposibilita que vuelvas a compilar, dándote el error del inicio de este post. Descartar los cambios realizados en la solución no solucionó el problema, así que si lo queréis probar, aseguraros de tener un snapshot de vuestra máquina virtual.

Por cierto, si alguien tiene alguna información al respecto, comentad el post, por favor, por si alguien llega aquí con el problema entre manos…

Consumir servicios externos desde código SandBoxed (y II)

Hace unos días, en este artículo empecé a hablaros de la posibilidad de realizar una llamada a un servicio externo publicado en Azure desde CRM 2011 Online, pero dejé de lado la parte relativa a CRM, quedándome básicamente en una introducción a la tecnología que iba a utilizar. Tal y como os prometí, aquí viene la segunda parte del asunto o, lo que es lo mismo, todo lo concerniente a CRM.

Lo primero que váis a tener que hacer es descargar la SDK de CRM 2011 que podéis encontrar aquí. Ahí encontraréis algunos ensamblados y algunas utilidades que necesitáis para realizar con éxito el proceso que se explica en este artículo. Tal y como avancé en la primera parte, necesitamos hacer un plugin que se lance según las condiciones que nos convengan y, antes de entrar en estas condiciones, vamos a desarrollar la pieza que necesitamos. Para ello, creamos una librería de clases y añadimos una referencia al ensamblado Microsoft.Crm.Sdk.Proxy que encontraremos en la carpeta sdkbin del SDK descargado previamente. Tal y como apareció en el artículo anterior, también necesitaré referencias a los ensamblados Microsoft.Http y Microsoft.Http.Extensions. A continuación creamos una clase y escribimos el siguiente código y generamos el ensamblado:

namespace Crm2011Plugins

{

    using System;

    using Microsoft.Http;

    using Microsoft.Xrm.Sdk;

 

    public class ExternalCallPlugin : IPlugin

    {

        public void Execute(IServiceProvider serviceProvider)

        {

            string uri = "http://myapp.cloudapp.net/Service1.svc/";

 

            using (HttpResponseMessage response = new HttpClient().Get(uri))

            {

                // TODO: tratar la respuesta aquí

            }

        }

    }

}

Como véis, tenemos que implementar la interfaz IPlugin y su método Execute. Es ahí dónde haremos la llamada a nuestro servicio externo pero, ¿cómo hago ahora para que CRM 2011 Online ejecute ese método cuando a mí me convenga? Bien, vamos a pensar, por ejemplo, que queremos que se ejecute siempre que alguien modifique el estado de un caso.

Lo primero que tenemos que hacer es buscar en la carpeta sdktoolspluginregistration de la SDK una solución de Visual Studio que tendremos que abrir y compilar para generar la herramienta necesaria para registrar plugins de CRM. Una vez generado tendremos un ejecutable llamado PluginRegistration en la carpeta sdktoolspluginregistrationbinDebug que deberemos ejecutar. Si proporcionamos a la herramienta los datos de conexión de nuestra instancia de CRM 2011 Online:

  • Nombre para la conexión: cualquiera que os ayude a identificar esa conexión entre otras.
  • Discovery URL: aquella que os corresponda según este artículo.
  • Username: un nombre de usuario con permiso en la instancia de CRM 2011.

Una vez conectados veremos una pantalla similar a la siguiente:

image

A continuación, del desplegable Register seleccionamos la opción Register New Assembly tal y como muestra la figura.

image

Nos aparecerá un formulario como el siguiente, en el cual deberemos especificar la ruta del ensamblado que hemos generado previamente y, como estamos desplegando para CRM 2011 Online seleccionamos las opciones SandBox y Database. Dejadme poner aquí un disclaimer: no me considero un experto en CRM 2011 –y ni siquiera me considero un desarrollador avanzado- así que estas selecciones pueden ser o no la mejor opción.

image

Una vez aceptado el formulario aparecerá un nuevo ensamblado en la lista. Lo seleccionamos con el botón derecho y seleccionamos la opción Register new Step tal y como muestra la figura.

image

Una vez hecho esto aparecerá una pantalla como la de la imagen y deberás rellenar los datos que te pide según tus necesidades.

image

En este caso, las decisiones que hemos tomado han sido las siguientes:

  • Message: esto es la acción que originará el lanzamiento del método Execute. Seleccionamos Update.
  • Primary Entity: nombre de la entidad sobre la cual queremos monitorizar cambios. Seleccionamos incident que es el nombre interno para la entidad Caso.
  • Filtering Attributes: campos sobre los cuales, si se produce un cambio, se lanzará el método Execute. Seleccionamos status code.

Además de esto, podemos elegir si el método se llamará de manera síncrona o asíncrona y si se ejecutará antes de validar el formulario del caso, antes de ejecutar la actualización o después de ejecutar la actualización. En nuestro caso seleccionamos Post-operation y Synchronous. Finalmente, pulsamos el botón Register New Step.

Una vez hecho esto, ya deberíamos observar como, cada vez que modificamos el estado de un caso en el sistema se produce una llamada al método externo que tenemos publicado en Azure.