1

Scenario:

SharePoint 2010. A list is configured with this setting turned on: "Create items and edit items that were created by the user". Users can only edit or delete their own items; if they try to edit or delete someone else's items, they are shown an error message saying that they are not allowed to perform the action.

An ItemDeleting event receiver is attached to the list. The problem is it gets fired even though it will eventually get cancelled, because the user is not allowed to delete the item, due to the aforementioned settings.

Question:

Is there a way to prevent a custom event to fire in such a scenario? OR, is there a way to detect, from within the event receiver code, that this event will eventually get cancelled by the system ?

I would like not having to go through a check to determine whether the user is allowed to perform this particular action or not, because this would essentially make the above setting pointless (if I had to check the user's permissions anyway, I could as well turn it off).

1

I would suspect that SharePoint has an event receiver themself that on ItemDeleting checks the setting on the list to see if the deleting should be allowed, hopefully they do a "CancelWithRedirect" if not so.

So I should start with making sure my event reciever is synchronous and give it a higher Sequence numbert than today, to force it to execute after the SharePoint one.

This two parts in the Elements.xml of the reciever:

    <SequenceNumber>10000</SequenceNumber>
    <Synchronization>Synchronous</Synchronization>

Also, could you not check the properties.Cancel in your event receiver? If it is true, you could do nothing.

If that does not help, it point at SharePoint not using the properties.Cancel, and you might be out of luck.

I know you do not want to, but here is a snippet for quickly checking that the current user is indeed the item creator:

public override void ItemDeleting(SPItemEventProperties properties)
{
    using(SPSite site = new SPSite(properties.SiteId))
    {
        using(SPWeb web = site.OpenWeb(properties.RelativeWebUrl))
        { 
            SPFieldUserValue user = new SPFieldUserValue(web, web.CurrentUser.ID, web.CurrentUser.LoginName);

            if(properties.ListItem["Author"] == user)
               return;

            properties.Cancel = true;
            properties.ErrorMessage = "You cannot delete items created by other users";
        }
    }
}

Source

  • Thanks, but this is how it's currently configured (it's the default setting Visual Studio creates for you when you add an item receiver to your project). The synchronous setting is also the default for a *ing event receiver type – MdMazzotti May 30 '14 at 8:43
  • I know it it the default settings, but had no way of knowing if you where using default or not ;) – Robert Lindgren May 30 '14 at 8:44
  • But the fact that you have your receiver executing is bad news, since that point in a direction of SharePoint not using "CancelWithRedirect" internally :( – Robert Lindgren May 30 '14 at 8:45
  • Updated my answer with another suggestion (and an unwanted snippet for doing the permissions check ;)) – Robert Lindgren May 30 '14 at 8:49
  • It's very bad news indeed. And the error came out because we made the wrong assumption that these system-handled events would occur first. The Cancel property is set to false when my event gets fired (bummer!). I'll make some experiments with the sequence number; if this doesn't work, I'll have to give up and make the check by hand as in your snippet. – MdMazzotti May 30 '14 at 8:52
1

Just to expound on what was being discussed about properties.Cancel not being set, here is some output from JustDecompile from the version 14 Microsoft.SharePoint.dll:

public virtual void ItemDeleting(SPItemEventProperties properties)
{
    this.BaseItemEventReceiver(properties);
}

private void BaseItemEventReceiver(SPItemEventProperties properties)
{
    if (properties != null)
    {
        properties.Status = SPEventReceiverStatus.Continue;
        return;
    }
    else
    {
        throw new ArgumentNullException("properties");
    }
}

So this is all that is being called by the base implementation of ItemDeleting (which is inline with the discussion that fell out of my question: Is Calling base.ItemUpdating(properties); necessary?). The base code never sets properties.Cancel or any value other than properties.Status = SPEventReceiverStatus.Continue.

It looks like doubling out the permission validation in your event receiver (as suggested by Robert Lindgren) may be the only way to handle this problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.