Pregunta

Tengo una situación en la que hay requisitos de permisos estrictos en una lista de la cual ya he escrito un formulario personalizado. El requisito es que, a la creación, en función de los metadatos, solo ciertos usuarios tienen acceso a leer y escribir el artículo.

Mi primer intento de esto fue poner esto en un receptor de eventos en la lista para asegurarse de que los permisos se actualicen cuando se agregue el artículo. Puse el artículo en el evento agregado del artículo, ya que durante el artículo agregado, no tengo una manera de elevar los privilegios y obtener una instancia elevada del artículo (que conozco). Esto provocó un retraso no deseado, aunque corto, entre el momento en que se creó el artículo y el tiempo que realmente corrió.

Lo siguiente que intenté fue poner los permisos de elementos en el formulario inmediatamente después de que se cree el artículo, ya que luego tendría una identificación para el artículo para que pueda recuperarlo en un contexto elevado (quiero que el artículo sea el elemento creado en el contexto del usuario actual). Esto es problemático porque tan pronto como se implementó este enfoque, aproximadamente el 50% del tiempo obtenemos un error en un flujo de trabajo que se ejecuta en el artículo Crear dicho: "Error al iniciar el flujo de trabajo. El flujo de trabajo no puede acceder al artículo que se ha aplicado ". (Probablemente vale la pena señalar que esto es un flujo de trabajo de NintEx): asumo que el problema se debe a una condición de raza donde en medio del artículo. Utilice () para establecer los permisos, el flujo de trabajo intenta comenzar a la misma hora.

Idealmente, me gustaría poder actualizar los permisos en la primera actualización del artículo (crear) o durante un evento del elemento, pero no estoy seguro de cómo hacerlo sin elevar todo el proceso, de modo que el artículo sea creado por el artículo. La cuenta del sistema y no el usuario que realmente creó el artículo.

¿Qué opciones tengo disponibles para mí?

¿Fue útil?

Solución

La forma en que originalmente lo tenía usando el evento de artículos fue correcto.Sin embargo, solo falta un paso: puede hacer que el evento se ejecute inmediatamente cambiándolo para funcionar de forma sincrónica en lugar de de forma asíncrona.

Los detalles de cómo cambiar el modo síncrono están aquí: http://bogs.technet.com/b/stefan_gossner/archive/2011/11/10/using-ynchuchronous-quot-spter-quot-event-event-item itemupdated-in-sharepoint-2010.aspx

Otros consejos

Un enfoque que podría intentar, está permitiendo la aprobación de contenido en esa lista.Esto significará, que siempre que se cree un nuevo artículo, permanecerá en el estado pendiente hasta que esté aprobado.Cuando un artículo está en estado pendiente, solo el originador del artículo y las personas que tienen permisos para administrar listas y bibliotecas pueden verla, siempre que haya elegido la siguiente configuración: ¿Quién debería ver los proyectos de elementos en esta biblioteca de documentos?-> Solo usuarios que pueden aprobar los artículos (y el autor del artículo). Luego, podría usar el evento itemDeded para cambiar los permisos del archivo y también poner en el estado aprobado .

Espero que esto lo ayude en su escenario en particular.

Debe poder hacerse pasar por el usuario que creó el artículo o hizo el cambio en su código.

    public override void ItemUpdating(SPItemEventProperties properties)     
       {     
           base.ItemUpdating(properties);

           SPUserToken objSPUserToken = properties.OriginatingUserToken;

           if (objSPUserToken != null) 
           { 
               using (SPSite objSPSite = new SPSite(properties.SiteId, objSPUserToken)) 
               { 
                   using (SPWeb objSPWeb = objSPSite.OpenWeb())

                   { 
                       //You can perform user context specific changes here... 
                   } 
               } 
           }
       }

Elevación de impersonación de privilegios

Impersonación de eventos en SharePoint 2010

Lo que he hecho para pasar por este problema es en lugar de iniciar automáticamente el flujo de trabajo a través de la configuración del flujo de trabajo, estamos "manualmente" que inician el flujo de trabajo a través del código después de actualizar los permisos.

string workflowId = "{...}"; //dynamically retrieve workflow id
SPWorkflowManager workflowManager = item.Web.Site.WorkflowManager;
SPWorkflowAssociationCollection workflowCollection = item.ParentList.WorkflowAssociations;

foreach (SPWorkflowAssociation workflow in workflowCollection)
{
    if (String.Compare(workflow.BaseId.ToString("B"), workflowId, true) == 0)
    {
        workflowManager.StartWorkflow(item, workflow, workflow.AssociationData, true);
        break;
    }
}

Licenciado bajo: CC-BY-SA con atribución
scroll top