Property extender providers are widely used in the Windows Forms environment where this technology enjoys full support of the .NET Framework and Visual Studio IDE. Conversely ASP.NET developers do not always fully appreciate the benefits of the technique. This article demonstrates how to take advantage of the property extenders in ASP.NET custom control projects and suggests practical solutions to issues with design-time serialization and state management posed by ASP.NET 2.0 and Visual Studio 2005.
There is a common case of user interface requirements that calls for controls presented on a Web Form to expose a specific set of custom properties. For instance certain controls could disable themselves based on current user credentials or display some sort of interactive context-sensitive help. Most often web developers tend to realize such use cases by creating libraries of custom controls representing subclasses of original controls however employing a property extender provider could prove to be the more elegant and effective technique under a wide variety of circumstances.
Extender providers add new properties to other controls. Components or controls acting as property providers are responsible for the behavior of the provided properties.
The world of Windows Forms Visual Studio renders full support to property extenders including built-in CodeDom serialization thus making the implementation simple and straightforward. On the other hand, developers of custom web controls and components exposing extender providers were forced to custom-code their own serialization logic. In most cases this approach worked better with non-visual designable components as opposed to more common visual controls until Visual Studio 2005 eliminated components and CodeDom serialization from the developer’s arsenal altogether.
CodeProject has published a number of articles on this subject:
In this article, I would like to introduce in broad terms the concept of property extenders to the ASP.NET practitioners and share some ideas on how to address issues with serialization of provided properties specifically when working with ASP.NET 2.0 and Visual Studio 2005.
Anatomy of property extender
An extender provider component can provide properties to other components in a container. In a sense these other components are acting as clients of an extender provider. One well-known example is an
ErrorProvider component. When an
ErrorProvider control is added to a form all other controls have an
Error property added to their list of properties.
IExtenderProvider interface allows the design environment to query method
CanExtend to identify all the objects in a container capable of receiving the extender properties.
public bool CanExtend(object extendee)
return extendee is TextBox;
This class-level attribute defines the name of the property offered by a property extender to other components. The class marked by the attribute has to provide implementation of the property code in the form of
public class ValidatorControl
public TextValidator GetValidation(TextBox textBox)
As you can see property extender concept is fairly straightforward and permits a great degree of flexibility when adding new features to components in your project. We will cover specifics of building property extenders for ASP.NET applications next.
Property extenders in ASP.NET
To better illustrate this fairly complex topic all concepts and techniques are going to be discussed in the context of the sample project MutlifieldValidator (source is attached with this article). It has been developed in C# 2.0 with Visual Studio 2005 Beta 2. While coding I restrained from using generics and other new framework features not available in .NET 1.1 and Visual Studio 2003, therefore the project can be easily ported to that environment as well.
Multi-field validator overview
MutlifieldValidator solves the proverbial problem of validating text input with the somewhat ambitious aim of establishing a strong relevance to the practical development tasks in this purely theoretical exercise. This choice of problem domain also allows readers to easily compare this solution with the existing ‘out-of-the-box’ ASP.NET validator control in such areas as usability and functional simplicity.
The following requirements definitions are assumed to drive our preference in technology to property extenders:
- Each text box on a form should have an individually specified regular expression for validation and an error message that will be displayed when the regular expression is not matched by the user input.
- Standard validator controls are not a preferable option due to limited real estate in this application where the error message for all validated controls share a single label for display.
As directly inferred by our requirement the property extender control will have to provide two properties for each text box –
Expression. In the best traditions of good design practices instead of providing these properties individually we will encapsulate them into a class called
TextValidator. Since we also need a reference to the hosting property extender and an ID of a client control these items are reflected in the properties
Placing a proper type converter attribute on the class level
[TypeConverter(typeof(ExpandableObjectConverter))] will allow client text boxes to show these properties in an elegantly expandable manner in the designer’s property grid.
We are going to hide
Target from a property grid by marking them with
ValidatorControl class is inherited from
System.Web.UI.WebControl.Label and therefore exposes all the attributes of a Label, making itself useful as a means of display for error messages as well as housing our property extender control.
As you can see from the diagram above the
IExtenderProvider interface by defining
CanExtend method i.e. limiting the scope of ‘client’ controls to text boxes.
public bool CanExtend(object extendee)
return extendee is TextBox;
To actually define a provided property we are using a
ProvideProperty attribute and a
Get method for implementing the property’s logic.
Set method is not required since the provided property is a
TextValidator that handles its internal state.
public TextValidator GetValidation(TextBox textBox)
FindValidation method will have to find the corresponding
TextValidator in the encapsulated collection for each instance of
TextBox passed or create a new
TextValidator if none is found.
ValidatorControl also implements
IValidator interface making it a part of validators collection owned by a Web Form hosting it. Both this feature and the actual validation logic based on regular expressions are rather trivial and the source code in the sample project is self-explanatory. Those details are omitted from this narrative.
Why it does not work
Having performed all these or similar steps you should have a fully functional property extender control, and you probably would if this was done in a Windows Forms environment. So what is so different with Web Forms? If you test your control on an actual Web Form you will discover that the property values assigned to ‘client’ controls are ‘disappearing’ within the same design session and there is no persisting into the run-time. Clearly the issue is property serialization. In Windows Forms case, the designer is does all the dirty work serializing extended properties into CodeDom within the
ComponentInitialize method of a form class but a Web Form designer of Visual Studio 2003 seems to be unaware of the extended properties. It does however have and maintain the same
ComponentInitialize canvas method making it possible to write custom serialization for your properties with some fancy CodeDom footwork (see article by Wouter van Vugt for details). However there is one tough catch.
ComponentInitialize and CodeDom serialization are not available in Visual Studio 2005 as of Beta 2 release. These features have been ‘discontinued’ in favor of more straightforward HTML-based persistence. This means that if we want to see these properties serialized we will have to find an alternative to CodeDom.
Solving the issue of serialization for provided properties
There are a number of helpful attributes that allow WebControls to serialize and deserialize their collection-based properties. Since our
ValidatorControl is exposing the collection of
TextValidator objects as property named
Validators (where each member of the collection is responsible for validating a
TextBox) we can take advantage of those attributes. Given below is the declaration of the property:
public TextValidatorCollection Validators
DesignerSerializationVisibility instructs Web Form design environment to persist this property as content i.e. HTML tags versus
PersistenceMode attribute tells the designer to save the property as
InnerProperty, that is to serialize our collection between the opening and closing tags of
- We do not wish to expose this property in designer’s property grid therefore we mark it with
This is an example of the resulting HTML:
ErrorMessage="phone number should include only numerics">
ErrorMessage="last name should include only alpha characters">
ErrorMessage="first name should include only alpha characters">
As you can see all the
TextValidator objects are neatly tacked in within the
ValidatorControl tags. This takes care of serialization. Now what should we do about deserializing the TextValidators?
There is another attribute that can make this task a trivial one. It is called
ParseChildren and it is placed on a class level. While applying the attribute we specify that one of the properties in this control will have to be deserialized as a child collection and we also have to indicate specifically which property it is. This is how it is done:
public class ValidatorControl : Label, IExtenderProvider,
Now that we have the serialization and deserialization covered there is still one small problem. If you change the values of extended properties in design-time you will notice that the Web Form designer is not always updating the HTML tags representing your
ValidationControl. This happens because Visual Studio does not recognize the changes made from within a
TextBox property grid as in any way related to the
ValidatorControl. Let’s see what we can do about it.
Correcting design-time behavior
Since there is obvious gap in Web Form designer functionality that prevents
ValidationControl designer from being notified of changes in its state we will have to hand-code this wiring ourselves. Here is a method in
ValidatorControl that will ‘refresh’ design-time representation of our
Validators property whenever we need it to:
internal void NotifyDesigner()
IDesignerHost dh =
this.Site.Container as IDesignerHost;
LabelDesigner designer =
dh.GetDesigner(this) as LabelDesigner;
PropertyDescriptor pd =
ComponentChangedEventArgs ccea =
new ComponentChangedEventArgs(this, pd,
What happens here is we are telling the designer to refresh its rendering of the
ValidatorControl by explicitly sending
ComponentChanged event to the design-time environment. This will cause Visual Studio to re-render HTML tags of the control. As we employ a custom-built collection (
TextValidatorCollection) to store our
TextValidators we can ensure that each member in the collection has a reference to its parent (internal property and a member variable
private ValidatorControl m_Control;).
In the exposed properties of
TextValidator, I simply call
NotifyDesigner method every time the property is set.
[Description("regex expression for validating a textbox")]
public string Expression
m_Expression = value;
private void NotifyDesigner()
if (m_Control != null)
This simple technique will make the
ValidatorControl correctly reflect the changes that are made to the extended properties at design-time. Finally, we have a fully functional property extender control that plays nice with ASP.NET 1.1 and ASP.NET 2.0.
As this article demonstrated, there is a fairly straightforward way to leverage powerful extender technology in ASP.NET projects. Coding effort involved in setting up a property extender control is very well balanced by the flexibility and cleanness of the final solution. Developer’s attempts to introduce this .NET feature into Web Forms were somewhat discouraged by the changes that ASP.NET 2.0 has brought about but as we have proven there is a way to overcome the difficulties with serialization of extended properties and Visual Studio designer event model.
This paper is by no means a final word on the future of property extenders in ASP.NET environment and the sample project does have its limitations but it provides enough of a starting ground and brings in a new perspective to building elements of complex user interface. I am sure there are significant opportunities for design and experimentation that may lead to a better or a simpler model. Happy coding!
- 7/11/2005 - Original article posted.