Question

I have a document library that should replace the Name column with the value from an Employee column.

Code:

public override void ItemUpdated(SPItemEventProperties properties)
{
    base.ItemUpdated(properties);
    try
    {
        SPListItem item = properties.ListItem;
        SPFieldUser employee = item.Fields.GetField("Employee") as SPFieldUser;
        SPFieldUserValue current = employee.GetFieldValue(item["Employee"].ToString()) as SPFieldUserValue;
        if (!item.Name.StartsWith(item.DisplayName))
        {
            item["Name"] = current.User.Name.Replace(", ", "_");
            item["Letter"] = current.User.Name.Substring(0, 1);
        }
        item.Update();
    }
    catch(SPException error)
    {
        throw new SPException(error.Message);
    }
}

The when a new document is uploaded and the Employee field is entered, the Name field is correctly set. However, if you go back and edit the item the Name field doesn't change.

Why would this code only work on creation and not update? Better yet, what is missing to get the code to work on both creation and edit?

Was it helpful?

Solution

Some remarks that may help:

  1. You may have an endless loop since the call to .Update triggers itself a new update and then the Event Receiver... You may not notice it immediately since SharePoint 2013 has now a protection that stops the re-entrance after 10 occurrences... Simply add EventFiringEnabled = false; at the begin of your ItemUpdated method and then EventFiringEnabled = true; in a finally block at the end.

  2. AllowUnsafeUpdates is most probably not needed here since you work on the contextual SPWeb object (i.e. you did not create it explicitely), issued from a POST request. In this case, you don't have to bother with AllowUnsafeUpdates.

  3. The column 'Name' is the standard Text field from a document Library, right?

  4. You should add some null checks, for instance item["Employee"] may be null and raise an exception with item["Employee"].ToString().

  5. I don't understand your if (!item.Name.StartsWith(item.DisplayName))... What's the point?

  6. To progress on this problem, you definitely need to attach the Visual Studio debugger to w3wp while running the test. This will allow you to ensure:

    • The event receiver is called on an properties update (I guess it is, according to your description)
    • Where it fails, and what's the error message.

OTHER TIPS

Few changes here...Add the DisabledEvents class and allow unsafe updates. Also if you set the properties.ErrorMessage, it will show in the UI if there is an issue.

public override void ItemUpdated(SPItemEventProperties properties)
{
    base.ItemUpdated(properties);
    try
    {
        using (DisabledEventsScope scope = new DisabledEventsScope())
        {
            SPListItem item = properties.ListItem;
            SPFieldUser employee = item.Fields.GetField("Employee") as SPFieldUser;
            SPFieldUserValue current = employee.GetFieldValue(item["Employee"].ToString()) as SPFieldUserValue;
            if (!item.Name.StartsWith(item.DisplayName))
            {
                item["Name"] = current.User;
                item["Letter"] = current.User.Name.Substring(0, 1);
            }
            item.Web.AllowUnsafeUpdates = true;
            item.Update();
            item.Web.AllowUnsafeUpdates = false;
        }
    }
    catch(Exception error)
    {
        properties.ErrorMessage = error.Message;
    }
}


class DisabledEventsScope : SPItemEventReceiver, IDisposable
{
    // Boolean to hold the original value of the EventFiringEnabled property 
    bool _originalValue;

    public DisabledEventsScope()
    {
        // Save off the original value of EventFiringEnabled 
        _originalValue = base.EventFiringEnabled;

        // Set EventFiringEnabled to false to disable it 
        base.EventFiringEnabled = false;
    }

    public void Dispose()
    {
        // Set EventFiringEnabled back to its original value 
        base.EventFiringEnabled = _originalValue;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top