Using Reflection to List Properties and their Values
In the Properties dialog, we are going to list all properties of the selected object. Usually, when you want to access a property value in code, you simply type the object name, followed by the period key and then the property name.
This is fine when you are just dealing with one or two properties, but there are over 40 properties for the channel object alone. In order to display all its property values in this way, you would have to type in at least 40 lines of code. And should there be future upgrades to the PAPI, the list may grow even longer. The good news is there’s a short cut—.NET Reflection.
Reflection is a technique used to access information about a class, such as its methods, properties, events and even information about its assembly. To implement reflection, use the GetType()
method of the object (inherited from System.Object
), which returns an object of type System.Reflection.Type
. The System.Reflection.Type
class contains methods that retrieve metadata about the object’s class. For example, given any object, you can get a list of its methods by calling:
MyObject.GetType().GetMethods();
and to get a list of its properties, you could call:
MyObject.GetType().GetProperties();
As you can see, reflection is a powerful feature. In this example, instead of writing 40+ lines of code to list the properties of a ChannelItem
object, we will simply use reflection to iterate through each property and display its value.
Let’s display the list of properties in a DataGrid
. To start, add a new web form to the CMSExplorer project. Name the new web form Properties.aspx
. Toggle to HTML view
and add a couple of headings to the form to describe what it does:
<form> <h1>Properties of <asp:Literal Runat="server" ID="litCurrentItem"/></h1> <h2>List of all Properties and their values</h2></form>
In the web form’s code-behind file, import the Microsoft.ContentManagement.Publishing
and System.Reflection
namespaces and add the following code in the Page_Load()
event handler:
. . . code continues . . . // MCMS PAPI using Microsoft.ContentManagement.Publishing; // for reflection using System.Reflection; namespace CMSExplorer { /// <summary> /// Summary description for Properties. /// </summary> public class Properties : System.Web.UI.Page { HierarchyItem hItem; // the current item private void Page_Load(object sender, System.EventArgs e) { CmsHttpContext cmsContext = CmsHttpContext.Current; hItem = null; string cmsObjectGuid = ""; if (Request.QueryString["CMSObjectGuid"]!=null) { // template gallery items and resource gallery items cmsObjectGuid = Request.QueryString["CMSObjectGuid"]; hItem = cmsContext.Searches.GetByGuid(cmsObjectGuid); } else { // channels and postings hItem = cmsContext.ChannelItem; } // list all properties and their values in the grid if (hItem!=null) { litCurrentItem.Text = hItem.Path; ListProperties(); } } . . . code continues . . . } }
The code gets a reference to the HierarchyItem
whose properties you wish to view. For template galleries, templates, resource galleries, and resources, this is obtained by getting the GUID from the CMSObjectGuid
querystring parameter and using the Searches.GetByGuid()
method. Channels and postings are obtained from the CmsHttpContext.Current.ChannelItem
property.
In Design
view, drag and drop the Styles.css
file and DataGrid
onto the Properties.aspx
web form and give the DataGrid
the following property values:
Property |
Value |
---|---|
Auto Format |
Simple 3 |
Font-Size |
10pt |
ID |
DataGrid1 |
Below the Page_Load()
event handler, add the ListProperties()
method. The method first creates a DataTable
containing the following columns:
The property name
The property value
Whether or not the property can be written to
We use the GetType.GetProperties()
method to retrieve a collection of all properties associated with the hierarchy item. Next, iterate through each property of the current ChannelItem
and add each one as a row to the DataTable
. Notice that the property value is obtained by calling PropertyInfo.GetValue()
and passing in the hierarchy item as an input parameter. Finally, we bind the DataTable
to the DataGrid
.
private void ListProperties() { // display the property names and values for the current channelitem DataTable dt = new DataTable(); DataRow dr; // add columns for the property name, property value and // the boolean that indicates if the property is writable dt.Columns.Add(new DataColumn("PropertyName")); dt.Columns.Add(new DataColumn("PropertyValue")); dt.Columns.Add(new DataColumn("CanWrite")); // use reflection to iterate through a list of the object's properties foreach(PropertyInfo pi in hItem.GetType().GetProperties()) { if (pi.PropertyType.ToString().StartsWith("System")) { dr = dt.NewRow(); dr[0] = pi.Name; Object piObject = pi.GetValue(hItem, null); if (piObject!=null) { dr[1] = piObject.ToString(); } dr[2] = pi.CanWrite.ToString(); dt.Rows.Add(dr); } } // bind the datatable to the datagrid DataGrid1.DataSource = dt.DefaultView; DataGrid1.DataBind(); }
When you are done, save and build the solution. To see the code in action:
Access
http://localhost/CmsExplorer
.Click on the
Edit
button on the row corresponding to the Tropical Green channel.Click
Properties
.
The Properties page opens as shown on the facing page. Notice that all properties of the Tropical Green channel are displayed! The page also works when viewing the properties of other object types like template galleries and resource galleries.