El cliente solicitó una eliminación en cascada, vamos a explicarlo, eran tres listas, "Project" , "Task" y "Project Documents", primero se crea un proyecto, despúes crean tareas en la lista "Task" para este proyecto, luego cabe la posibilidad de subir documentos a la lista "Project Documents" y enlazarlos directamente al projecto o a una tarea específica, la idea del desarrollo era si se elimina un proyecto entonces que se eliminen las tareas relacionadas a este proyecto y tambien los documentos relacionados ya sea a la tarea o al proyecto.
Nada fuera de lo común, escribí el código y todo bien, hasta que pasamos al "User acceptance test", todo va bien excepto que lo prueba alguien con acceso "Contribute" al sitio y se elimina el proyecto, las tares pero los documentos no se eliminan.
Ummm, que extraño si claramente estaba usando la "impersonation" de sharepoint para evitar este tipo de problemas. Despúes de realizar bastantes pruebas con diferentes usuarios sigue igual, lo curioso es que el acceso "Contribute" en sharepoint permite eliminar archivos, ¿ Qué podría estar pasando?.
El código estaba de esta manera.
private void processItemDeleting(SPItemEventProperties properties)
{ base.DisableEventFiring(); SPSecurity.RunWithElevatedPrivileges(delegate(){ using(SPWeb web = properties.OpenWeb())
{ //aqui va toda la lógica que necesitamos hacer } } }Como se puede apreciar estamos usando la función SP.Security.RunWithElevatedPriveleges, esto normalmente nos permite ejecutar código con el nivel más alto.
Despúes de investigar, leer acerca de permisos en sharepoint, de particularidades de event receiver, encontré un solo artículo que me ayudó.
Para solucionar el problema era necesario escribir el código de la siguiente manera.
private void processItemDeleting(SPItemEventProperties properties)
{ base.DisableEventFiring(); SPSecurity.RunWithElevatedPrivileges(delegate(){ using (SPSite site = new SPSite(properties.SiteId))
{ using (SPWeb web = site.OpenWeb("cla"))
{ using (SPWeb web2 = web.Webs["ProcessCon"]){ var item = properties.ListItem; web.AllowUnsafeUpdates = true; } } } }}La diferencia con el primer código que escribimos es que estamos abriendo de nuevo el sitio con el que queremos trabajar. Asi que para evitar el problema de "Acces denied" en un event receiver debemos de abrir de nuevo el sitio, si miramos el primer código de una vez accedemos al web donde estamos con el método de properties.OpenWeb(); pero en el segundo caso tomamos el SiteId que obtenemos en el objeto
SPItemEventProperties y abrimos un nuevo sitio.
La desventaja con esto es que tenemos que abrir la web donde vamos a trabar y si es como mi caso que el url era algo asi, http://server/sites/rootSite/subsite1/subsite2 se debe de hacer de la forma mostrada para acceder al subsite2 porque el método OpenWeb(); no tiene una sobrecarga que nos permita obtener el subsite2 de una forma directa.
Espero que esto les pueda ayudar si tiene un problema parecido o les ayude en su conocimiento del desarrollo en Sharepoint.
Muchas gracias.
No hay comentarios:
Publicar un comentario