更新用户配置文件会在sharepoint 2010中引发PropertyNotEditableException

时间:2012-03-06 15:06:45

标签: c# sharepoint-2010 active-directory

我正在尝试更新sharepoint 2010用户个人资料,并且我一直收到此错误:

Microsoft.Office.Server.UserProfiles.PropertyNotEditableException: Property Not
Editable: This property can only be modified by an administrator. 
at Microsoft.Office.Server.UserProfiles.UserProfileValueCollection.
CheckUpdatePermissions()

我首先使用单独的代码块更新AD(可行)。我们正在使用配置文件同步服务,因此值最终会向下传播,但我们希望同时更新SP配置文件以立即显示更改。

代码:

using (System.Web.Hosting.HostingEnvironment.Impersonate())
{
  SPSecurity.RunWithElevatedPrivileges(delegate()
  {
    Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
    using (var site = new SPSite(SPContext.Current.Site.ID))
    {
        try
        {
            SPServiceContext sc = SPServiceContext.GetContext(site);
            UserProfileManager userProfileMangager = new UserProfileManager(sc);
            SPUser user = site.RootWeb.EnsureUser(loginName);
            UserProfile profile = userProfileMangager.GetUserProfile(loginName);
                try
                {
                    profile["WorkEmail"].Value = tbEmail.Text;
                    profile["WorkPhone"].Value = tbPhone.Text;
                    profile["company"].Value = tbCompany.Text;
                    profile.Commit();
                }
                catch (Exception ex)
                {
                    lblMesssage.Text = ex.ToString() + "<br/>";
                    lblMesssage.Visible = true;
                }
        }
        catch (Exception ex)
        {
            lblMesssage.Text = ex.ToString();
            lblMesssage.Visible = true;
        }
  }
});
panComplete.Visible = true;
panForm.Visible = false;
waiting.Visible = false;
litSuccess.Visible = true;
}
当我四处搜寻并尝试不同的东西时,其中有几件事情在那里。建议?

5 个答案:

答案 0 :(得分:2)

此异常的问题不是您的代码。这是你想要改变的领域的腐败设置。 请查看以下post,因为这个描述了解决方案以及您必须在字段设置上更改的内容。

http://msscorner.de/en/2011/10/18/userprofile-manager-eigenschaft-kann-nicht-bearbeitet-werden-diese-eigenschaft-kann-nur-von-einem-administrator-geandert-werden/

我希望它有所帮助

答案 1 :(得分:0)

你到底有没有做到这一点?根据我的经验,模拟对用户个人资料服务不起作用。它倾向于使用HttpContext.Current.User.Identity代替System.Security.Principal.WindowsIdentity.GetCurrent()。尝试将HttpContext.Current设置为null并查看会发生什么。

还要记住,当前身份必须具有托管用户配置文件权限。

答案 2 :(得分:0)

此时我们正在做的是写入隐藏的SP用户个人资料列表以欺骗它,直到AD同步发生。这不是最好的答案,但它是迄今为止我发现的唯一答案。如果有人来,我会很乐意接受更好的答案。

SPSecurity.RunWithElevatedPrivileges(() =>
                     {
                         using (var site = new SPSite(CurrentWeb.Site.Url))
                         {
                             using (var web = site.OpenWeb(CurrentWeb.ID))
                             {
                                 web.AllowUnsafeUpdates = true;
                                 SPList userInfo = web.Site.RootWeb.Lists["User Information List"];
                                 SPListItem userItem = userInfo.Items.GetItemById(_SelectedUser.ID);
                                 userItem["Work phone"] = tbPhone.Text;
                                 userItem["Work e-mail"] = tbEmail.Text;
                                 userItem["company"] = tbCompany.Text;
                                 userItem.Update();
                             }
                         }
                     });

答案 3 :(得分:0)

执行以下步骤,这些将解决问题:

1)从services.msc重新启动 Sharepoint Administration 服务和 Sharepoint计时器服务
2)使用powershell来停止和启动用户配置文件服务 3)在所有Web前端服务器和应用服务器上执行 IISRESET 4)现在清理浏览器缓存并访问URL。

答案 4 :(得分:0)

无论是谁还想弄清楚,我都会找到一个解决方案,感谢this博客。

简而言之:

您必须运行更新提升,并且必须将HttpContext.Current设置为null。我个人的猜测是,如果设置了上下文,它就是SharePoint中的一个错误。

代码段:

SPSecurity.RunWithElevatedPrivileges(() =>
{
    HttpContext httpContext = HttpContext.Current;
    try
    {
        SPServiceContext serviceContext = SPServiceContext.GetContext(httpContext);
        HttpContext.Current = null; // Hack !!!
        UserProfileManager upm = new UserProfileManager(serviceContext);
        //.. update your property which has "IsAdminEditable" set to true and "IsUserEditable" set to false
    }
    finally
    {
        //restore old context
        HttpContext.Current = httpContext;
    }
}