В одном из проектов потребовалось на стороне клиента, обнулить значение поля выбора пользователя (PeopleEditor) но как оказалось это не так просто. Поковырявшись в разметке около 3х часов написал следующий код.
Привет всем, этим постом я начну серию по SharePoint (далее шарик), кому-то эти знания покажутся тривиальными, но мне пришлось потратить некоторое время, чтоб найти их и адаптировать по свои нужды. Итак, начнем. В шарике есть встроенная рассылка, когда приходят письма об определенных событиях прошедших на портале. Например, назначение задачи на пользователя или изменение статуса задачи. Можно конечно воспользоваться типами из пространства имен System.Net но в этом случае письма будут приходить не в стиле шарика. Задача 1 предположим у нас на узле шарика есть стандартный список замечаний названный “Замечания” и нужно отправлять оповещение пользователю, на которого назначена данная задача.
SPWeb web =newSPSite(Url–вашегосайтагденаходитсясписок“Замечания”).OpenWeb();SPAlert alert = web.Alerts.Add();//добавляем оповещение
alert.Title="Вам назначена задача";//тут добавляем “начало” темы письма
alert.AlertType=SPAlertType.List;// оповещение для списка (не для конкретного элемента)
alert.EventType=SPEventType.Add;// cобытия на которые срабатывает alert (можно Delete, Discussion, Modify, All и Add)
alert.AlertFrequency=SPAlertFrequency.Immediate;// отсылать оповещение сразу (можно ежденевно, сразу, раз в неделю)
alert.User=null;// оповещение системное, и владельца у него нет
alert.AlertTemplate=newSPAlertTemplate{Name="SPAlertTemplateType.Tasks"};// шаблон сообщения
alert.List= web.Lists["Замечания"];// список на который вешается динамическое оповещение
alert.DynamicRecipient="AssignedTo";// поле, в котором указан пользователь получающий оповещение
alert.Status=SPAlertStatus.On;//включение отключение оповещения
alert.Update(false);//применяем все изменения которые внесли после создания оповещения
Задача 2 нужно отправить оповещение автору задачи, если задача перешла в статус «Выполнено» или «Отклонено»
var chose =newList<string>(){"Выполнено","Отклонено"};for(int j =0; j < chose.Count; j++){SPAlert alertProblem = web.Alerts.Add();
alertProblem.Title="Замечание";
alertProblem.AlertType=SPAlertType.List;// оповещение для списка (не для конкретного элемента)
alertProblem.EventType=SPEventType.Modify;// события на которые срабатывает alert (модификация Items)
Главное отличие этого оповещения от предыдущего это то, что нужно фильтровать события и конечно тут никуда не денешься от CAML запроса. Суть запроса фильтровать изменение в Item и если значение в поле “Status” изменилось и является одним из нужных нам («Выполнено», «Отклонено») то срабатывает оповещение. Вообще возможность применения CAML запросов делает достаточно гибким систему оповещений SharePoint.
alertProblem.Filter= @""+""+""+""+
chose[j]+""+""+//новое значение в поле Status""+""+""+
chose[j]+""+""+// значение в поле Status до изменения""+""+"";
alertProblem.AlertFrequency=SPAlertFrequency.Immediate;
alertProblem.User=null;// оповещение системное, и владельца у него нет
alertProblem.AlertTemplate=newSPAlertTemplate{Name="SPAlertTemplateType.Tasks"};
alertProblem.List= web.Lists["Замечания"];
alert.DynamicRecipient=" Author";// поле, в котором указан пользователь получающий оповещение
alertProblem.Status=SPAlertStatus.On;
alertProblem.Update(false);}
Итогом всего этого будет рассылка писем в стиле SharePoint. Данный код привязать к списку можно консольным приложением или вставив, в какое либо событие. Я его вставил в событие создание web – узла.
И снова здравствуйте, вот решил написать второй пост. При создании очередного проекта возникла потребность, ограничить доступ к элементам списка (задач), и чтобы доступ на редактирование имели только два пользователя — создатель и тот, на кого эта задача назначена, и при этом тот, на кого она назначена, не мог эту задачу удалить. Порывшись в интернете, я обнаружил, что многие программисты вешали проверку прав пользователя на событие, и если пользователь был не тот, то просто кидали стандартное исключение SharePoint о недостатке прав на данную операцию. Но мне это решение не понравилось. Покопавшись, я сделал так, что пользователь, у которого нет прав, не видит операций, которые ему запрещены. Суть решения состоит в том, что при событиях ItemAdded и ItemUpdated я для данной конкретной записи наделяю правами нужных мне пользователей, а остальным пользователям присваиваю роль с правами только для чтения. А поскольку мне нужны специфические права (запрет удаления), мне пришлось создать отдельную роль с ограниченными правами. Итак, теперь поподробней.
privatevoidCreateAccess(SPItemEventProperties properties){DisableEventFiring();//данный метод присутствует в событии ItemUpdated поэтом отключаем Updated чтоб не получить в дальнейшем зацикливание// запись создается/редактируется под пользователем, поднимаем приоритет операций до прав админа (поскольку только он может создавать и назначать роли) SPSecurity.RunWithElevatedPrivileges(delegate(){if(properties.ListItemId!=0){SPWeb web =newSPSite(properties.WebUrl).OpenWeb();//получаем узел SPListItem item = web.Lists[properties.ListTitle].Items.GetItemById(properties.ListItemId);// получаем созданную запись//отключаем наследование прав пользователей списка if(!item.HasUniqueRoleAssignments){ item.BreakRoleInheritance(false);};#region для всех пользователей и групп узла назначаем права ридеровfor(int i =0; i < web.Users.Count; i++){var roleAssignment =newSPRoleAssignment(
web.Users[i].LoginName,
web.Users[i].Email,
web.Users[i].Name,
web.Users[i].Notes);//добавляем пользователя в объект роли
roleAssignment.RoleDefinitionBindings.Add(web.RoleDefinitions.GetByType(SPRoleType.Reader));//назначаем роль ридера
item.RoleAssignments.Add(roleAssignment);добавляемпользователяв«хранилищеролей»записи}for(int i =0; i < web.Groups.Count; i++)// проделываем тоже самое с группами{var roleAssignment =newSPRoleAssignment(web.Groups[i]);
roleAssignment.RoleDefinitionBindings.Add(web.Groups[i].Name=="Группа админов"? web.RoleDefinitions.GetByType(SPRoleType.Administrator): web.RoleDefinitions.GetByType(SPRoleType.Reader));
item.RoleAssignments.Add(roleAssignment);}#endregion
Здесь хочется отметить, что если для данной записи не добавить (или удалить) пользователя из «хранилища ролей» записи, то этот пользователь не увидит данной записи в списке. Что очень удобно, особенно в списке документов, когда нужно спрятать какой-то документ, например контракт.
#region назначаем права для автора и того на кого назначено заданиеSPUser author =newSPFieldUserValue(
web,
properties.ListItem["Author"].ToString()).User;//получаем пользователя из поля автор и назначаем ему роль участникSPRoleAssignment authorRoleAssignment =newSPRoleAssignment(
author.LoginName,
author.Email,
author.Name,
author.Notes);
authorRoleAssignment.RoleDefinitionBindings.Add(web.RoleDefinitions.GetByType(SPRoleType.Contributor));
item.RoleAssignments.Add(authorRoleAssignment);AddAccess(web);// метод создания роли участника но без возможности удаления записи, данный метод описан ниже//Далее созданную роль (Ограниченное участие)// присваиваем пользователю, на которого назначено заданиеSPUser assignedTo =newSPFieldUserValue(
web,
properties.ListItem["AssignedTo"].ToString()).User;SPRoleAssignment assignedToRoleAssignment =newSPRoleAssignment(
assignedTo.LoginName,
assignedTo.Email,
assignedTo.Name,
assignedTo.Notes);
assignedToRoleAssignment.RoleDefinitionBindings.Add(web.RoleDefinitions["Ограниченное участие"]);
item.RoleAssignments.Add(assignedToRoleAssignment);
item.SystemUpdate(false);//поскольку права можно назначить уже созданной записи то чтобы наши манипуляции с правами не попали в журнал версий записи вызываем данный метод#endregion}
Итак, самое интересное: создаем роль, при которой пользователь не будет видеть ни в карточке записи, ни в меню записи в представлении списка команды «удалить запись».
privatevoidAddAccess(SPWeb web){//проверяем, не была ли роль создана ранееbool roleIs =false;foreach(SPRoleDefinition roleDefinition in web.RoleDefinitions){if(roleDefinition.Name=="Ограниченное участие"){ roleIs =true;}}if(!roleIs)//ну и если не было создано роли ранее то собственно создаем саму роль{SPRoleDefinition roleDefinition =newSPRoleDefinition(){BasePermissions=SPBasePermissions.OpenItems|SPBasePermissions.ViewListItems|SPBasePermissions.AddListItems|SPBasePermissions.EditListItems|SPBasePermissions.OpenItems|SPBasePermissions.ViewVersions|SPBasePermissions.DeleteVersions|SPBasePermissions.ManagePersonalViews|SPBasePermissions.ViewFormPages|SPBasePermissions.Open|SPBasePermissions.ViewPages|SPBasePermissions.CreateSSCSite|SPBasePermissions.BrowseDirectories|SPBasePermissions.BrowseUserInfo|SPBasePermissions.AddDelPrivateWebParts|SPBasePermissions.UpdatePersonalWebParts|SPBasePermissions.UseClientIntegration|SPBasePermissions.UseRemoteAPIs|SPBasePermissions.CreateAlerts|SPBasePermissions.EditMyUserInfo,Name="Ограниченное участие",Description="Все привилегии роли Участник кроме возможности удаления"};
web.RoleDefinitions.BreakInheritance(true,true);
web.RoleDefinitions.Add(roleDefinition);
web.Update();}}