UserProfile - Property Not Editable

今天接到一个需求,是需要在用户的个人信息里添加工号以便和另外一个系统接口(那个系统是用员工工号作为登录名),用户在登录的时候必须强制填写完工号信息才可以访问其他页面。

开始想的比较简单:

1.  在UserProfile里添加自定义的属性"EmployeeNo"

2.  在用户登陆时,先判定用户是否有工号,如果没有则跳到一个页面进行填写; 如果有则不做任何处理

3.  创建一个webpart,用于输入工号信息并更新UserProfile

 

第一步: 添加"EmployeeNo"属性:

              这一步比较简单,SSP --> "User Profile and Properties" --> "Add Profile Property". 里面有一些细节的设定,要根据实

              际需求去填充。

第二步:   判定用户是否有工号

             因为采用的是Windows验证,所以用户的入口链接是不固定的。 我现在会的方法就是在对应的Global.asax页面里重写相应的事

             件。

             因为需要在用户身份验证通过以后才能获取到用户的信息,所以开始选择了Application_PreRequestHandlerExecute:在将请

             求发送到服务于请求的处理程序对象之前触发。当事件触发后,页面将由HTTP处理程序处理请求。

             void Application_PreRequestHandlerExecute(object sender, EventArgs e) { using (HttpApplication httpApp = (HttpApplication)sender) { Verify(httpApp.Request.Url.AbsolutePath, httpApp.Context, httpApp); } } void Verify(string fileUrl, HttpContext content, HttpApplication httpApp) { if (!String.Equals(httpApp.Request.Url.AbsolutePath, "/Pages/EmployeeNumber.aspx", StringComparison.CurrentCultureIgnoreCase)) { Microsoft.SharePoint.SPWeb contextWeb = Microsoft.SharePoint.WebControls.SPControl.GetContextWeb(content); Microsoft.SharePoint.SPUser user = contextWeb.CurrentUser; if (user != null) { //bool isEmployeeNoExist = true; Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(delegate() { using (Microsoft.SharePoint.SPSite elevatedSite = new Microsoft.SharePoint.SPSite(contextWeb.Site.ID)) { using (Microsoft.SharePoint.SPWeb elevatedWeb = elevatedSite.OpenWeb(contextWeb.ID)) { Microsoft.Office.Server.ServerContext context = Microsoft.Office.Server.ServerContext.GetContext(elevatedSite); Microsoft.Office.Server.UserProfiles.UserProfileManager profileManager = new Microsoft.Office.Server.UserProfiles.UserProfileManager(context); string accountID = user.LoginName; Microsoft.Office.Server.UserProfiles.UserProfile newProfile = profileManager.GetUserProfile(accountID); if (newProfile["EmployeeNo"] == null || newProfile["EmployeeNo"].Value == null || newProfile["EmployeeNo"].Value.ToString() == "") { //isEmployeeNoExist = false; if (IsGroupMember(user, contextWeb, "Internal Members")) { contextWeb = null; httpApp.Response.Redirect("~/Pages/EmployeeNumber.aspx?link=" + httpApp.Server.UrlEncode(httpApp.Request.Url.AbsolutePath)); } else { contextWeb.AllowUnsafeUpdates = true; newProfile["EmployeeNo"].Value = "F0000000"; newProfile.Commit(); contextWeb.AllowUnsafeUpdates = false; contextWeb = null; } } } } }); } } } protected bool IsGroupMember(Microsoft.SharePoint.SPUser spUser, Microsoft.SharePoint.SPWeb spWeb, string operationGroup) { bool isMember = false; try { Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(delegate() { using (Microsoft.SharePoint.SPSite elevatedSite = new Microsoft.SharePoint.SPSite(spWeb.Site.ID)) { using (Microsoft.SharePoint.SPWeb elevatedWeb = elevatedSite.OpenWeb(spWeb.ID)) { Microsoft.SharePoint.SPGroup spGroupOperation = elevatedWeb.SiteGroups[operationGroup]; foreach (Microsoft.SharePoint.SPUser eachUser in spGroupOperation.Users) { if (eachUser.ID == spUser.ID) { isMember = true; break; } } } } }); return isMember; } catch { return isMember; } }

            

              因为用公司内外的用户以及匿名访问,所以添加了一些判定。

              结果执行的时候却发现了问题:

              1) 可以跳转到对应的页面,但是刷新以后发现页面的样式全部丢失

               对Global.asax里的HTTPApplication事件浏览了一下,看的有点晕头转向的,只知道是在身份验证之后,想了下,就选了

               Application_PostRequestHandlerExecute : 当HTTP处理程序与页面请求一起完成时触发。此时,Response对象将获得由客

               户端返回的数据。 (额,可能是不够严谨吧,后面会仔细研究下的)换成了这个事件以后就没有问题了。

第三步:  填入工号信息并更新"EmployeeNo"

              这里代码就很简单了,获取当前的用户的UserProfile,然后对"EmployeeNo"属性赋值,

               /// <summary> /// 2010-12-08 Rex Create Update Employee Number for current user /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnSave_Click(object sender, EventArgs e) { string queryString = this.Page.Request.QueryString.Get("link"); lblError.Text = ""; if (txtEmployeeNo.Text.Trim() == "" || txtEmployeeNo.Text.Trim().ToUpper() == "F0000000" || txtEmployeeNo.Text.Trim().Length > 15) { lblError.Text = "Please input a valid employee number!"; } else { SPWeb contextWeb = SPContext.Current.Web; SPUser user = contextWeb.CurrentUser; SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite elevatedSite = new SPSite(contextWeb.Site.ID)) { using (SPWeb elevatedWeb = elevatedSite.OpenWeb(contextWeb.ID)) { Microsoft.Office.Server.ServerContext context = Microsoft.Office.Server.ServerContext.GetContext(elevatedSite); UserProfileManager profileManager = new UserProfileManager(context); string accountID = user.LoginName; UserProfile newProfile = profileManager.GetUserProfile(accountID); newProfile["EmployeeNo"].Value = txtEmployeeNo.Text.Trim().ToUpper(); newProfile.Commit(); if (queryString != null && queryString != "") { this.Page.Response.Redirect("~" + queryString); } else { this.Page.Response.Redirect("~/"); } } } }); } }

           

                结果在执行的时候出错了,经过调试发现时在赋值的时候会报错:

                newProfile["EmployeeNo"].Value = txtEmployeeNo.Text.Trim

                错误信息: Property not editable

                1. 是否是因为属性没有设置正确: 把属性设置为可编辑,还是会报错。、

                2. 后来再调试发现还有一句 "You can only edit the property as an administrator",于是想到可能是权限的问题。

                    一般来说权限的问题用代码权限提升是屡试不爽的,结果这次碰壁了。

                   上网搜索,结果发现时因为没有管理userprofile的权限, 我发现代码权限提升后对应的账户是"SharePoint/System”,于是想

                   着把这个账号授予管理UserProfile的权限就可以了吧,结果发现无法添加。 后来的解法是对所有的用户进行授权:

                   SSP --> "Personalization services permissions" --> 为"NT AUTHORITY/Authenticated Users" 添加/授予 "Manage

                   UserProfile"的权限。

                设置完成后重启应用程序池, 再次执行,成功。

               

你可能感兴趣的:(UserProfile - Property Not Editable)