Use the Power of Reflection to Dynamically Set SharePoint Web Part Properties

harePoint’s User Defined Site Template helps empower your end users to take control of their own user interface design, pushing much of the user interface design responsibility away from traditional developers.

Once your users are done tweaking the look and feel of a given interface, they can save the design as a template. The templates are stored in the Site Template Collection list, located at the root site of the current site collection. For example, if your site URL is http://server/sites/rootsite/site1/site2 and you save it as a template, the template will be located in the http://server/sites/rootsite Site Template Collection.

Figure 1. The Site Creation Wizard: The image shows template availability during site creation.

These templates are available during a site’s creation process, from any level within the site collection tree (the root site and all its sub-sites). Figure 1 shows the template’s availability during the site creation wizard. Your users now have the ability to replicate their site many times over, all without needing any assistance from you.

However, because all their properties are set at design time, creating sites based on these saved site templates results in static content. This can become a problem in today’s business environment, which demands dynamic site content.

Enter Reflection
.NET brought with it a set of tools neatly grouped into the System.Reflection namespace, which solves this problem. Reflection allows you to query information from any assembly?even the same assembly?dynamically. Information such as properties, fields, and methods, which were declared as public in the assembly, can be reflected. In addition, reflection allows you to retrieve the values of these properties and/or fields as well as set those values dynamically. Reflection also allows you to dynamically invoke methods of the assembly at run time and dynamically compile the code. With it, you can dynamically set a template’s Web part properties, thus rendering a static site dynamic.

Why Modify Web Part Properties at Run Time?
One of the most common issues that enterprise developers and consultants face when they start the customization of their SharePoint Technologies environments is the customization of Web parts. Though it is possible to set your Web parts properties design time, in order for your content to be dynamic, you’ll need to set and/or change some properties at run time.

The Page Viewer Web part is a commonly used component allowing you to unify information dispersed across multiple systems in one central location in the form of a portal site. Though the Web part forms part of the SharePoint page, its content is not rendered from the server. Instead, the client interprets the “Link” property of the Page Viewer Web part and requests the content, subsequently displaying it in the Web part. This helps with single sign-on situations where the user’s credentials will automatically provide the desired information.

A common problem with the Page Viewer Web part is that its content source is static?the URL provided in the “Link” property is set at design time and does not change. If a user want to target another URL value, they’ll need to manually modify Page Viewer’s properties. Having end users perform this activity is not realistic, so you’ll want to find other ways for the system to manage and change these properties automatically.

Locating the Target Web Part
To dynamically change the “Link” property of the Page Viewer Web part, you’ll need two important pieces of information. The first is the URL of the site on which the Page Viewer Web part resides and the second is the URL value to which you wish to set the “Link” property.

Enable the use of reflection in your application by including it with a using statement. Use the SPSite object to obtain a reference to the site on which the Page Viewer Web part, residing in the form of a SPWeb object. The SPSite class represents a root site collection on a virtual server, i.e. the top-level site and all its sub-sites. Obtain a reference to the root site collection with the SPSite object:

using System.Reflection;SPSite spsSite = new SPSite("http://server/sites/web/default.aspx");

Once you’ve obtained the SPSite object reference, use it to obtain a reference to the SPWeb object using the OpenWeb() method. If your code is running from a command context, as in the example code, the next statement is not required. However, if your code is running in a Web part context?as a tool on a Windows SharePoint Services site, say, then you have to set the AllowUnsafeUpdates property to true in order for your changes to register.

SPWeb spwWeb = spsSite.OpenWeb();spwWeb.AllowUnsafeUpdates = true;

Once you have obtained the reference to the SPWeb object, you’ll use SPWeb‘s GetWebPartCollection() method to to obtain an instance of the SPWebPartCollection object (which contains all the Web parts on the site):

SPWebPartCollection wpcWebParts =  spwWeb.GetWebPartCollection("http://server/sites/web/default.aspx",  Storage.Shared);

GetWebPartCollection()‘s first parameter specifies the URL of the current Web you’re working on. Its second parameter specifies the view you’ll have of the site from which you’re retrieving the Web part list. Finally, the Storage.Shared value returns the list of Web parts which are visible to all users.

Before you can modify your collection of Web parts, you need to identify your Page Viewer Web part. A simple foreach loop iterates the collection, returning a reference to any Web parts in the collection. Simply check each Web part to find the relevant one.

Use reflection along with the GetType() method to check the type of Web part from within the loop. Using Intellisense in Visual Studio, explore the Microsoft.SharePoint.WebPartPages namespace to locate the class names of each of the standard Web parts in SharePoint. This is how you determine that the class name for the Page Viewer Web part is:

Microsoft.SharePoint.WebPartPages.PageViewerWebPart

This article’s example uses a direct compare for this value in order to avoid addressing the class name topic until this part of the code. However, in real world projects, you would probably want to define the value as a constant in your code.

The currently referenced Web part in your iteration has the power to reflect on itself. The System.Reflection reference provides it with the GetType() method to return the object type. Casting the returned value, which the ToString()method returns in System.Type format to a string, you can make a direct comparison to the target Web part type string which uses the full namespace convention. Once you find your target Page Viewer Web part, you can change it.

foreach (WebPart wptWebPart in wpcWebParts){  if (wptWebPart.GetType().ToString() ==     ?Microsoft.SharePoint.WebPartPages.PageViewerWebPart?)  {    ...  }}

If you’ve got more than one Page Viewer Web part on the target page, you’ll need to employ additional property values in order to locate the exact right Page Viewer Web part you wish to modify. The Part Order could be used to help identify your target more clearly.

Making the Change
Before you can set your new values, you need to change the “Link” property of the Page Viewer Web part. To do this, you need to obtain the the “Link’s” array of properties. Using the reflection method GetProperties() returns an array of PropertyInfo objects, each of which contain property information related to the type being reflected upon. GetProperties() takes a bitwise enumerated value for flags that control binding. Reflection conducts the search for members and types. The code below uses values that specify for all public, non-public, and instance members to be included in the reflection search.

PropertyInfo[] pinProperties = wptWebPart.GetType().GetProperties(      BindingFlags.NonPublic | BindingFlags.Public |      BindingFlags.Instance);

After you obtain the array of properties for the Page Viewer Web part, you need to locate the target property. In the example of the Page Viewer Web part, the “Link” property in the user interface is stored in the “ContentLink” property in the property array. Using another foreach loop, iterate through the property array and check the property names until you locate the “ContentLink” property. Again, repeated usage of the property name would probably dictate it being stored in a constant in your code.

foreach (PropertyInfo pinProperty in pinProperties)    {      if (pinProperty.Name == ?ContentLink?)      {        ...      }    }

To set the value, pass a reference to the Page Viewer Web part object?as well as to the new URL value to whose property you wish to set the SetValue() method. Commit these changes with a call to the Web part collection’s SaveChanges() method.

        pinProperty.SetValue(wptWebPart,           ?http://MyNewURLValueHere?, null);        wpcWebParts.SaveChanges(wptWebPart.StorageKey);

Once this update has been made, terminate each foreach loop by issuing a break statement for each loop in turn.

using System.Reflection;SPSite spsSite = new SPSite(?http://server/sites/web/default.aspx?);SPWeb spwWeb = spsSite.OpenWeb();spwWeb.AllowUnsafeUpdates = true;SPWebPartCollection wpcWebParts =  spwWeb.GetWebPartCollection(?http://server/sites/web/default.aspx?,  Storage.Shared);foreach (WebPart wptWebPart in wpcWebParts){  if (wptWebPart.GetType().ToString() ==     ?Microsoft.SharePoint.WebPartPages.PageViewerWebPart?)  {    foreach (PropertyInfo pinProperty in pinProperties)    {      if (pinProperty.Name == ?ContentLink?)      {        pinProperty[?ContentLink?].SetValue(wptWebPart,           ?http://MyNewURLValueHere?, null);        wpcWebParts.SaveChanges(wptWebPart.StorageKey);        break;      }    }    break;  }}

Reflection Allows for Flexibility
Reflection helps you dynamically update Web part properties so you can provide relevant site content. Using it, you can:

  1. Locate and identify your target Web part.
  2. Inspect its properties.
  3. Update those properties.

All this gives you the felixibility to dynamically respond to any changes in your SharePoint Technologies environments.

The accompanying download contains the project source code for a command line utility that modifies the Page Viewer Web part property on any specified site. Note that the project file has set default command line switches. You’ll need to modify these if you intend to run the project in debug mode from Visual Studio. If you compile the application and run the .exe from the command line, standard parameter parsing rules apply.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

More From DevX