Write customer webpart and application pages to change SharePoint out of box behaviors are very common. However, these changes will ask users to use the customized UI (webparts or application pages) instead of out of box UI. There are some cases users want to change some SharePoint behavior globally without changing SharePoint UI. One example is for our SharePoint 2010 extranet implementation, security team asked us to restrict people picker to display users ONLY belongs to the site collection instead of whole farm for external users login from form based authentication. However, the same people picker needs to display all users in the whole farm for internal users login from Kerberos authentication. This requirement drives us to override SharePoint People Picker logic using tag mapping design.
The tag mapping functionality is a mechanism to instruct the parser to substitute a different derived type implementation whenever it encounters the type being mapped. It was originally invented as part of the WebPart framework so as to allow the ASP.NET WebPartManager to be mapped to the derived Sharepoint WebPartManager implementation without having to change individual pages. However, it is quite powerful and generally applicable.
Here are major steps how to implement this without changing SharePoint UI.
1. Identify the control out of box used for People Picker using browser tools to view source
2. Create a new class deriving Microsoft.SharePoint.WebControls.PeopleEditor identified in #1
3. Overwrite the functions inside class #2 to display only people inside the site collection for external users
4. Sign the assembly with a Strong Name and install assembly into the GAC using feature
5. Configure tag mapping entry in the Web.Config for the targeted webapp
public class QCPeopleEditor : Microsoft.SharePoint.WebControls.PeopleEditor
{
protected override void OnLoad(System.EventArgs e)
{
base.OnLoad(e);
// Determine which claims authentication type was used to log in
SPClaimProviderManager mgr = SPClaimProviderManager.Local;
if (mgr != null)
{
SPClaim userLogonNameClaim = mgr.DecodeClaim(SPContext.Current.Web.CurrentUser.LoginName);
SPOriginalIssuerType issuerType = SPOriginalIssuers.GetIssuerType(userLogonNameClaim.OriginalIssuer);
// If user used FBA then switch people picker to only show users already in the site
if (issuerType == SPOriginalIssuerType.Forms)
{
this.PrincipalSource = Microsoft.SharePoint.Utilities.SPPrincipalSource.UserInfoList;
}
}
}
}
<add tagType="Microsoft.SharePoint.WebControls.PeopleEditor" mappedTagType="qualcomm.com.sp.peoplepicker.QCPeopleEditor" />
· Assert Picker
· People Picker
· Time Picker
· List Picker
There are several classes you may identify that need to be modified. Two of them are:
Class Microsoft.SharePoint.Portal.WebControls.SpListFilterValuesPickerUI function protected override void PopulateListItems()
Class Microsoft.SharePoint.WebControls.EntityEditorWithPicker function protected override int IssueQuery(string searchString, string filterName, int pageIndex, int pageSize)
SpListFilterValuesPickerUI is a sealed class and it will invoke other functions that are also sealed that would be very difficult to change them all. EntityEditorWithPicker will aslo call some utility class that are sealed and it is difficult to get the required dll or reference to compile the overwritten classes. Here are two examples of sealed class or functions.
internal sealed class SpListFilterValuesPickerUI : ListFilterValuesPickerUIBase<SpListFilterValuesPickerContext>
BdcClientUtil.GetEntity(BdcClientUtil.MetadataCatalog, pickerDialog.EntityNamespace, pickerDialog.EntityName);
As a result, change SharePoint 2010 behavior without change out of box UI using tag mapping is very useful but it may not be possible for all circumstances.
No comments:
Post a Comment