C# 更新用户配置文件在sharepoint 2010中引发PropertyNoteTableException

C# 更新用户配置文件在sharepoint 2010中引发PropertyNoteTableException,c#,sharepoint-2010,active-directory,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.UserProfileValueCollect

我正在尝试更新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()
我首先用一个单独的代码块更新广告(这是可行的)。我们正在使用配置文件同步服务,因此该值最终会向下传播,但我们希望同时更新SP配置文件以立即显示更改

代码:

使用(System.Web.Hosting.HostingEnvironment.Impersonate())
{
SPSecurity.runWithLevelatedPrivileges(委托()
{
Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
使用(var site=newspsite(SPContext.Current.site.ID))
{
尝试
{
SPServiceContext sc=SPServiceContext.GetContext(站点);
UserProfileManager UserProfileManager=新的UserProfileManager(sc);
SPUser user=site.RootWeb.EnsureUser(loginName);
UserProfile profile=userprofilemanager.GetUserProfile(loginName);
尝试
{
profile[“WorkEmail”].Value=tbEmail.Text;
profile[“WorkPhone”].Value=tbPhone.Text;
profile[“company”].Value=tbCompany.Text;
profile.Commit();
}
捕获(例外情况除外)
{
lblmessage.Text=ex.ToString()+“
”; lblMesssage.Visible=true; } } 捕获(例外情况除外) { lblmessage.Text=ex.ToString(); lblMesssage.Visible=true; } } }); panComplete.Visible=true; panForm.Visible=false; 等待。可见=假; litSuccess.Visible=true; }

当我四处搜索并尝试不同的东西时,其中的一些东西就在那里。建议?

你最终有没有找到工作?根据我的经验,模拟在用户配置文件服务中不太好用。它倾向于使用
HttpContext.Current.User.Identity
而不是
System.Security.Principal.WindowsIdentity.GetCurrent()
。尝试将HttpContext.Current设置为null,并查看发生了什么


还请记住,当前标识必须具有托管用户配置文件权限。

此时我们要做的是写入隐藏的SP用户配置文件列表以欺骗它,直到广告同步发生。这并不是最好的答案,但这是迄今为止我找到的唯一答案。如果有人来的话,我很乐意接受一个更好的答案

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

此异常的问题不是您的代码。您要更改的字段设置已损坏。 请看以下内容,因为这一部分描述了解决方案以及您必须在字段设置上更改的内容


我希望它有助于执行以下步骤,这些步骤将解决问题:

1) 从services重新启动Sharepoint管理服务和Sharepoint计时器服务。msc
2) 使用powershell停止和启动用户配置文件服务
3) 在所有web前端服务器和应用程序内服务器上执行IISRESET

4) 现在清理浏览器缓存并访问url。

无论是谁仍在努力解决这个问题,我都通过博客找到了解决方案

简言之:

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

代码段:

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

谢谢您的回答,但我尝试将httpcontext设置为null。我尝试过使用和不使用
模拟
。我已经验证了当时使用的帐户是服务器场管理员(dev环境)。此时,我们正在做的是写入隐藏的SP用户配置文件列表并欺骗它,直到广告同步发生:Pthanks。我在7个月前问过这个问题,我们已经从这个问题上走了。好像是我干的,但我想不起来了。
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;
    }
}