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.

Quiero empezar con SharePoint, ¿dónde voy?

El título de este artículo pretende resumir muy brutamente una consulta bastante habitual en los foros y el contenido de bastantes correos electrónicos que recibo solicitando ayuda o consejo. Mi respuesta normalmente varía según mi estado de ánimo o según el día que haya tenido pero normalmente se resumiría también como:

“Puedes empezar por Google, Bing o cualquier buscador con el que te sientas cómodo.”

No es que quiera resultar borde con esta respuesta ni que quiera frivolizar con el tema que para mí es muy serio. La respuesta es correcta para algunos casos y, de hecho, es ese el punto de partida que hemos tenido muchos de los que nos dedicamos a esto. Lo que pasa es que aquellos que hemos utilizado esa vía de aprendizaje no realizaríamos nunca la pregunta “por dónde empiezo”. Voy a exponer ahora lo que es simplemente mi opinión personal al respecto. Incluiré alguna dirección de interés para responder a la pregunta inicial, pero siempre intentando argumentar el por qué de cada indicación.

Para empezar, SharePoint es un producto (o mejor dicho una plataforma) muy extensa y compleja. Sí, es cierto que cualquier persona con mínimos conocimientos sobre la materia puede instalar un SharePoint en su casa y empezar a jugar con él. Seguramente, sin ninguna indicación podría incluso montar algo que funcionara, pero os garantizo que invertiría mucho tiempo en andar y desandar caminos que seguramente no le lleven a nada que le resulte de interés. Por lo tanto, primer consejo: si queréis instalar un SharePoint para empezar a jugar, no perdáis el tiempo en ello. Descargad una máquina virtual con el producto instalado y con ejemplos de estructuras ya creadas. Os ahorraréis mucho tiempo que, a la postre, es lo más importante siempre. Por poneros un ejemplo a descargar, os dejo éste.

De todas maneras, cuando alguien se plantea empezar en “esto del SharePoint” no se está refiriendo a empezar a jugar con algo. Si yo me planteo empezar a jugar con algo pienso en una consola, no en una plataforma informática o en un producto. Puestos a empezar en algo, ¿por qué SharePoint y no SAP, Ubuntu o Movie Maker? He de entender que te planteas SharePoint porque sabes o has oido que hace algo concreto. Pensad que en función de lo que estés buscando, la dirección a tomar puede ser muy diferente. Si quieres SharePoint para crear un portal de publicación, puedes perder meses aprendiendo como funcionan y como se extienden las características de colaboración de SharePoint. Lo primero a conocer de SharePoint está precisamente fuera de SharePoint. Me refiero a los requerimientos de lo que quieras o tengas que montar. Segundo consejo: si necesitas tener un overview de lo que ofrece el producto, te recomiendo directamente la página oficial de Microsoft. Una vez tenga claro qué partes del producto son de tu interés la búsqueda de información al respecto te resultará mucho más fructífera.

Más preocupante me parece cuando la intención real del que se hace esta pregunta es empezar en el ámbito del desarrollo o de la administración de SharePoint. Principalmente me preocupa por el echo que si ya estás familiarizado con el desarrollo o la administración de otro producto o plataforma no te sueles plantear por dónde empezar. Ya sabes que está internet, y que hay libros especializados o incluso cursos presenciales u online. Tercer consejo: si estás buscando estos elementos siempre encontrarás en los buscadores la información más reciente. Si aún así no encuentras nada (cosa que dudo) yo os dejo un enlace que funciona a día de hoy. Si no estás familiarizado con ningún otro producto, me parece irreal querer empezar por SharePoint. Pongamos dos casos:

  • Un administrador de SharePoint tiene que tener amplios conocimientos de sistemas (SQL Server, IIS, ISA Server, etc.) Quizá no domine todos los sistemas, pero tiene que ser capaz de interpretar cuando un problema es de base de datos, o de seguridad. Si estás al día en estos productos, seguramente conocerás Technet y sabrás que ahí tienes todo lo que necesitas para trabajar con SharePoint.
  • Un desarrollador de SharePoint debería (aunque no siempre es así) tener sólidos conocimientos de .NET. Si es así, conoces Msdn y, al igual que ocurría antes, ahí tienes todo lo que necesitas para trabajar con SharePoint.

Evidentemente, tanto los administradores de sistemas como los desarrolladores se encontrarán con problemas con los que nunca se han encontrado, por mucha experiencia que tengan. Ahí es cuando tienes que pedir ayuda. Cuarto consejo: si te encuentras con un problema para el cual no encuentras solución, acude a los blogs y a los foros. Encontrarás foros de todo tipo y para todos los gustos pero, por ejemplo, os dejo aquí el link al foro oficial de desarrollo en SharePoint.

Para concluir, un último consejo. Si os estáis planteando empezar en “esto del SharePoint” por un asunto oficial o, lo que es lo mismo, porque en vuestra empresa te han propuesto ponerlo en marcha en algún sentido, busca ayuda. SharePoint no es algo que sólo puedan tocar super-expertos, pero te vendrá bien alguien con conocimientos para tener un punto de partida. Quizá sólo necesites una consultoría de unas cuantas horas para enseñarte lo que puedes hacer para satisfacer tus necesidades, o quizá necesites 3 desarrolladores trabajando durante 5 meses, pero una primera consulta le ahorrará a tu empresa mucho tiempo y dinero. En un escenario real, un error en el inicio del planteamiento del proyecto puede concluir en la necesidad de comenzar de cero después de mucho tiempo invertido o, lo que es peor, comenzar de –X, teniendo que obtener de alguna manera toda la información que ya estuviera en una instalación con problemas, hacer el proyecto de cero y, finalmente, volcar toda la información obtenida previamente.

Como dirían en la tele, antes de tomar SharePoint, consulten con un farmacéutico…

Consumir servicios externos desde código SandBoxed

El título de este post puede llevarnos a pensar que voy a hablar de Office365, sobretodo por el concepto SandBox y por el requerimiento de llamar a un servicio externo desde mi SharePoint en la nube. La verdad es que me gustaría que fuera así, pero todavía no es momento de hablar de la nueva versión de BPOS y de lo que ofrecerá cuando la primera beta se haga pública. No obstante, os puedo hablar de CRM 2011, del cual hoy me he enterado que ya tenemos disponible la RC, y se da el caso que también utiliza el concepto SandBox cuando se habla de despliegue de soluciones personalizadas sobre la versión online del producto. Obviamente, la necesidad de consumir servicios externos desde esta plataforma será también un requerimiento más que común. Se nos pueden dar varias opciones, desde tener que consumir un servicio “privado” que interactúe con un sistema interno dentro de nuestra infraestructura o la de un tercero a tener que consumir un servicio “público” proporcionado por cualquier organización. Vayamos por partes…

Si tenemos que consumir un servicio privado las opciones se minimizan y todo apunta a que tenemos que utilizar AppFabric y, más en concreto, el Service Bus. Si tenemos que consumir un servicio público el abanico de posibilidades se abre, almenos en teoría. En este post os voy a explicar un ejemplo concreto de este caso. Imaginemos que tenemos que desarrollar un servicio para publicarlo en Azure y que queremos consumir desde CRM 2011 Online. Evidentemente podemos seguir usando AppFabric para este caso pero, siendo nuestras las dos piezas y estando ambas alojadas en la nube, ¿no puedo hacerlo por mis propios medios? La respuesta no es evidente, y si empezas a hacer tus pruebas te vas encontrando con algunas limitaciones de la tecnología. Entonces, ¿cómo lo hago? la respuesta es REST. A continuación os detallo los pasos que deberíais seguir para montar una solución similar.

Lo primero, añadir una referencia (si no la teníais ya) a los ensamblados System.ServiceModel y System.ServiceModel.Web. A continuación, incluir un servicio WCF dentro de nuestro sitio web que queremos publicar en Azure. Esta acción crea tres ficheros en nuestro proyecto. Primero editamos el archivo Service1.svc y añadimos el atributo Factory="System.ServiceModel.Activation.WebServiceHostFactory" dentro del nodo ServiceHost. El fichero resultante quedará así:

<%@ ServiceHost Language="C#" Debug="true"

    Service="WebApplication1.Service1"

    CodeBehind="Service1.svc.cs"

    Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

Después editamos el fichero IService1.cs que es la interfaz del servicio WCF para añadir la firma del método o de los métodos que queremos publicar. En este caso, expongo un método llamado GetIntegerResult que devolverá un valor entero.

namespace WebApplication1

{

    using System.ServiceModel;

    using System.ServiceModel.Web;

 

    [ServiceContract]

    public interface IService1

    {

        [OperationContract(Name = "GetIntegerResult")]

        [WebInvoke(UriTemplate = "/", Method = "GET")]

        int GetIntegerResult();

    }

}

Una vez hecho esto tenemos que añadir la implementación del método que devuelve dicho valor entero. Para ello, editamos el fichero Service1.svc.cs y escribimos lo siguiente:

namespace WebApplication1

{

    public class Service1 : IService1

    {

        public int GetIntegerResult()

        {

            return 3;

        }

    }

}

Si compilamos este código y accedemos vía web a nuestro servicio usando la url http://localhost:49254/Service1.svc/ (donde localhost:49254 es la url principal de vuestra aplicación web) observaréis un resultado como el de la figura:

image

El ejemplo, como se puede apreciar es muy simple y estoy pasando por alto muchas consideraciones pero el resumen es que si yo hago un GET de esta url obtengo el resultado que observáis en la figura. Ahora, ¿cómo hago ese GET? Está claro que hay múltiples respuestas para esta pregunta pero lo que parece evidente es que no vamos a tener muchas trabas tecnológicas independientemente de la tecnología que utilicemos siempre y cuando el servicio al que quiero llamar sea visible desde el sistema que estoy extendiendo, ya sea CRM 2011 Online, Office 365 o X. Para que sea visible deberemos publicar nuestro servicio en azure. Vamos a suponer que he publicado mi aplicación web en http://myapp.cloudapp.net y que, por lo tanto, si en mi navegador pongo http://myapp.cloudapp.net/Service1.svc veré una figura exactamente igual que la anterior. Para realizar la llamada desde C# una posibilidad es la siguiente:

Añadimos referencias a los ensamblados Microsoft.Http y Microsoft.Http.Extensions. Estos ensamblados los podréis encontrar dentro del WCF REST Starter Kit. A continuación, desde el sitio desde el cual quieras llamar a tu servicio, introduce el siguiente código.

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

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

{

    // TODO: tratar la respuesta aquí    

    // No olvidéis la siguiente línea al principio del fichero:

    //    using Microsoft.Http;

}

Así de simple, independientemente de la tecnología que uses […] Bueno en realidad siempre hay una trampa, o varias. Si recordáis el título del artículo hablaba sobre CRM 2011 Online y yo sólo os he dado el punto de partida, la primera pista. .NET puro y duro que deberéis saber cómo publicar en CRM 2011 Online, en Office 365 o donde buenamente queráis. La segunda pista en la cadena CRM 2011 Online – SandBox – REST es Plugin.

Aún a riesgo de que me odiéis por haber metido sólo la puntita dejaros con la miel en los labios, voy a dejar el artículo aquí por el momento con la promesa de escribir una continuación digna a lo largo de esta semana.

Actualizado a lo largo de esa semana…

Os dejo aquí la segunda parte de este artículo.

CRM 2011 – An unsecured or incorrectly secured fault was received from the other party error

Como veréis, hoy me traslado temporalmente al mundo de CRM 2011, lo cual no es demasiado habitual en mí, una persona acostumbrada a trabajar mayoritariamente en tecnologías SharePoint. El caso es que de vez en cuando me toca jugar con una nueva tecnología y, entre la novedad del producto y mi desconocimiento del medio, me encuentro con errores que se escapan totalmente de mi control y me hacen perder invertir tiempo en la búsqueda de soluciones. El caso de hoy ha resultado ser una tontería pero, por si os sucede lo mismo que a mí, os pongo aquí el problema y su resolución.

El problema
A la hora de utilizar el Plugin Registration Tool para conectarme a mi instancia de CRM 2011 Online me encuentro con una excepción cuando trato de conectar con mi organización. El error dice lo siguiente:

An unsecured or incorrectly secured fault was received from the other party error.

El caso es que trato de utilizar todas las credenciales de que dispongo, pero el resultado es siempre el mismo.

La solución
Para poder conectar de nuevo la herramienta a mi instancia de CRM 2011 Online basta con acceder a la carpeta LiveDeviceID que encontraréis en vuestro perfil de usuario (C:Users{usuario} en Win7, por ejemplo) y eliminar el fichero LiveDevice.xml que encontraréis en ella.