Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

One of the things that was introduced in .NET 2.0 was a new mechanism for managing registration of client script into the page, via the new ClientScriptManager class, instead of the page's dedicated RegisterClientScriptBlock method. In the process of moving the API, MS also saw fit to add a new Type parameter to the method.

This reflects the fact that the best practice when calling Page.RegisterClientScriptBlock was to formulate a unique key for your script that incorporated the fully qualified name of the class doing the registration of the script, as a way to avoid unseemly clashes between script registrations. That way, only one copy of the script for a particular control gets registered per page, no matter how many such controls appear on the page - and at the same time, the script shouldn't trample on the scripts needed by other controls.

With ClientScriptManager, you're spared the need to formulate the name for your script to incorporate said fully qualified typename by the API, which asks you to pass a type object in, which it will use to uniquely key all the scripts registered.

So far so good. The one fly in the ointment for anyone calling the new API is figuring out how to actually obtain an appropriate type object to pass in.

The MSDN example code, and all the other examples I can find, the idiom adopted seems to be:

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Script", scriptText);

This is not good. Why not? Well, this.GetType() is a way of getting the runtime type of an object. That's not necessarily the same type as the one in which this bit of code is being declared.

So what? Does that actually make any difference? Well, yes, if anyone ever writes a control that inherits from your control.

If I create a control called Widget that calls RegisterClientScriptBlock() passing this.GetType(), then whenever I put a few Widget controls on the page, the script block will be registered once, and only once. That's great.

Then later on, I develop a SpecialisedWidget control that inherits from Widget. I drop it onto the page, and suddenly, RegisterClientScriptBlock is getting called with the same script, but two different types - Widget, and SpecialisedWidget. The script block ends up appearing on the page twice. Cue tricky hard to track JavaScript bugs that take ages to find...

Now, if Widget had originally registered that script block passing typeof (Widget) as the type argument instead of this.GetType(), the whole problem wouldn't arise, because even when the SpecialisedWidgets are registering script on the page, the script is registered with the type qualifier of Widget. And as a side bonus, the IL will be more efficient, because typeof (Widget) is a kind of type literal, which the compiler can embed right into the code, rather than a runtime dispatched method call to a reflection API.

So the lesson of the day is, use typeof to get a static compile-time type reference when calling the ASP.NET 2.0 RegisterClientScriptBlock method, not GetType() to get a dynamic runtime type.

Print | posted on Tuesday, October 03, 2006 12:03 PM

Comments on this post

# ClientScript.RegisterClientScriptBlock

Requesting Gravatar...
.. I had been using this.GetType() until i read this article ... which clearly explains why it is not good practise to use this.GetType() as it returns the runtime type of an object. ...
Left by Pingback/TrackBack on Jan 05, 2007 12:52 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Hi!
This was helpfull.
But Page.ClientScript.IsClientScriptBlockRegistered()
comes with tow overloaded variants. One is without type and other is with type.
Any idea how this IsClientScriptBlockRegistered(key) cheks if script is registered?
Left by Sander on Feb 15, 2007 12:50 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
I stumbled onto your blog when refreshing my memory on RegisterClientScriptBlock() syntax. Great post.

Your byline is great too.

Cheers,

Mike
Left by Mike on Mar 22, 2007 2:41 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
how about using reflection to get the current type??
ie:

System.Reflection.MethodBase.GetCurrentMethod().GetType();

Left by David Jorgensen on Mar 27, 2007 1:57 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Good info I was just about to do this when I found your blog.
Left by Larry on Jun 18, 2007 6:42 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Why on earth would you ever make one ascx control inherit from another?
Left by Brandon on Jun 27, 2007 4:11 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Brandon - who said anything about ascx controls?
Seeing as inheritance is being discussed, I would think think that the advice is more targetted toward custom server controls (i.e. those derived from System.Web.UI.WebControls.WebControl and compiled to dlls) rather than user controls (.ascx files)
Left by Chris on Jun 29, 2007 12:23 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Very helpful post.
Left by Darryl on Jul 17, 2007 8:54 PM

# Wow...

Requesting Gravatar...
Wow, I ran into this EXACT problem right now! I can't believe I found the answer on my first try! Yay me!
Left by Travis on Jul 27, 2007 8:04 PM

# DON'T Work Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Calendar_ChangeDate", strScript);

Requesting Gravatar...
protected void Calendar_SelectionChanged(object sender, EventArgs e)
{
if (Request.QueryString["textbox"] != "")
{
string strScript = "<script>window.opener.document.forms(0)." + Request.QueryString["textbox"].ToString() + ".value = '";
strScript += Calendar.SelectedDate.ToString("MM/dd/yyyy");
strScript += "';self.close()";
strScript += "</" + "script>";
//Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "calenderScript", strScript);
//ClientScript.RegisterClientScriptBlock(typeof(Calender), "calenderScript", strScript);
if (!Page.ClientScript.IsClientScriptBlockRegistered("Calendar_ChangeDate"))

Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Calendar_ChangeDate", strScript);
}
}
Left by N.N on Aug 14, 2007 7:34 AM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
How do I get back the yes/no answer on something like this :

if (dr.HasRows)
{
dr.Read();
Txt1.Value = dr.GetOracleString(5).ToString();
}
else
string msgDesc = "Sure you want to continue?";
string script = "<script language=\"javascript\">confirm('" + msgDesc + "');</script>";
ClientScript.RegisterStartupScript(typeof(Page), "UserMessage", script);


(Now how do I get back the yes/no reply???)
Left by JayViz on Aug 20, 2007 11:31 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Very usefull post
Left by Rajan on Aug 22, 2007 6:08 AM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
How can one get this to work if the method that is to register the client script is being executed within a button click event that updates the page using AJAX?

thanks.
Left by m on Nov 23, 2007 11:06 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Thanks, this helped alot.
Gus
Left by Gus on Nov 27, 2007 2:16 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Very helpful post indeed!! You solved my problem in minutes :)
Left by Sana on Feb 25, 2008 9:32 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
typeof does not appear to be allowed in vb.

if I put this Me.GetType.TypeHandle

i get the system.runtime.typehandle cannot be converted to system.type
Left by tim gapinski at yahoo on Feb 27, 2008 2:15 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Thank you for the tip. It solved my problem!!!
Left by Edwin on Apr 23, 2008 5:22 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
string sbReference = ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
string cbScript = String.Empty;
// check if the script is already registered or not
if (!ClientScript.IsClientScriptBlockRegistered("CallServer"))
{
cbScript = @" function CallServer(arg,context) { " + sbReference + "}";
ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", cbScript, true);
}
Left by deepa on May 06, 2008 10:08 AM

# Text label “inside” password input (safe without javascript)

Requesting Gravatar...
You can find several ways of putting some sample text in a HTML input text which fades away when you
Left by Bruno Silva on Aug 08, 2008 4:09 PM

# Sape&amp;#8217;s Blog &amp;raquo; Blog Archive &amp;raquo; Client Side Script in a .NET Web Part

Requesting Gravatar...
Sape&#8217;s Blog &raquo; Blog Archive &raquo; Client Side Script in a .NET Web Part
Left by Pingback/TrackBack on Aug 26, 2008 7:38 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
In VB.Net the syntax is:

ClientScript.RegisterStartupScript(GetType(Page), "UserMessage", script)
Left by Andrea Conti on Oct 07, 2008 3:04 PM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
Hi,

I'm a newbie to asp.net.

I'm using the below code in one of my .aspx pages.
try
{
bTrans = true;
txn.Commit();
}
catch (Exception ex)
{
bTrans = false;
txn.Rollback();
ExceptionLog(ex);

throw ex;
}
finally
{
if (txn != null)
txn.Dispose();
if (bTrans)
{
btnSubmit.Enabled = false;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("");
RegisterClientScriptBlock("ShowParent", sb.ToString());
}
else
{
btnSubmit.Enabled = true;
}
}

Instead of RegisterClientScriptBlock how should i use ClientScript.RegisterClientScriptBlock() especially for Type parameter which on i should go for ?

Thanks :)
Left by Sreenivasan on Nov 03, 2008 6:24 AM

# re: Don't use GetType() with Page.ClientScript.RegisterClientScriptBlock()

Requesting Gravatar...
So, how do I register a script block on the parent page of an ASCX control?

Thanks
Left by dds110 on Nov 14, 2008 4:22 PM

Your comment:

 (will show your gravatar)
 
Please add 5 and 5 and type the answer here: