처음 저장하기 전에 항목 수준 권한을 프로그래밍 방식으로 수정하는 방법은 무엇입니까?
문제
나는 이미 사용자 정의 양식을 작성한 목록에 엄격한 사용 권한 요구 사항이있는 상황이 있습니다. 요구 사항은 메타 데이터를 기반으로 작성시 특정 사용자만이 항목을 읽고 쓸 수 있도록 액세스 할 수있는 것입니다.
첫 번째 시도는 이벤트 수신자 에이 항목을 추가 할 때 사용 권한이 업데이트되었는지 확인하는 것입니다. 항목을 추가 한 경우 항목을 추가 한 이벤트에 항목을 넣고 특권을 높이고 상품의 상승 된 인스턴스를 얻을 수있는 방법이 없습니다. 이로 인해 항목이 작성된 시간과 코드가 실제로 실행되는 시간 사이에 짧지 만 원하지 않는 지연이 발생했습니다.
내가 시도한 다음의 다음은 상승 된 컨텍스트에서 그것을 검색 할 수 있도록 항목에 대한 ID를 가지고 있기 때문에 항목을 만들 때 즉시 양식의 항목을 설정하는 것입니다 (항목을 원한다. 현재 사용자의 컨텍스트 하에서 생성됨). 이것은이 접근 방식이 구현되는 즉시 문제가되는 경우 약 50 %의 시간의 오류가 발생하여 "워크 플로를 시작하지 못했습니다. 워크 플로가 적용된 항목에 액세스 할 수 없습니다. " (이것은 NINTEX 워크 플로우임을 주목할 가치가 있습니다.) - 일부 경쟁 조건으로 인한 문제가 권한을 설정하려면 워크 플로가 동시에 시작하려고 시도합니다.
이상적으로 첫 번째 항목 업데이트 (생성) 또는 itemaddding 이벤트 중에 사용 권한을 업데이트 할 수 있지만 항목이 만들어진 다음 프로세스를 제작하지 않고 전체 프로세스를 상승하지 않고이 작업을 수행하는 방법을 모르겠습니다. 실제로 항목을 만든 사용자가 아닌 시스템 계정이 아닙니다.
어떤 옵션을 사용할 수 있습니까?
해결책
원래 ItemAdded 이벤트를 사용하여 가져간 방식이 올바른 것입니다.비동기 대신 동기식으로 실행되도록 변경하여 이벤트를 즉시 실행할 수 있습니다.
동기 모드를 전환하는 방법에 대한 세부 사항은 다음과 같습니다. http://blogs.technet.com/b/stefan_gossner/archive/2011/11/10/using-synchronous-quot-after- quot-efvent-eg-itemupdated-in-sharepoint-2010.aspx
다른 팁
시도 할 수있는 한 접근법은 해당 목록에서 콘텐츠 승인을 가능하게합니다.이렇게하면 새 항목이 생성 될 때마다 승인 될 때까지 보류 중 상태가 유지됩니다.항목이 보류중인 상태가되면 항목의 발신자만이 다음 설정을 선택한 다음 설정을 선택하면 다음과 같은 설정을 선택할 수 있습니다.이 문서 라이브러리의 초안 항목은 누구입니까?-> 항목을 승인 할 수있는 사용자 (및 항목 작성자). 그런 다음 itemAdded 이벤트를 사용하여 파일의 사용 권한을 변경하고 승인 상태에 넣을 수 있습니다.
이것은 당신이 당신의 특정 시나리오에서 당신을 돕기를 바랍니다.
항목을 만든 사용자를 가장하거나 코드를 변경 한 사용자를 가장 할 수 있어야합니다.
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...
}
}
}
}
.
이 문제를 해결하기 위해 수행 한 것은 워크 플로 설정을 통해 자동으로 워크 플로를 시작하는 대신 "수동으로"권한이 업데이트 된 후 코드를 통해 워크 플로우를 시작합니다.
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;
}
}
.