Getting values of internal properties in SharePoint 2007


SharePoint has a lot of gold under the hood. Unfortunately for us – developers not all of it is publicly available. Some methods/properties are marked as internal what makes it impossible for us to use is custom functionality we’re developing. But do you really develop your own alternatives or is there a way to get to those gems after all?

GroupedItemPicker – almost unusable?

Grouped Item Picker SharePoint control

One of the examples of the situation I’ve described above is the GroupedItemPicker- a list control which allows the end users to select multiple items. Comparing to the standard list box the GroupedItemPicker provides a richer experience and makes selecting multiple items way easier.

By default a multiple lookup field stores the selected items as ID1;#Title1;#ID2;Title2 string. Unfortunately, there is a problem when querying the content of a MultiLookup field. At the end of the day, you might to create an alternative field type which would correctly support selecting multiple values and making the value available to a query.

No matter how you would solve the plumbing the odds are high that you would query the value as text which would resemble the standard MultiLookup value (ID1;#Title1;#ID2Title2). There is one problem however…

I assume you would use GroupedItemPicker to provide the same great experience as the standard MultiLookup SharePoint field. The problem is that GroupedItemPicker provides you access to the selected ID’s (GroupedItemPicker.SelectedIds) only. The selected text (GroupedItemPicker.SelectedTokens) is accessible internally only! Does it mean that you must create your own control which would work exactly the same as the GroupedItemPicker? Luckily not!

Reflecting the GroupedItemPicker

It turns out that you can still get to the values of internal properties using reflection. And the best of it all: it’s not even that complicated! Take a look at the following method I’ve made which simplifies getting type safe value of any property:

public static bool TryGetPropertyValue<TValue>(object o, string propertyName, out TValue value)
{
  bool succes = false;
  value = default(TValue);
  foreach (PropertyInfo pi in o.GetType().GetProperties(BindingFlags.Default | BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static))
  {
    if (pi.Name.Equals(propertyName) && pi.CanRead)
    {
      object rawValue = pi.GetValue(o, null);
      if (rawValue is TValue)
      {
        value = (TValue)rawValue;
        succes = true;
      }
    }
  }
  return succes;
}

Now if you want to retrieve the value of a non-public property you can do it like this:

InternalClass ic = new InternalClass();
int value = 0;
if (TryGetPropertyValue<int>(ic, "InternalProperty", out value))
{
    // do something
}

As far as I’m concerned it’s a lot less development than creating a fully functional control similar to GroupedItemPicker.

GroupedItemPicker is not the only gem stored in SharePoint. There is a lot more of them. Having the TryGetPropertyValue in your utils can enable to benefit even more of the SharePoint framework.

Technorati Tags: SharePoint, SharePoint 2007, WSS 3.0, MOSS 2007, .NET, Reflection

Others found also helpful: