Educating through exceptions
Note: this entry has moved.
The problem consist of calling these Register*
methods after the PreRender
event. For example, a common mistake made by (beginners)
custom controls developers is to write Register*
calls in the Render
method. This will only work for some of the Register*
methods:
|
Method |
Works in Render |
|
RegisterArrayDeclaration |
Yes |
|
RegisterHiddenField |
Yes |
|
RegisterStartupScript |
Yes |
|
RegisterOnSubmitStatement |
No |
|
RegisterClientScriptBlock |
No |
So what happens when the Render
method includes calls to RegisterOnSubmitStatement
and/or RegisterClientScriptBlock? Just nothing (and that
is the whole
problem!). No script gets rendered, no error is shown.
The (beginner) developer has to start guessing why his
code it’s not working as expected. A quick search in
google groups
will give him an instant answer but I believe the
framework could include a better approach to this.
I’m proposing to throw an exception (instead of
silently falling) when any of these methods are used
inappropriately. The exception should tell the user to
move the code to PreRender
or any other previous event. This will be even faster
than searching google J.
I believe this could be implemented by adding proper
checks in the Register*
methods. When one of these methods is called, the
control state for the Page
should be checked and if PreRender
was already processed then an exception should be
thrown. Something in the lines of:
[C#]
public virtual void
RegisterClientScriptBlock(String key, String
script)
{
if(this.ControlState ==
ControlState.PreRendered)
{
// throw an exception here
}
//
registration continues here
}
I would love to see this check added to all of the Register*
methods. To me, script registration should
always precede rendering. But as NikhilKo (not sure if he has
a blog but he wrote
this
great book) has properly pointed out, some of these
methods (see the table above) will work even when called
in Render
thus changing this behaviour could be considered a
breaking change.
For completeness sake, there is another scenario that will cause all the Register* methods to fail without giving you a clue. That happens when your page doesn’t include a server-side form; this is caused by a hard dependency between the Page and the HtmlForm classes... I will save the explanation for my next post… J