User field in Event Receivers when using Claims based authentication and Classic mode authentication

When accessing a user field in event receivers there are few differences in the returned values when Classic mode authentication is used from the value when Claims based authentication is used. The difference is present in AfterProperties of ItemAdding and ItemUpdating event. This is true for SharePoint 2010 and SharePoint 2013 and its present only for custom lists but not for document libraries. I’ve done some testing and the results are presented in this post.

Testing

For testing I created a custom list that contains one User field, added the event receiver and overrode all the list item event handlers. For every event I tried to get the value of the user field from properties.BeforeProperties, properties.AfterProperties and properties.ListItem. The test is performed when adding/changing/deleting the item’s user field using the UI (New and Edit form) and when adding/changing/deleting the field pragmatically. The test is repeated when using Classic authentication and when using Claims based authentication. Also the test is repeated for SharePoint 2010 and SharePoint 2013.

Test results

From the results it turns out that when getting the value of a user field from AfterProperties in ItemAdding and ItemUpdating events the value is different when using the New and Edit form from the value when adding and updating the field pragmatically. This difference is present only when using Claims based authentication.
Below are shown the results only for the events that have this problem. At the end of this post you can find the complete test results for SharePoint 2013. In the tests user1 and user2 are used and they happen to have ID of 41 and 42.

Results when using claims based authentication :

When adding, modifying and deleting item using the UI:

Event From Value
ItemAdding AfterProperties -1;#i:0#.w|domain\user1
ItemUpdating AfterProperties -1;#i:0#.w|domain\user2

When adding,modifying and deleting an item programatically:

Event From Value
ItemAdding AfterProperties 41
ItemUpdating AfterProperties 42
Results when using classic authentication:

When adding,modifying and deleting an item using the UI:

Event From Value
ItemAdding AfterProperties 41
ItemUpdating AfterProperties 42

When adding,modifying and deleting an item programatically:

Event From Value
ItemAdding AfterProperties 41
ItemUpdating AfterProperties 42

You can see that the problem is only with claims based authentication while with classic authentication the results are the same when the item is added/modified using the UI and when it’s added/modified programmatically.
One small difference between SharePoint 2010 and SharePoint 2013 is that in SharePoint 2010 even if the user field is not changed the AfterProperties in ItemUpdating event will have the value “-1;#i:0#.w|domain\user1”. In SharePoint 2013 if the field is not changed then the AfterProperties in ItemUpdating event contain the user ID.

Consequences

Because of these differences it’s possible that your old code which has worked fine with classic authentication will not work with claims based authentication.
For example with classic based authentication in ItemAdding and ItemUpdating events the modified value of a user field can be retrieved as below:

 SPUser user = new SPFieldUserValue(properties.Web, properties.AfterProperties["UserField"].ToString()).User;

This code will not work when using Claims based authentication because the value of properties.AfeterProperties[“UserField”] is “-1;#i:0#.w|domain\user1”

Solution

Because its happening only when adding and modifying a user field using the New and Edit form it seems that the problem is with the PeapleEditor control. For some reason it doesn’t work as well with claims based authentication as it does with classic authentication.
To solve the problem I changed my code for getting the user from AfterProperties so it would work for Claims authentication no matter is the field changed using the PeapleEditor control or programmatically.

public static SPUser GetUserFromAfterProperties(object property, SPWeb web)
{
	SPUser user = null;
	string fieldValue = property == null ? null : property.ToString();

	//If adding/editing item directly in the list using NewItem/EditItem form
	if (fieldValue.Contains(";#"))
	{
		string loginName = fieldValue.Contains(";#") ? fieldValue.Split(new string[] { ";#" }, StringSplitOptions.None)[1] : null;
		user = web.EnsureUser(loginName);
	}
	//If adding/editing item programatically
	else
	{
		user = new SPFieldUserValue(web, poperty.ToString()).User;
	}

	return user;
}

To get the user from after properties call the above function in your event receiver:

SPUser user = GetUserFromAfterProperties(properties.AfterProperties["YourUserField"], properties.Web);

All test results

For reference below are all the results from the tests for SharePoint 2013 for Claims based authentication and Classic authentication, both when working with a list item using the UI and programmatically.

Resluts when using claims based authentication:

When adding, modifying and deleting item using the UI:

Event From Value
ItemAdding AfterProperties -1;#i:0#.w|neodomain0\u1
ItemAdding BeforeProperties N/A
ItemAdding ListItem ListItem = null
ItemAdded AfterProperties 41
ItemAdded BeforeProperties N/A
ItemAdded ListItem 41;#u1
ItemUpdating AfterProperties -1;#i:0#.w|neodomain0\u2
ItemUpdating BeforeProperties N/A
ItemUpdating ListItem 41;#u1
ItemUpdated AfterProperties 42
ItemUpdated BeforeProperties N/A
ItemUpdated ListItem 42;#u2
ItemDeleting AfterProperties N/A
ItemDeleting BeforeProperties N/A
ItemDeleting ListItem 42;#u2
ItemDeleted AfterProperties N/A
ItemDeleted BeforeProperties N/A
ItemDeleted ListItem ListItem = null

When adding,modifying and deleting an item programatically:

Event From Value
ItemAdding AfterProperties 41
ItemAdding BeforeProperties N/A
ItemAdding ListItem ListItem = null
ItemAdded AfterProperties 41
ItemAdded BeforeProperties N/A
ItemAdded ListItem 41;#u1
ItemUpdating AfterProperties 42
ItemUpdating BeforeProperties N/A
ItemUpdating ListItem 41;#u1
ItemUpdated AfterProperties 42
ItemUpdated BeforeProperties N/A
ItemUpdated ListItem 42;#u2
ItemDeleting AfterProperties N/A
ItemDeleting BeforeProperties N/A
ItemDeleting ListItem 42;#u2
ItemDeleted AfterProperties N/A
ItemDeleted BeforeProperties N/A
ItemDeleted ListItem ListItem = null
Results when using classic authentication:

When adding,modifying and deleting an item using the UI:

Event Properties Result
ItemAdding AfterProperties 8
ItemAdding BeforeProperties N/A
ItemAdding ListItem ListItem = null
ItemAdded AfterProperties 8
ItemAdded BeforeProperties N/A
ItemAdded ListItem 8;#u1
ItemUpdating AfterProperties 9
ItemUpdating BeforeProperties N/A
ItemUpdating ListItem 8;#u1
ItemUpdated AfterProperties 9
ItemUpdated BeforeProperties N/A
ItemUpdated ListItem 9;#u2
ItemDeleting AfterProperties N/A
ItemDeleting BeforeProperties N/A
ItemDeleting ListItem 9;#u2
ItemDeleted AfterProperties N/A
ItemDeleted BeforeProperties N/A
ItemDeleted ListItem ListItem = null

When adding,modifying and deleting an item programatically:

Event Properties Result
ItemAdding AfterProperties 8
ItemAdding BeforeProperties N/A
ItemAdding ListItem ListItem = null
ItemAdded AfterProperties 8
ItemAdded BeforeProperties N/A
ItemAdded ListItem 8;#u1
ItemUpdating AfterProperties 9
ItemUpdating BeforeProperties N/A
ItemUpdating ListItem 8;#u1
ItemUpdated AfterProperties 9
ItemUpdated BeforeProperties N/A
ItemUpdated ListItem 9;#u2
ItemDeleting AfterProperties N/A
ItemDeleting BeforeProperties N/A
ItemDeleting ListItem 9;#u2
ItemDeleted AfterProperties N/A
ItemDeleted BeforeProperties N/A
ItemDeleted ListItem ListItem = null

Add, Modify or Delete List Event Receivers with PowerShell

Developing and troubleshooting custom SharePoint solutions always involves checking, adding, modifying or deleting event receivers. When working on production servers usually we don’t have all the tools that we have in our own VMs. In those cases we can use PowerShell or write inline code in an application page and put it in the LAYOUTS folder in SharePoint Root.

Below are some PowerShell commands to check, add, modify and remove list event receivers.

It goes without saying that you should be very careful when working with event receivers as with everything else in SharePoint. Save the original state with a back up, or at least make sure you know which event receivers are there with all their properties before modifying anything. That way you can get everything back in the original state.

Checking event receivers:

After getting the list in PowerShell you can just run $list.EventReceivers and it will show all the event receivers will all their properties.

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://....
$list = $web.GetList($web.Url + '/Lists/' + “list name”)
$list.EventReceivers

To save the result in a text file for future reference execute the following command:

$list.EventReceivers | Out-File -filepath "D:\EventReceivers.txt"

Add EventReceiver

To add an event receiver you need to know the full assembly name (you can get that from GAC) and the class name that contains the event receivers

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://....
$list = $web.GetList($web.Url + "/Lists/" + “list name”)

$type = "ItemAdding" #or any other type, like ItemDeleting, ItemAdded, ItemUpdating ...
$assembly = "YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5eff...(here goes assebly's token"
$class = "Your Class"

$list.EventReceivers.Add($type, $assembly, $class)

$web.Dispose()

Modify Event Receiver

For example, to change an after event EventReceiver from asynchronous to synchronous

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://...
$list = $web.GetList($web.Url + "/Lists/" + “list name”)

$type = "ItemAdded" #or any other type, like ItemDeleting, ItemAdding, ItemUpdating, ...

$numberOfEventReceivers = $list.EventReceivers.Count

if ($numberOfEventReceivers -gt 0)
{
 for( $index = $numberOfEventReceivers -1; $index -gt -1; $index–-)
 {
 	$receiver = $list.EventReceivers[$index] ;
 	$name = $receiver.Name
 	$typ = $receiver.Type ;

 if ($typ -eq $type)  #or you can check ($name -eq "event receiver's name") if you have more then one event receivers of the same type
 {
 	$receiver.Synchronization = "Synchronous"
	$receiver.Update()
	Write-Host "Event receiver " $name " is changed to Synchronous"
 }
 }
}
else
{
 	Write-Host " There is no EventReceiver of type " $type " registered for this list "
}

$web.Dispose()

Delete Event Receivers

Run the following to delete a specific event receiver (in this example ItemDeleting event receiver)

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://...
$list = $web.GetList($web.Url + "/Lists/" + “list name”)

$type = "ItemDeleting" #or any other type, like ItemDeleting, ItemAdding, ItemUpdating, ...

$numberOfEventReceivers = $list.EventReceivers.Count

if ($numberOfEventReceivers -gt 0)
{
   for( $index = $numberOfEventReceivers -1; $index -gt -1; $index–-)
   {
      $receiver = $list.EventReceivers[$index] ;
      $name = $receiver.Name
      $typ = $receiver.Type ;

      if ($typ -eq $type)  #or you can check ($name -eq "event receiver's name") if you have more then one event receivers of the same type
      {
         $receiver.Delete()
         Write-Host "Event receiver " $name " is deleted"
      }
   }
}
else
{
   Write-Host " There is no EventReceivers of type " $type " registered for this list "
}

$web.Dispose()
%d bloggers like this: