In asp.net world, creating custom server controls has become some sort of a standard. In fact, it is so easy to create a server control, that developers usually do it without thinking. The problem is, that server controls are a bit more complex than an average Joe would think. There are bunch of things you need to take care of, like handling client and server-side validation, handling control when view state is disabled etc. A developer must pay attention to these things, or weird bugs can start happening.

At one of my gigs, I lost 5 hours to what should have been a 30 minute task of writing a piece of JavaScript code that would disable and enable desired validator control on the page. The task was simple:

  1. locate desired validator and
  2. call ValidatorEnable JavaScript function.

 

The problem was, ValidatorEnable method threw null reference exception. An in-depth look and some serious debugging of Microsoft’s JavaScript library lead to conclusion that control that was set in ControlToValidate property could not be found on the page. This looked odd, as control was displayed on a page. I scouted web source code for control’s ID without much luck.To make it even weirder, server-side validation worked without any problems. I nearly gave up, when it dawned on me. Custom server control didn’t assign it’s id to any of controls it rendered and it never rendered any other HTML element with its id. Thus, HTML element with id validator was looking for, was never generated. I fixed the control to wrap it’s contents in span element with id set to ClientID of custom control and the bug was gone. And, in case you wondered, this bug never affected server-side validation, because server-side validation only looks at ValidationPropertyAttribute and it’s control stack. Thus…

In custom server control, always assign id to controls it renders

If you don’t, client-validation will fail in most odd, weird and ridiculous ways.

Always set ValidationPropertyAttribute

ValidationPropertyAttribute tells attached validator(s) what property to check when validation occurs. If you don’t set the attribute, validator(s) will automatically search for property named Text. If no property named Text is found, attached validator(s) simply won’t execute.

Never use ViewState

The worst possible mistake developers do, when creating custom server controls is use of ViewState. Controls are meant to be reused in many different scenarios, not just the one you are trying to solve at this particular moment. Using ViewState in a control means that control will stop working, if someone disables ViewState in a page that uses your control. To avoid this store all persistent state mechanism should be stored in ControlState.