martes, 29 de enero de 2013

Integrar Microsoft Enterprise Library 5.0 con webparts de Sharepoint

Microsoft enterprise library 5.0 es un conjunto de utilidades y funcionalidades, liberadas de forma gratuita por Microsoft para apoyar nuestros procesos de desarrollo. Entre las funcionalidades mas interesantes esta el Data Access Application Block, el cual provee toda la funcionalidad de conexión la BD, como una capa de datos final que accede a la BD.

En Sharepoint muchas veces es necesario interactuar con Bases de datos externas como MSSQL Server, por lo que nos vemos en la necesidad de implementar una capa de datos consistente para nuestros proyectos, lo cual nos implicaría un esfuerzo adicional en desarrollo y pruebas. MSEL nos ahorra este esfuerzo en nuestros proyectos, minimizando tiempos y esfuerzos en desarrollo.

Para integrar esta tecnología en nuestros webparts de sharepoint se deben seguir los siguientes pasos:

1. Configurar sitio (webapplication) de sharepoint:
- Pegar los assemblies del MSEL requeridos, en la carpeta /bin del directorio virtual del sitio de sharepoint (Ej: c:\inetpub\wwwroot\wss\VirtualDirectories\80). Si por ejemplo usáramos el Data Access Application Block tendríamos que pegar las siguientes dlls:
  • Microsoft.Practices.EnterpriseLibrary.Common.dll
  • Microsoft.Practices.EnterpriseLibrary.Data.dll
  • Microsoft.Practices.ServiceLocation.dll
  • Microsoft.Practices.Unity.dll
  • Microsoft.Practices.Unity.Interception.dll

- Configurar el archivo web.config del sitio Sharepoint. En la carpeta virtual del sitio abrimos para edición el archivo de configuración web.config y agregamos las siguientes etiquetas:
Dentro de la seccion <configSections> agregar lo siguiente:
<section name="dataConfiguration"type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data" requirePermission="false" />

Despues de la seccion </configSections> agregar lo siguiente:
<dataConfiguration defaultDatabase="SampleDatabaseName" />

Reusar o Crear una nueva cadena de conexión en la sección <connectionStrings>:
<add name="SampleDatabaseName" connectionString="Data Source=<DataServerName>;Initial Catalog=<DatabaseName>;user id=<DatabaseUserName>;password=<DatabasePassword>;" providerName="System.Data.SqlClient" /> 

Luego de algunas experiencias angustiantes he detectado que lo mas importante del punto anterior es el dato del nombre del proveedor (providerName="System.Data.SqlClient"), cuando no se configura este valor, por razones aun desconocidas se genera el siguiente error: 

Activation error occured while trying to get instance of type Database, key "" en Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) en Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService](String key) en Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.InnerCreateDatabase(String name) en Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase() en DBTestWP.DBTestWP.ObtenerUsuariosAplicacion() en DBTestWP.DBTestWP.MostrarUsuarios() en DBTestWP.DBTestWP.OnLoad(EventArgs e)

Por lo anterior y luego de varios días tratando de resolver este inconveniente, recomiendo siempre asegurarse que este dato este configurado en la cadena de conexión que van a usar para el MSEL.


2. Usar MSEL en nuestro webpart de Sharepoint:
- Referenciar las dll necesarias dependiendo de que bloque se va usar del MSEL.
 Siguiendo con el ejemplo del Data Access Application Block tendríamos que referenciar las siguientes dll en nuestro proyecto de webparts:
  • Microsoft.Practices.EnterpriseLibrary.Common.dll
  • Microsoft.Practices.EnterpriseLibrary.Data.dll
  • Microsoft.Practices.ServiceLocation.dll
  • Microsoft.Practices.Unity.dll
  • Microsoft.Practices.Unity.Interception.dll

- Usar los objetos de MSEL en nuestro código fuente. Siguiendo con el ejemplo nuestro código fuente podría lucir de la siguiente manera. 

using System;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;



namespace DBTestWP

{

 [Guid("4b057748-7e21-41e0-a30e-51d114fb0ca3")]

 public class DBTestWP : Microsoft.SharePoint.WebPartPages.WebPart

 {

  
  ...
  


  /// <summary>
  /// Consulta en la BD los Usuarios existentes en la aplicación.
  /// </summary>
  /// <returns>Tabla de obtener usuarios.</returns>
  private DataTable ObtenerUsuarioAplicacion(string param1, string param2)
  {
    try
    {
        //// Crea la bd con la fabrica
        Database myDB = DatabaseFactory.CreateDatabase();
        //// Prepara el comando con los parámetros del sp.
        DbCommand dbcom = myDB.GetStoredProcCommand("MyStoredProc");
        //// Definición de Parámetros.
        myDB.AddInParameter(dbcom, "@param1"DbType.String, param1);
        myDB.AddInParameter(dbcom, "@param2"DbType.String, param2);
        //// Ejecución de la consulta.
        DataSet ds = myDB.ExecuteDataSet(dbcommand);
        return ds.Tables[0];
     }
     catch (Exception)
     {
        throw;
     }
  }


 }

}



En esta ejemplo, he definido en la clase de mi webpart (DBTestWP), un método privado que consulta en una BD-Sql un usuario del sistema.
Importante notar los objetos nuevos del MSEL, primero la referencia al namespace el 
using Microsoft.Practices.EnterpriseLibrary.Data; 
Los objetos principales:  Database, DatabaseFactory con los cuales se conecta con la bd, y el método de consulta usado en este ejemplo: ExecuteDataSet(dbcommand) el cual recibe un objeto standar .net para la configuracion de los comandos hacia la BD (DbCommand), que en este caso se trata de un Procedimiento almacenado con parámetros creado en la BD.

Con estos dos pasos es suficiente para usar Microsoft enterprise library 5.0 en nuestros desarrollos personalizados para Sharepoint como webparts .


viernes, 8 de abril de 2011

Crear una lista programaticamente con vista predeterminada

Con el Api de Sharepoint podemos crear listas de almanamiento de manera programática, haciendo uso de los objetos SPWeb y los metodos del objeto SPList, adicional a esto podemos crear la vista por defecto que toda lista de forma nativa tiene mediante el objeto SPView, el siguiente ejemplo crea una lista en tiempo de ejecucion para mostrar las ventas del día por areas de negocio de una empresa respectiva:

SPWeb web = SPContext.Current.Web;
web.AllowUnsafeUpdates = true;
string listName = "VentasDelDia";


// Adicionar nueva lista.
web.Lists.Add(listName, string.Empty, SPListTemplateType.GenericList);


// Adicionar campos.
web.Lists[listName].Fields.Add("Title", SPFieldType.Text, false);
web.Lists[listName].Fields.Add("VentaDelDia", SPFieldType.Text, false);
web.Lists[listName].Fields.Add("Area", SPFieldType.Text, false);


// Creacion de la vista por defecto con campos nuevos.
SPView defaultView = web.Lists[listName].DefaultView;
defaultView.ViewFields.DeleteAll();
defaultView.ViewFields.Add("VentaDelDia");
defaultView.ViewFields.Add("Area");
defaultView.Update();


// guardar cambios en el sitio web
web.Update();

jueves, 20 de enero de 2011

Consulta CAML con los últimos N elementos

Muchas veces necesitamos consultar una lista cualquiera en Sharepoint, retornando solo los últimos items actualizados, por ejemplo, el famoso carrusel de imágenes con las últmas 5 fotos cargadas, pues bien, si tuvieramos una lista de imágenes y quisieramos desarrollar un webpart con un look and feel ya establecido, la recomendación seria usar el objeto SPQuery para implementar una consulta CAML, con las siguientes características:

Clausula OrderBy:
<OrderBy><FieldRef Name='Modified' Ascending='FALSE'/></OrderBy>

Propiedad RowLimit:
miConsulta.RowLimit = 10;

Adicional a esto, si quisiera solo retornar las columnas o campos específicos, debo indicarlo asi:

Propiedad ViewFields:

miConsulta.ViewFields = "<FieldRef Name=\"Title\"/>" + "<FieldRef Name=\"Description\"/>" + "<FieldRef Name=\"Link\"/>";

El código completo sería asi, suponiendo que se tiene un objeto SPList lista:

SPQuery miConsulta = new SPQuery();

miConsulta.Query = "<OrderBy><FieldRef Name='Modified' Ascending='FALSE'/></OrderBy>";
miConsulta.RowLimit = 5;
miConsulta.ViewFields = "<FieldRef Name=\"Title\"/>" + "<FieldRef Name=\"Description\"/>" + "<FieldRef Name=\"Link\"/>";
SPListItemCollection myColl = lista.GetItems(miConsulta);

De aqui, ya sería recorrer los items de la lista, o llenar un DataTable para continuar con la lógica de nuestro webpart.

Saludos,