El desarrollo de aplicaciones de cliente utilizando el Modelo de Objetos de Cliente, resulta algo más cómodo que las llamadas a Servicios Web, desde el punto de vista del desarrollador. Al fin de cuentas, es lo mismo, ya que todo acabará en llamadas al Servicio Web Client.svc, aunque esto será transparente para nosotros. A modo de ejemplo, a continuación describimos los pasos para crear un Proyecto de Visual Studio 2010 y utilizar el Modelo de Objetos de Cliente Gestionado.
Crearemos un nuevo Proyecto en Visual Studio 2010 de tipo Consola, asegurándonos de seleccionar el Net Framework 3.5. En nuestro caso de ejemplo, llamaremos a nuestro Proyecto ManagedClient.
Agregaremos una Referencia en nuestro Proyecto a las DLLs de Microsoft.SharePoint.Client.dll y Microsoft.SharePoint.Client.Runtime.dll. Es importante recordar, que la máquina en la que ejecutemos nuestra aplicación debe tener estas DLLs disponibles, por ejemplo, copiadas en el mismo directorio del ejecutable.
Realizado esto, ya podremos empezar a escribir el código que deseemos. En nuestro caso de ejemplo, utilizaremos la clase ClientContext para conectarnos a un Sitio de SharePoint, indicando la URL del mismo. Por defecto, utiliza la Autenticación de Windows, tomando la identidad del usuario que ejecuta la aplicación. Esta clase implementa el interfaz IDisposable, por lo que es recomendable utilizar la sentencia using para evitar Memory Leaks. Seguidamente, utilizaremos la clase ListCreationInformation para crear una Lista Genérica en dicho Site de SharePoint, y así poder utilizar la clase ListItemCreationInformation en el interior de un bucle para poblar de contenido la Lista que acabamos de crear.
Todas las acciones que hemos solicitado realizar a través de nuestro código, son encapsuladas en un único Lote (Batch), que es enviado al servidor cuando ejecutamos el método ExecuteQuery, lo cual crea un XML que es enviado al Servicio Web client.svc, que lo ejecuta y devuelve una respuesta.
Cabe destacar que también es posible conectarse a una Granja SharePoint que utilice Autenticación Anónima o Autenticación Basada en Formularios (FBA), aunque esto puede variar ligeramente nuestro código. Igualmente, también es posible conectarse a una Granja SharePoint impersonándose, es decir, especificando por código las credenciales (usuario y contraseña) que deseemos mediante la propiedad Credentials de la clase ClientContext.
La Gestión de Errores, el número de Lotes (Batches), y el Rendimiento
El hecho de que al ejecutar el método ExecuteQuery() se envíen al servidor todas las acciones a realizar para su ejecución en un lote (batch), afecta a cómo realizar la gestión de errores, y en consecuencia, a la forma en que deberemos de escribir nuestro código.
A priori, por un lado, tenemos la posibilidad de agrupar todas las acciones a realizar en uno o varios lotes (Batches), en función de la forma que más nos facilite la gestión de errores y el rendimiento de nuestra aplicación (cuanto menor sea el número de lotes a ejecutar, mejor).
Por otro lado, si por ejemplo, deseamos crear una Lista y añadir diez elementos, pero desconocemos si la lista estará creada o no de antemano, podríamos:
- En un bloque try, crear la Lista y añadir los diez elementos (un lote), mientras que en el bloque catch tan sólo añadiríamos los diez elementos (otro lote). De este modo, si se produce una excepción porque la Lista ya existe, desde el bloque catch se añadirían los elementos. Si todo va bien, con la ejecución del primer lote, hemos acabado.
- En un bloque try, crear la Lista (un lote). En otro bloque Try, añadir los diez elementos (otro lote). Aquí ejecutaremos dos lotes en todos los casos.
Esta sería una primera aproximación. Sin embargo, con el Modelo de Objetos de Cliente Gestionado en SharePoint 2010, tenemos disponible la clase ExceptionHandlingScope, la cual nos permite realizar una gestión de errores dentro de cada Lote (Batch) al ser ejecutado en el Servidor. Una gestión de errores algo distinta a la forma más tradicional, que nos puede ser de gran utilidad en muchos casos.
Téngase en cuenta también, que por defecto, ciertas propiedades y colecciones de algunos objetos no son devueltas, con el objetivo de mejorar el rendimiento. Si intentamos acceder a algunas de estas propiedades que no están disponibles, obtendremos un error del tipo PropertyOrFieldNotInitializedException ó CollectionNotInitializedException. En estas situaciones, por un lado podemos utilizar el método IsPropertyAvailable para comprobar si cierta propiedad está disponible o no antes de acceder a la misma, evitando de este modo que se produzca un error de acceso. Por otro lado, también se puede utilizar el método Load de la clase ClientContext para indicar qué propiedades deseamos obtener.
A continuación se puede ver un ejemplo, en el que se utiliza el método Load, para cargar la colección de Listas de un Site, así como también cargar la propiedad Title del mismo Site, y evitar de este modo que se produzcan excepciona al intentar acceder a dichas propiedades/colecciones. Es importante recordar que primero se llama al método Load() y luego a ExecuteQuery(), y no al revés.
Utilizar el Modelo de Objetos de Cliente de forma Asíncrona
En ocasiones, necesitaremos ejecutar procesos de larga duración, en cuyo caso, la forma más acertada será realizar una ejecución asíncrona de dicho código, en lugar de la tradicional forma síncrona que puede transmitir al usuario la sensación de que nuestra aplicación se ha quedado colgada. Como ocurre con cualquier cosa en .Net, si deseamos ejecutar código de forma asíncrona, deberemos utilizar Delegados. Una forma es como se muestra en el siguiente ejemplo:
La salida de ejecución del código anterior sería algo similar a:
El código anterior también se podría escribir de otro modo, utilizando una función de CallBack.
Poco más por hoy. Como siempre, confío que la lectura resulte de interés.