Event Receiver to Set Item Level Permissions based on List Column Value
The requirement is to Set Item Level Permission on Document Library Items based on the field in the document library “Visible to Visitors”. The field “Visible to Visitors” is a Checkbox. Technically, When this column set to True, We’ll have to do nothing. When this column set to False, we’ll have to break the inheritance and remove the visitors group from the Item’s permissions.
Lets build a Event Receiver to set Item level permissions based on the field in the Library.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace SetItemLevelPermission
{
class SetPermissions : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
// base.ItemAdded(properties);
SPListItem item = properties.ListItem;
//Check whether the List Item has the "Visible to Visitors" column
if (item.Fields.ContainsField("Visible to Visitors"))
{
//Check whether the Item's "Visible to Visitors" column value is False!
if (item["Visible to Visitors"].ToString().ToLower() == "false")
{
//Break the Inheritence and Remove the Visitor group
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Break the Inheritence
if (!item.HasUniqueRoleAssignments)
{
item.BreakRoleInheritance(true);
//Remove Visitors Group from the Item's permission
item.RoleAssignments.Remove(item.Web.AssociatedVisitorGroup);
}
});
}
}
}
public override void ItemAdding(SPItemEventProperties properties)
{
// base.ItemAdding(properties);
}
public override void ItemUpdated(SPItemEventProperties properties)
{
// base.ItemUpdated(properties);
}
public override void ItemUpdating(SPItemEventProperties properties)
{
// base.ItemUpdating(properties);
//Check whether the List Item has the "Visible to Visitors" column
if (properties.ListItem.Fields.ContainsField("Visible to Visitors"))
{
//Check whether the "Visible to Visitors" column value is changed
//IMPORTANT: Use the internal name in AfterProperties, otherwise, It will not work!!!
if (properties.ListItem["Visible to Visitors"].ToString().ToLower() != properties.AfterProperties["Visible_x0020_To_x0020_Visitors"].ToString().ToLower())
{
SPListItem item = properties.ListItem;
//Check whether the Item's "Visible to Visitors" column value is True!
if (properties.AfterProperties["Visible_x0020_To_x0020_Visitors"].ToString().ToLower() == "true")
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Reset the Inheritense
if (item.HasUniqueRoleAssignments)
{
item.ResetRoleInheritance();
}
});
}
else // Visible to Viewers= "false"
{
//Break the Inheritence and Remove the Visitor group
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Break the Inheritence
if (!item.HasUniqueRoleAssignments)
{
item.BreakRoleInheritance(true);
//Remove Visitors Group from the Item's permission
item.RoleAssignments.Remove(item.Web.AssociatedVisitorGroup);
}
});
}
}
}
}
}
}
Alright, our Event Receiver is ready! Lets Create a Feature to Bind the Event Receiver with All Document Libraries. How? Update the Elements.xml file with the Event Receiver details:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
<Receivers ListTemplateId="101">
<Receiver>
<Name>AddedEventHandler</Name>
<Type>ItemAdded</Type>
<SequenceNumber>10000</SequenceNumber>
<Assembly>SetItemLevelPermission, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e166fe20cd991fe</Assembly>
<Class>SetItemLevelPermission.SetPermissions</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
<Receiver>
<Name>UpdatingEventHandler</Name>
<Type>ItemUpdating</Type>
<SequenceNumber>10000</SequenceNumber>
<Assembly>SetItemLevelPermission, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e166fe20cd991fe</Assembly>
<Class>SetItemLevelPermission.SetPermissions</Class>
<Data></Data>
<Filter></Filter>
</Receiver>
</Receivers>
</Elements>
Build and Deploy the WSP and we’re done!
Excelent post! Thank you for saving my day 🙂 Just one qustion, I got “NullRefferenceException” on line:
if (properties.ListItem[“Visible to Visitors”].ToString().ToLower() != properties.AfterProperties[“Visible_x0020_To_x0020_Visitors”].ToString().ToLower())
And FYI, I’ve double -checked my internal name wich is “Visible_x0020_to_x0020_Visitors” and it’s still throwing the sam exception. What could be the problem?
Thank u in advance!
When an item is edited from SharePoint interface, then both properties.ListItem[“Visible to Visitors”] and properties.AfterProperties[“Visible_x0020_To_x0020_Visitors”] has the expected values.
But, when the list item is being updated by code, and the code does not update the “Visible to Visitors” field, then properties.AfterProperties[“Visible_x0020_To_x0020_Visitors”] will be NULL in the event receiver code. AfterProperties will have the correct value, only when “Visible to Visitors” is also updated through code.
This doesn’t occur when editing is done through SharePoint UI.