Как изменить "Модифицированный By" при использовании RunWithElevatedPrivileges?

У нас есть веб-часть, которая загружает документ в библиотеку документов. Пользователь, загружающий документ, может не иметь доступа к месту назначения, поэтому код, добавляющий файл, выполняется в блоке RunWithElevatedPrivileges. Это означает, что для поля "Изменено" всегда задано значение "Системная учетная запись". Вот код:

SPSecurity.RunWithElevatedPrivileges(
    delegate
    {
        using (SPSite elevatedSite = new SPSite(SPContext.Current.Site.Url))
        using (SPWeb targetWeb = elevatedSite.OpenWeb(webUrl))
        {
            targetWeb.AllowUnsafeUpdates = true;
            SPFile newFile = files.Add(filename, file);
            SPListItem item = newFile.Item;

            // TODO: Insert code to set Modified By

            item.SystemUpdate();
        }
    }
}

В поле "Изменено" должно быть указано имя текущего пользователя (на линии TODO выше), но ни одна из следующих попыток не сработала:

item["Modified By"] = SPContext.Current.Web.CurrentUser;

item["Author"] = SPContext.Current.Web.CurrentUser;

item["Modified By"] = new SPFieldUserValue(
SPContext.Current.Web, SPContext.Current.Web.CurrentUser.ID,
SPContext.Current.Web.CurrentUser.Name);

item["Author"] = new SPFieldUserValue(
SPContext.Current.Web, SPContext.Current.Web.CurrentUser.ID,
SPContext.Current.Web.CurrentUser.Name);

Кто-нибудь знает о решении, которое позволяет изменить значение "Изменено" ?

Ответы

Ответ 1

Я сделал еще несколько тестов...

item["Editor"] = SPContext.Current.Web.CurrentUser;
item["Author"] = SPContext.Current.Web.CurrentUser;
item.SystemUpdate();

Created By установлен для текущего пользователя, но для параметра Modified By установлено значение System Account.

item["Editor"] = SPContext.Current.Web.CurrentUser;
item["Author"] = SPContext.Current.Web.CurrentUser;
item.Update();

Оба Created By и Modified By установлены на текущего пользователя.

Проблема заключалась в использовании SPListItem.SystemUpdate(), который делает точную противоположность тому, что указано в документации API, по крайней мере, при работе с повышенными привилегиями.

Примечание.. SPContext.Current.Web.CurrentUser выполняет поиск текущего пользователя, а не системной учетной записи при работе в SPSecurity.RunWithElevatedPrivileges. (Следует ли его использовать таким образом, это еще один вопрос.)

Ответ 2

Один из способов решения этой проблемы - сохранить в настоящий момент зарегистрированного пользователя в памяти до. Позже в запросе на обновление замените "Системную учетную запись" на свою переменную.

См. ниже:

// Keep a reference of the Logged in user in memory
SPUser currentUser = SPContext.Current.Web.CurrentUser;

SPSecurity.RunWithElevatedPrivileges(
delegate
{
    using (SPSite elevatedSite = new SPSite(SPContext.Current.Site.Url))
    using (SPWeb targetWeb = elevatedSite.OpenWeb(webUrl))
    {
        targetWeb.AllowUnsafeUpdates = true;
        SPFile newFile = files.Add(filename, file);
        SPListItem item = newFile.Item;

        // Replace 'System Account' with current user
        item["Author"] = currentUser;
        item["Modified By"] = currentUser;

        item.SystemUpdate();
    }
});

Надеюсь, это поможет.

Ответ 3

Сделайте так (Henrique Zacchi), но создайте метод расширения оболочки, который принимает SPUser в качестве дополнительного параметра. Затем используйте его.

Ответ 4

RunWithElevatedPrivileges всегда создает новый поток внутри текущего потока с идентификатором AppPool. Таким образом, внутри этого делегата контекст относится к системной учетной записи.

Ответ 6

Вы пробовали это вместо SPSecurity.RunWithElevatedPrivileges?

using (WindowsImpersonationContext w = WindowsIdentity.Impersonate(IntPtr.Zero)) 
{
     //Do stuff here
}