Sunday, June 3, 2007

Profile Properties Webpart

There is something innately wrong with working on weekends. When I started working with MOSS back in July, I was fearful that perhaps it would not catch on. I don't feel that way anymore....

I do not have a whole lot of time to post, but I feel compelled to share the knowledge. My current consulting project has over exposed me to all the workings of people and profiles. At the height of the design, we were importing from three sources.

Other developers and users often ask me about the data we store for each user, and how they can view this information. Since I am not partial to giving out the server settings password, I created a small webpart that can be placed on a page and set to a user's id to display that user's information.



using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace ProfileProperties
{
[Guid("1fe9ec91-b377-4421-bc00-7cbc39ce3061")]
public class ProfileProperties : System.Web.UI.WebControls.WebParts.WebPart
{
PeopleEditor editor = null;
private Dictionary _userProperties = new Dictionary(50);
private string _user_account_info = string.Empty;
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true),
WebDisplayName("Account Info"),
WebDescription("The account of the profile to return.")]
public string AccountInfo
{
get { return _user_account_info; }
set { _user_account_info = value; }
}
public ProfileProperties()
{
this.ExportMode = WebPartExportMode.All;
}
internal void GetUserProfileProperties() {
try
{
Queue profileFlds = GetPropertyFieldList();
UserProfileManager mgr = new UserProfileManager();
UserProfile profile = mgr.GetUserProfile(_user_account_info);
foreach (string fld in profileFlds)
{
try
{
_userProperties.Add(fld, profile[fld].Value.ToString());
}
catch
{
continue;//lame I know, but its only an example
}
}
}
catch {}
}
internal Queue GetPropertyFieldList() {
Queue profileFlds = new Queue(50);
using (SPSite site = SPContext.Current.Site)
{
try
{
ServerContext context = ServerContext.GetContext(site);
UserProfileConfigManager configManager = new UserProfileConfigManager(ServerContext.Current);
Microsoft.Office.Server.UserProfiles.PropertyCollection propColl = configManager.GetProperties();
foreach (Property property in propColl)
{
profileFlds.Enqueue(property.Name);
}
return profileFlds;
}
catch
{
return null;
}
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (!string.IsNullOrEmpty(_user_account_info))
{
SPSecurity.CodeToRunElevated mf = new SPSecurity.CodeToRunElevated(GetUserProfileProperties);
SPSecurity.RunWithElevatedPrivileges(mf);
}
}
protected override void RenderContents(HtmlTextWriter writer)
{
int x = 0;
foreach (KeyValuePair prop in _userProperties) {
writer.Write(string.Format(@"{0}. {1} = {2}",++x, prop.Key,prop.Value));
}
editor.RenderControl(writer);
}
}
}



The code also utilizes the elevated privilages property for webparts that is new to MOSS.
This allows the webpart to go to the profile manager and get the field list before finding the specified profile and displaying the values.

2 comments:

Stephen E.S. said...

Just a note:

private Dictionary _userProperties = new Dictionary(50);

Doesn't seem to work anymore, throwing the following:

Using the generic type 'System.Collections.Generic.Dictionary TKey,TValue' requires '2' types of arguments.

Unknown said...

editor.RenderControl(writer) is not behaving as I would expect. I am not seeing the control unless I explicitly add it to the controls collection earlier in the page lifecycle.

Has something changed since you wrote this post that would prevent it form now working, or have I missed something?