Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

BUG: Script Blocks Not in the Same Order of Registration When You Add Them to a Page That Uses RegisterClientScriptBlock() or RegisterStartupScript()


View products that this article applies to.

Symptoms

When you use the RegisterClientScriptBlock() method to add more then eight client-side script blocks to a page, the Script Blocks are not added in the order that you register them. Similarly, when you use RegisterStartupScript() to add more then eight client-side script blocks to a page, the script blocks are not added in the order that you register them. If the execution of the client-side script depends on the order of the script block registration, then the client-side scripts may not behave as you expect.

Note You can preserve the registration order for a maximum of 16 client-side script blocks. To do so, use eight for the RegisterClientScriptBlock() method and eight for the RegisterStartupScript() method.

↑ Back to the top


Cause

The registered script blocks exist in the HybridDictionary object class. If there are eight or fewer client-side script blocks, then the HybridDictionary implements with a ListDictionary class to store the items in the collection. When the collection size grows to more than eight items, the HybridDirectory switches to a Hashtable table. The ListDictionary maintains the order for added items, so that the items are retrieved in sequence. However, the Hashtable does not maintain the order of registration of the items in the collection. Therefore, the insertion of the client-side script does not occur in the serial order of registration.

↑ Back to the top


Resolution

To resolve this problem, add all the client-side script blocks to a StringBuilder method, and then register the StringBuilder as one script block. To do so, follow these steps:
  1. In Microsoft Visual Studio .NET, use Microsoft Visual Basic .NET or Microsoft Visual C# .NET to create a new ASP.NET Web application project. Name the project RegJScriptBlock. By default, WebForm1.aspx is created.
  2. Right-click WebForm1, and then click View HTML.
  3. Replace the existing code with the following code:

    Visual C# .NET Code


    <%@ Page language="c#" %>
    <HTML>
    	<HEAD>
    		<script language="C#" runat="server">				
    		public void Page_Load(object sender, System.EventArgs e)
    		{
    			int i = 0;							
    			string scriptKey = "";
    			if(Page.IsPostBack.Equals(false))
    			{
    				ViewState["n"]=0;
    			}
    			else 
    			{
    				ViewState["n"] = Int32.Parse(ViewState["n"].ToString())+1;
    				i = Int32.Parse(ViewState["n"].ToString());			
    			}
    
    			string[] nubmerOfScripts = new string[Int32.Parse(ViewState["n"].ToString())+1] ;   
    			StringBuilder sb = new StringBuilder();
    			for(int j=1;j<=i+1;j++)
    			{
    				sb.Append("<script language=JavaScript>");
    				sb.Append("if("+j+">1){clicked="+j+";} else {clicked=1;}");				
    				sb.Append("function DoClick"+j+"() {");			
    				sb.Append("myForm.textCount.value=clicked} <");
    				sb.Append("/");
    				sb.Append("script>");	
    				sb.Append("\n");
    				nubmerOfScripts[j-1]=sb.ToString();
    				scriptKey = "clientScript"+j;
    			}						
       			// Register all  Java script  as a Single Block							
    			if(!this.IsClientScriptBlockRegistered(scriptKey))
    				this.RegisterClientScriptBlock(scriptKey, nubmerOfScripts[i]);						
    		}	
    		</script>
    	</HEAD>
    	<body onload="DoClick1()">
    		<form id="myForm" method="post" runat="server">
    			Serial Number of the Last JavaScript Registered:<INPUT id="textCount" type="text"><br>
    			<asp:Button id="AddScripts" runat="server" Text="Register JavaScript Block" Height="70px" Width="326px"></asp:Button>
    		</form>
    	</body>
    </HTML>
    

    Visual Basic .NET Code


    <%@ Page Language="vb" %>
    <%@ Import Namespace="System.Text" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    	<HEAD>
    		<title>WebForm1</title>
    		<script language= "vb" runat="server">				
    	 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Dim i As Integer
            Dim scriptKey As String
    
            If (Page.IsPostBack.Equals(False)) Then
    
                ViewState("n") = 0
            Else
                ViewState("n") = Int32.Parse(ViewState("n").ToString()) + 1
                i = Int32.Parse(ViewState("n").ToString())
    
            End If
    
            Dim nubmerOfScripts As String()
     
            ReDim nubmerOfScripts(Int32.Parse(ViewState("n").ToString()))
    
            Dim j As Integer
            Dim sb As New StringBuilder()
    
            For j = 1 To i + 1 Step 1        
                sb.Append("<script language=JavaScript>")
                If j > 1 Then
                sb.Append("clicked=" + j.ToString() + ";")
                else
                sb.Append("clicked=1;")
                End If            
                sb.Append("function DoClick" + j.ToString() + "() {")
                sb.Append("myForm.textCount.value=clicked} <")
                sb.Append("/")
                sb.Append("script>")
                sb.Append(Chr(13))
                nubmerOfScripts(j - 1) = sb.ToString()
                scriptKey = "clientScript" + j.ToString()
            Next
    
            ' Register all  JavaScript  as a Single Block							
            If (Not (Page.IsClientScriptBlockRegistered(scriptKey))) Then
                Page.RegisterClientScriptBlock(scriptKey, nubmerOfScripts(i))
            End If
        End Sub
    		</script>
    	</HEAD>
    	<body onload="DoClick1()">
    		<form id="myForm" method="post" runat="server">
    			Serial Number of the Last JavaScript Block Registered:<INPUT id="textCount" type="text"><br>
    			<asp:Button id="AddScripts" runat="server" Text="Register JavaScript Block" Height="70px" Width="326px"></asp:Button>
    		</form>
    	</body>
    </HTML>
    
  4. On the Debug menu, click Start to run the application.
  5. Click Register JavaScript Block to register the new JScript blocks. Each time that the JScript block is registered, the textbox displays the serial number of the last script block that is added to the Web page.
  6. To register more than eight JScript blocks, repeat step 5 in this section of the article.
  7. View the source on the Web page to see the order where the client script blocks are added. To do so, locate the following Web page and then right-click View Source:
    http://localhost/RegJScriptBlock/WebForm1.aspx
    You can see that the JScript blocks are in sequence even when the number of registered scripts is greater than eight.

↑ Back to the top


Status

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

↑ Back to the top


More information

Steps to Reproduce the Behavior


  1. Start Microsoft Visual Studio .NET, and then create a new ASP.NET Web application project with Visual Basic .NET or with Visual C# .NET. Name the project RegJScriptBlock. By default, WebForm1.aspx is created.
  2. Right-click WebForm1, and then click View HTML.
  3. Replace the existing code with the following code:

    Visual C# .NET Code

    <%@ Page language="c#" %>
    <HTML>
    	<HEAD>
    		<script language="C#" runat="server">				
    		public void Page_Load(object sender, System.EventArgs e)
    		{
    			int i = 0;							
    			string scriptKey = "";
    			if(Page.IsPostBack.Equals(false))
    			{
    				ViewState["n"]=0;
    			}
    			else 
    			{
    				ViewState["n"] = Int32.Parse(ViewState["n"].ToString())+1;
    				i = Int32.Parse(ViewState["n"].ToString());			
    			}
    
    			string[] nubmerOfScripts = new string[Int32.Parse(ViewState["n"].ToString())+1] ;				
    
    			for(int j=1;j<=i+1;j++)
    			{
    				StringBuilder sb = new StringBuilder();
    				sb.Append("<script language=JavaScript>");
    				sb.Append("if("+j+">1){clicked="+j+";} else {clicked=1;}");				
    				sb.Append("function DoClick"+j+"() {");			
    				sb.Append("myForm.textCount.value=clicked} <");
    				sb.Append("/");
    				sb.Append("script>");	
    				sb.Append("\n");
    				nubmerOfScripts[j-1]=sb.ToString();
    				scriptKey = "clientScript"+j;
            
    				// Register individual JavaScript Blocks
    				if(!this.IsClientScriptBlockRegistered(scriptKey))
    					this.RegisterClientScriptBlock(scriptKey, nubmerOfScripts[j-1]);							
    			}						
    	
    		}	
    		</script>
    	</HEAD>
    	<body onload="DoClick1()">
    		<form id="myForm" method="post" runat="server">
    			Serial Number of the Last Java Script Block Registered:<INPUT id="textCount" type="text"><br>
    			<asp:Button id="AddScripts" runat="server" Text="Register JavaScript Block" Height="70px" Width="326px"></asp:Button>
    		</form>
    	</body>
    </HTML>
    

    Visual Basic .NET Code


    <%@ Page Language="vb" %>
    <%@ Import Namespace="System.Text" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    	<HEAD>
    		<title>WebForm1</title>
    		<script language= "vb" runat="server">				
    	 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) 
            Dim i As Integer
            Dim scriptKey As String
    
            If (Page.IsPostBack.Equals(False)) Then
    
                ViewState("n") = 0
            Else
                ViewState("n") = Int32.Parse(ViewState("n").ToString()) + 1
                i = Int32.Parse(ViewState("n").ToString())
    
            End If
    
            Dim nubmerOfScripts As String()
            ReDim nubmerOfScripts(Int32.Parse(ViewState("n").ToString()))
    
            Dim j As Integer        
     
            For j = 1 To i + 1 Step 1
                Dim sb As New StringBuilder()
                sb.Append("<script language=JavaScript>")
                If j > 1 Then
                sb.Append("clicked=" + j.ToString() + ";")
                else
                sb.Append("clicked=1;")
                End If            
                sb.Append("function DoClick" + j.ToString() + "() {")
                sb.Append("myForm.textCount.value=clicked} <")
                sb.Append("/")
                sb.Append("script>")
                sb.Append(Chr(13))
                nubmerOfScripts(j - 1) = sb.ToString()
                scriptKey = "clientScript" + j.ToString()
                    'Register individual Java Script Blocks
                    If (Not (Page.IsClientScriptBlockRegistered(scriptKey))) Then
                       Page.RegisterClientScriptBlock(scriptKey, nubmerOfScripts(j - 1))
                  End If
    
            Next
    
        End Sub
    		</script>
    	</HEAD>
    	<body onload="DoClick1()">
    		<form id="myForm" method="post" runat="server">
    			Serial Number of the Last Java Script Block Registered:<INPUT id="textCount" type="text"><br>
    			<asp:Button id="AddScripts" runat="server" Text="Register JavaScript Block" Height="70px" Width="326px"></asp:Button>
    		</form>
    	</body>
    </HTML>
    
  4. On the Debug menu, click Start to run the application.
  5. Click Register JavaScript Block to register the new JScript blocks. Each time that you register the JScript block, the textbox displays the serial number of the last script block that you added to the Web page.
  6. View the source on the Web page to see the order that the client script blocks are added. To do so, locate the following Web page, right-click Web page, and then click View Source:
    http://localhost/RegJScriptBlock/WebForm1.aspx

    You can see that the JScript blocks are in sequence until the number of registered scripts exceeds eight.
  7. To register more than eight JScript blocks, repeat step 5 in this section of the article. The value in the textbox shows the serial number of the last script in the order that it was registered (until the number of JScripts that you register exceeds eight). When the number of registered JScript blocks exceeds eight, the order is not in sequence. The order that the script blocks are added does not match the script block registration order.
  8. Right-click WebForm1, and then click View Source. Note that the sequence of the JScript blocks is not the same order that you registered them.

↑ Back to the top


References


For more information about the RegisterClientScriptBlock method, visit the following Microsoft Developer Network (MSDN) Web sites:

Page.RegisterClientScriptBlock Method
http://msdn2.microsoft.com/en-us/library/system.web.ui.page.registerclientscriptblock(vs.71).aspx

Page.RegisterStartupScript Method
http://msdn2.microsoft.com/en-us/library/system.web.ui.page.registerstartupscript(vs.71).aspx

↑ Back to the top


Keywords: KB817032, kbbug, kbwebforms, kbwebserver, kbscript

↑ Back to the top

Article Info
Article ID : 817032
Revision : 7
Created on : 5/21/2007
Published on : 5/21/2007
Exists online : False
Views : 363