Muchos podrán pensar que podemos hacer lo mismo solo guardando la lista como plantilla y después agregándola al sitio que deseemos, sin embargo, para nosotros los desarrolladores, siempre es mejor tener todo por código, y que al crear nuestro paquete de instalación (WSP), este contenga una Feature que provisione la definición e instancia de la lista, es decir, todo lo necesario para que nuestro desarrollo funcione.
Básicamente esta solución lo que hace es utilizar la API que se encuentra en las dll’s:
VSeWSS.Server.Services.dll
VSeWSS.Server.SPProxies.dll
Pasos a seguir para provisionar la definición e instancia de nuestra lista a través de una feature.
1.- El código que nos permite extraer la definición de una lista
El código principalmente utiliza la funcionalidad que ya existe en la clase SPService del ensamblado VSeWSS.Server.Services, que es instalado junto con las extensiones de Visual Studio 2008 para Windows SharePoint Services 3.0, si tu instalación fue hecha en la ruta por default, estos ensamblados se encuentran en C:\Program Files\Microsoft SharePoint Developer Tools 9.0\svc\bin.
El método ExportListDefinition, que es el que se encarga de extraer la definición de la lista en cuestión, hace uso del método GetListTemplateFileExport de la clase SPService, el cual regresa un objeto del tipo ExportFilesResponse, el cual posteriormente es utilizado como parametro en el llamado al metodo SaveAsFile de la clase SPDefinitionExporter, pero que mejor que ver el código para aclarar cualquier duda.
/// <summary> /// Exporta la lista indicada hacia el directorio de salida /// </summary> /// <param name="outputdir" /> /// <param name="url" /> /// <param name="listname" /> private static void ExportListDefinition(string outputdir, string url, string listname) { SPSite site = null; SPWeb web = null; try { using (site = new SPSite(url)) { using (web = site.OpenWeb()) { Guid g = web.Lists[listname].ID; SPService service = new SPService(); ExportFilesResponse response = service.GetListTemplateFileExport(url, g); if (response.IfSuccess) { if (response.Entity != null) { SPDefinitionExporter exporter = new SPDefinitionExporter(outputdir, url); exporter.SaveAsFile(response.Entity); } } } } } catch (Exception ex) { if (web != null) web.Dispose(); if (site != null) site.Dispose(); throw ex; } }
La clase SPDefinitionExporter
internal class SPDefinitionExporter { public string ExportLocation { get; set; } public virtual string TargetSiteUrl { get; set; } // Methods public SPDefinitionExporter(string exportLocation, string targetSiteUrl) { this.ExportLocation = exportLocation; this.TargetSiteUrl = targetSiteUrl; } public void SaveAsFile(ExportFileEntity file) { if (file != null) { string path = string.Format("{0}{1}", this.ExportLocation, file.RelativePath); Directory.CreateDirectory(GetParentDirectoryPath(path)); if (file.IsText) { SaveAsFile(file.ContentStr, path); } else { SaveAsFile(file.ContentBin, path); } } } public void SaveAsFile(IEnumerable<ExportFileEntity> files) { if (files != null) { foreach (ExportFileEntity entity in files) { this.SaveAsFile(entity); } } } private static void SaveAsFile(string contents, string path) { FileStream stream = File.Create(path); StreamWriter writer = new StreamWriter(stream, Encoding.UTF8); writer.Write(contents); writer.Flush(); writer.Close(); stream.Close(); } private static string GetParentDirectoryPath(string path) { if (string.IsNullOrEmpty(path)) { return string.Empty; } int length = path.LastIndexOf(@"\"); return path.Substring(0, length); } private static void SaveAsFile(byte[] contents, string path) { FileStream output = File.Create(path); BinaryWriter writer = new BinaryWriter(output); writer.Write(contents); writer.Flush(); writer.Close(); output.Close(); } }
Corriendo este programita con los siguientes argumentos
ExportListDefinition.exe -url http://siber:81 -path "c:\temp" -listname Empleados
2.- Creando la feature
Una vez que ya tenemos los archivos obtenidos de la utilería que exporta la definición de la lista, es tiempo de crear la feature que provisionara estos archivos en un sitio de SharePoint, para esto recomiendo utilizar algún asistente como VSeWSS 1.3, WSPBuilder, etc.
Yo utilizo WSPBuilder simplemente porque estoy más familiarizado con él, y su uso me parece mas intuitivo.
Entonces creamos la solución, agregamos una nueva feature, y creamos una jerarquía de archivos como la siguiente:
3.- Archivos complementarios
Por default al crear la feature, el asistente nos creara un archivo elements.xml, el cual renombraremos como Instance.xml, y cuya estructura es la siguiente:
También, debemos colocar el archivo ListDefinition.xml, que la utilería creó, al mismo nivel que el archivo Feature.xml y el archivo Instance.xml, a continuación como se ve el archivo Instance.xml de mi ejemplo:
Noten que he resaltado el Id de estos dos elementos, y esto es porque este Id debe ser el mismo, y debe corresponder también con el que se encuentra en el archivo schema.xml, como se aprecia a continuación:
Y ya por último, en el archivo Feature.xml debemos hacer referencia a estos 3 archivos que acabo de mencionar, en la sección ElementManifest, como se muestra a continuación:
Una vez que hagamos todo esto y despleguemos nuestra solución (WSP), en la granja de SharePoint, activamos la Feature que hemos creado.
Y ahora en el sitio en que activamos la feature tenemos una instancia de la lista de empleados:
Pero además podemos crear una lista con el mismo template, ya que también provisionamos la lista como plantilla:
Espero que este tip, sea de utilidad
Happy Coding!
0 comentarios:
Publicar un comentario