Friday 8 July 2011

Redirecting userdisp.aspx to custom User Profile Page

Case
Because we are building a custom User Profile Page to display custom properties, we wanted to redirect the /_layouts/userdisp.aspx request to our custom LayoutsPage. This request is the default request of SharePoint to the built-in Profile Page.

Problem
The /_layouts/groups.aspx displays all groups in a collection. When you click on the groupname to display all members, it sends you to the /_layouts/userdisp.aspx which will redirect you to the correct /_layouts/people.aspx?MembershipGroupId.

Our /_layouts/userdisp.aspx should do the same, but how does SharePoint determine when it needs to show a group or user?

Solution
The solution could be found in the Microsoft.SharePoint.ApplicationPages.dll and original userdisp.aspx file.

In your SharePoint solution create a new application page. Make sure it's mapped to the /_layouts/ folder.

In your .aspx file
Add this control to the ContentPlaceHolder 'PlaceHolderMain':

[SharePoint:FormComponent id="UserListForm" TemplateName="UserListForm" ControlMode="Display" runat="server"/] (replace [ to make it a tag ;-)

In your .cs file
Add the following code to Page_Load:

int result = 0;
string url = "User/UserProfile.aspx?" + base.Request.QueryString.ToString();

if (base.Request.QueryString["ID"] != null)
{
if (!int.TryParse(base.Request.QueryString["ID"], out result) || (result <= 0))
{
throw new SPException(SPResource.GetString("InvalidQueryString", new object[] { "ID" }));
}
}
else
{
result = base.Web.CurrentUser.ID;

if (result <= 0)
{
throw new SPException(SPResource.GetString("InvalidQueryString", new object[] { "ID" }));
}

this.UserListForm.ItemId = result;
}

this.UserListForm.ListId = base.Web.SiteUserInfoList.ID;

SPListItem listItem = this.UserListForm.ListItem;
SPContentTypeId id = (SPContentTypeId)listItem["ContentTypeId"];

if (SPBuiltInContentTypeId.SharePointGroup.IsParentOf(id))
{
url = "people.aspx?MembershipGroupId=" + listItem.ID.ToString(CultureInfo.InvariantCulture);
string keyOrValueToEncode = base.Request.QueryString["Source"];

if (keyOrValueToEncode != null)
{
url = url + "&Source=" + SPHttpUtility.UrlKeyValueEncode(keyOrValueToEncode);
}
}

SPUtility.Redirect(url, SPRedirectFlags.RelativeToLayoutsPage, this.Context);

}

This should do the trick!