Pergunta

Tenho uma situação em que existem requisitos rígidos de permissão em uma lista da qual já escrevi um formulário personalizado.O requisito é que no momento da criação, com base nos metadados, apenas determinados usuários tenham acesso para ler e escrever o item.

Minha primeira tentativa foi colocar isso em um receptor de eventos na lista para garantir que as permissões fossem atualizadas quando o item fosse adicionado.Coloquei o item no evento item adicionado, pois durante a adição do item não tenho como elevar privilégios e obter uma instância elevada do item (que eu saiba).Isso causou um atraso indesejado, embora curto, entre o momento em que o item foi criado e o momento em que o código realmente foi executado.

A próxima coisa que tentei foi definir as permissões do item no formulário imediatamente após a criação do item, pois eu teria um ID para o item para poder recuperá-lo em um contexto elevado (quero que o item seja criado no contexto do usuário atual).Isso é problemático porque assim que essa abordagem é implementada, cerca de 50% das vezes obtemos um erro em um fluxo de trabalho executado na criação do item dizendo:“Falha ao iniciar o fluxo de trabalho.O fluxo de trabalho não pode acessar o item a que foi aplicado. ” (Provavelmente vale a pena notar que este é um fluxo de trabalho da Nintex) - presumo que o problema seja devido a alguma condição de corrida em que no meio do item.Update () definir as permissões, o fluxo de trabalho tenta começar ao mesmo tempo.

Idealmente, eu gostaria de poder atualizar as permissões na primeira atualização (criação) do item ou durante um evento ItemAdding, mas não tenho certeza de como fazer isso sem elevar todo o processo para que o item seja criado pela conta do sistema e não o usuário que realmente criou o item.

Que opções tenho disponíveis para mim?

Foi útil?

Solução

A maneira como você originalmente usava o evento itemadded estava correto.Há apenas um passo faltando - você pode fazer o evento correr imediatamente, alterando-o para ser executado de forma síncrona em vez de assíncronamente.

Detalhes de como alternar o modo síncrono estão aqui: http://blogs.technet.com/b/stefan_gossner/archive/2011/11/10/using-synchronous-quot--Quot-event-Events-itempdated-in-sharepoint-2010.aspx

Outras dicas

Uma abordagem que você poderia tentar, é permitindo a aprovação de conteúdo nessa lista.Isso significará que, sempre que um novo item for criado, ele permanecerá em pendente status até que seja aprovado.Quando um item está no status pendente, apenas o originador do item e as pessoas que têm permissões para gerenciar listas e bibliotecas podem vê-lo, desde que você escolheu a seguinte configuração: Quem deve ver itens raspados nesta biblioteca de documentos?-> Somente usuários que podem aprovar itens (e o autor do item). Então, você pode usar o evento itemadded para alterar as permissões do arquivo e também colocar no estado aprovado .

Espero que isso ajude você em seu cenário específico.

Você deve ser capaz de representar o usuário que criou o item ou fez a alteração no seu 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... 
                   } 
               } 
           }
       }

Elevação de privilégios de personificação

Representação de evento no SharePoint 2010

O que fiz para contornar esse problema foi, em vez de iniciar automaticamente o fluxo de trabalho por meio das configurações do fluxo de trabalho, iniciamos "manualmente" o fluxo de trabalho por meio do código após a atualização das permissões.

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 em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top