Вопрос

У меня есть библиотека документов, которая должна заменить столбец Name значением из столбца Employee.

Код:

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);
    }
}

При загрузке нового документа и вводе поля Employee поле Name установлено правильно.Однако, если вы вернетесь и отредактируете элемент, поле Name не изменится.

Почему этот код будет работать только при создании, а не при обновлении?А еще лучше, чего не хватает, чтобы заставить код работать как при создании, так и при редактировании?

Это было полезно?

Решение

Некоторые замечания, которые могут помочь:

  1. У вас может быть бесконечный цикл, так как вызов .Update запускает новое обновление, а затем приемник событий... Вы можете не заметить этого сразу, поскольку в SharePoint 2013 теперь есть защита, которая останавливает повторный вход после 10 вхождений... Просто добавьте EventFiringEnabled = false; в начале вашего метода ItemUpdated, а затем EventFiringEnabled = true; в блоке finally в конце.

  2. AllowUnsafeUpdates, скорее всего, здесь не нужен, так как вы работаете с контекстным объектом SPWeb (т.е. вы не создавали его явно), полученным из POST-запроса.В этом случае вам не нужно заморачиваться с AllowUnsafeUpdates.

  3. Столбец «Имя» — это стандартное текстовое поле из библиотеки документов, верно?

  4. Вы должны добавить некоторые проверки null, например, item["Employee"] может быть нулевым и вызвать исключение с item["Employee"].ToString().

  5. Я не понимаю вашего if (!item.Name.StartsWith(item.DisplayName))... Какой смысл?

  6. Чтобы решить эту проблему, вам обязательно нужно подключить отладчик Visual Studio к w3wp во время выполнения теста.Это позволит вам обеспечить: Приемник событий вызывается при обновлении свойств (наверное, по вашему описанию) Где это не удается, и какое сообщение об ошибке.

Другие советы

Здесь немного изменений... Добавьте класс DisabledEvents и разрешите небезопасные обновления.Также, если вы установите properties.ErrorMessage, оно будет отображаться в пользовательском интерфейсе, если есть проблема.

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;
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с sharepoint.stackexchange
scroll top