2011-02-01 4 views
2

확인. 사용자에게 업로드하는 모든 파일을 완벽하게 제어 할 수있는 이벤트 수신기를 작성하려고합니다. 관리자로 로그인 한 상태에서 코드를 작동시킬 수 있습니다. 기고자로 로그인하고 파일을 업로드 할 때도 동일한 코드가 System.UnauthorizedAccessException:> Access is denied. (Exception from HRESULT: x80070005E_ACCESSDENIED)) 예외로 표시됩니다.SPItemEventReceiver ItemAdded에서 참가자의 변경 권한을 설정하려면 어떻게해야합니까?

아래의 주석 처리 된 코드에서 볼 수있는 것처럼 문제를 해결하기 위해 몇 가지 '해결책'과 다양한 다른 방법을 시도했습니다. 내가 읽은 것부터, 문제의 객체에 대한 권한을 가지기 위해 특권이 상승하는 동안 객체를 어떻게 든 재현 할 필요가있을 것이다. 그러나이 두 가지 방법 모두 해당 항목을 찾을 수 없습니다. 항목이 아직 목록에없는 것 같습니다. 오, 이건 문서 라이브러리입니다.

//Works as admin 
    public override void ItemAdded(SPItemEventProperties properties) 
    { 
     base.ItemAdded(properties);//tried putting this at top and bottom of method, thinking perhaps this where the file get put in list. 

     SPSecurity.RunWithElevatedPrivileges(delegate 
     { 
      using (var site = new SPSite(properties.SiteId)) 
      using (var web = site.OpenWeb(properties.RelativeWebUrl)) 
      { 
        ... 

        //works when admin 
        var item = properties.ListItem; 

        //attempt: by item url 
         //this does not work, file not found 
        var item = web.GetListItem(properties.ListItem.Url); 

        //attempt: by item ID 
         // this works 
        var list = web.Lists[properties.ListId]; 
         //this does not 
        var item = list.GetItemById(properties.ListItemId); 


        item.BreakRoleInheritance(true); //this get the access denied error 
        item.RoleAssignments.Add(GetRoleAssignment(web, item)); 

        ... 
      } 
     } 
     base.ItemAdded(properties); 
    } 




UPDATE는


그래서, 현재 일하고있는 솔루션입니다 :

 ... 

     SPSecurity.RunWithElevatedPrivileges(delegate 
     { 
      using (var site = new SPSite(properties.SiteId)) 
      using (var web = site.OpenWeb(properties.RelativeWebUrl)) 
      { 
       try 
       { 
        properties.ListItem.File.CheckIn(String.Empty); 
        System.Threading.Thread.Sleep(1000); 
        var list = web.Lists[properties.ListId]; 
        var item = list.Items[properties.ListItem.UniqueId]; 
        item.BreakRoleInheritance(true); 
        item.RoleAssignments.Add(GetRoleAssignment(web, item)); 
       } 
       catch (Exception e) 
       { 
        LogError(e.ToString()); 
       } 
       finally 
       { 
        properties.ListItem.File.CheckOut(); 
        ... 
       } 
      } 
     }); 

     ... 

내가는 타이머의 필요성에 관한 몇 가지 우려를 가지고 내가 다른 곳에서 모은 아이디어. 필자가 본 것에서는 ItemAdded가 비동기식으로 실행되는 것으로 보이고 타이머가 필요하기 때문에 CheckIn은 비동기식으로 보인다. 나는 그것이 왜 그렇게 행동하는지 모르겠다. 그러나 그것은 나의 가설이다.

답변

5

업로드 할 파일이 기본적으로 체크 아웃되므로 RunwithElevatedPrevileges 블록에서도 ListItem을 검색 할 수 없습니다. 이 작업을 시도하십시오 : RunwithElevatedPrevileges 블록 바로 전에

properties.ListItem.File.CheckIn(String.Empty); 

블록을 실행하십시오.

+0

그것이 핵심이었습니다. 감사. –

0

응용 프로그램 풀 계정이 사이트 모음 관리자가 아닌 것 같습니다. RunwithElevatedPrevileges을 수행하면 기본적으로 응용 프로그램 풀 계정으로 가장합니다. 그러므로 해당 계정의 권한이 있는지 확인하십시오.

+0

나는 둘을 같은 것으로 만들었습니다 (둘 다 "관리자"로 설정 됨). 변경 없음. 관리자로 로그인했지만 참여자 계정으로 로그인하지 않은 경우에도 작동합니다. 내가 이해 한 바로는 속성에서 목록 항목에 액세스 할 때 현재 사용자가 목록을 만듭니다. –

관련 문제