Ver Parte I
Qué se debe hacer cuando necesitamos obtener las vistas que pertenecen a una lista específica?
public IList < TGLista > GetViews(Guid idList)
{
SPWeb webList = this.GetWebByIdList(idList);
if (webList != null)
{
TGLista vista = null;
IList
SPList listaTemp = null;
try
{
listaTemp = webList.Lists[idList];
foreach (SPView temp in listaTemp.Views)
{
vista = new TGLista();
vista.Id = temp.ID;
vista.Titulo = temp.Title;
vistas.Add(vista);
}
}
catch (SPException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
finally
{
if (webList != null)
webList.Dispose();
}
if (vistas != null)
{
//Hace un ordenamiento ASCENDENTE de la lista
var list = from temp in vistas
orderby temp.Titulo
select temp;
return list.ToList();
}
}
return null;
}
Nuevamente se aprecia el uso de una clase entidad para almacenar la información a pasar entre capas usando una colección genérica de dichos objetos.
Quizá lo que más rescato como buena práctica del método anterior es que si se fijan, el método recibe por parámetro el ID de la lista para la cual queremos obtener sus vistas. No el nombre de la lista (string) o su índice dentro de alguna colección, que puede ser un entero. No se recibe su GUID que es la técnica mejor considerada cuando uno quiere referirse a una lista de SharePoint. La razón que más me gusta y que resguarda las soluciones de problemas "tontos", es que aunque los usuarios finales cambien el nombre de la lista (título o caption), el ID interno se conserva, y eso ya evita que el código quede "débil". Si el usuario borra su lista, apague y vámonos, ahí no hay anda que hacer, pero bueno eso ya son situaciones que se corrigen con un buen entrenamiento y conocimiento de los usuarios de las soluciones.
Un poco de CAML, como buena práctica no le cae mal a una solución SharePoint 2007.
private SPListItem GetItemByTitle(string titulo)
{
SPWeb web = SPContext.Current.Site.RootWeb;
SPQuery query = new SPQuery();
query.Query = "
try
{
SPList list = web.Lists["Objetivos KPI"];
foreach (SPListItem item in list.GetItems(query))
{
return item;
}
}
catch (Exception ex)
{
throw;
}
return null;
}
Lo único más interesante a rescatar es el uso de la consulta CAML que lo único que hace es filtrar los ítems de la lista por un título dado. De aquí solamente quiero decirles que usen herramientas como CAML Builder
Y qué pasa cuando quiero guardar un archivo generado por la solución en una biblioteca de SharePoint?
public void SaveLibrary(string file,Stream stream,Guid idList)
{
SPFolder spFolder = null;
SPFile spFileTemp = null;
TGServices services = new TGServices();
SPListItem item = null;
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPWeb web = this.GetWebByIdList(idList))
{
web.AllowUnsafeUpdates = true;
spFolder = web.Folders["Plantillas Excel"];
spFileTemp = spFolder.Files.Add(file, stream, true);
spFolder.Update();
item = spFileTemp.Item;
item.UpdateOverwriteVersion();
web.AllowUnsafeUpdates = false;
}
});
}
catch (SPException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
finally
{
if (stream != null)
stream.Close();
}
}
Y para usar el método anterior podría tenerse algo similar:
FileInfo fileToLibrary = null;
try
{
fileToLibrary = new FileInfo(file);
link = services.SaveLibrary(file, fileToLibrary.OpenRead(), new Guid(IdLista));
}
Lo primero que el método recibe es el nombre de un archivo por ejemplo miarchivo.xlsx. Luego lo más importante recibe un Stream, en el ejemplo anterior se muestra cómo crear dicho stream y pasárselo al método en modo openRead(). Y finalmente pasar el ID de la lista, que quizá nos sirva como fuente para obtener el sitio de ejecución del proceso.
Muy importante la línea SPSecurity.RunWithElevatedPrivileges(delegate()
porque ejecuta el proceso de guardar a la biblioteca de documentos Plantillas Excel en un modo de privilegios elevados, así no tener problemas de acceso negado si el usuario ejecutando la solución no tiene suficientes permisos sobre la biblioteca.
Y siendo el resto de código algo entendible, lo realmente importante es dejar la seguridad de la ejecución como estaba web.AllowUnsafeUpdates = false;
Eso indica que solo ese tramo del código fue elevado, el resto de la ejecución continuará con los permisos del usuario que está ejecutando la solución.
Feliz coding!!