PRB: AutoPostBack for the DropDownList Control May Not Work as Expected When You Use Caching and VaryByControl Is Set to DropDownList (822317)



The information in this article applies to:

  • Microsoft ASP.NET (included with the .NET Framework 1.1)
  • Microsoft ASP.NET (included with the .NET Framework) 1.0

SYMPTOMS

When you set the VaryByControl attribute of the @ OutputCache directive to DropDownList in an ASP.NET page, the AutoPostBack property of the DropDownList control may not work as expected.

CAUSE

You can use the @ OutputCache directive attribute VaryByControl to cache multiple versions of user control output, based on a GET query string or on form POST parameters. However, after the user control is cached, the __doFormPost method is not generated for postback.

Registration of the postbackscript occurs on the OnPreRender method. However, the OnPreRender method of the cached control is not called when you cache the user control. Therefore, when the user control is cached, the __doFormPost method is not generated.

WORKAROUND

To work around this problem, call the GetPostBackEventReference method in the Page_Load event of an ASPX page. To work around the problem that is discussed in the "More Information" section, modify the code of the Page_Load event as follows:

Visual C# .NET Sample Code

  public void Page_Load()
   {
     DateTime Created = DateTime.Now;    
     CreatedStamp.InnerHtml = Created.ToString("r");        
     GetPostBackEventReference(this);
   }

Visual Basic .NET Sample Code

    Public Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       Dim Created As DateTime
       Created = DateTime.Now
       CreatedStamp.InnerHtml = Created.ToString("s")     
       GetPostBackEventReference(Me)
     End Sub

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce the Behavior

  1. Start Microsoft Visual Studio .NET.
  2. Use Microsoft Visual Basic .NET or Microsoft Visual C# .NET to create a new ASP.NET Web Application project. By default, WebForm1.aspx is created.
  3. In Design view, right-click WebForm1, and then click View HTML Source.
  4. Replace the existing code with the following sample code to add DropDownList and user control registration.

    Visual C# .NET Sample Code
    <%@ Register TagPrefix="Fragment" TagName="Simple" Src="fragmentCache_byControl.ascx" %>
    <%@ Page %>
    <HTML>
    <HEAD>
     <Script Language="C#" runat="server">
       public void Page_Load()
       {
         DateTime Created = DateTime.Now;    
         CreatedStamp.InnerHtml = Created.ToString("r");    
         // Uncomment the following line to work around the problem:
         // GetPostBackEventReference(this);
       }
     </Script>
    </HEAD>
      <body MS_POSITIONING="GridLayout">
       <FONT size="6">Fragment Cache VaryByControl example:</FONT>
       <HR SIZE="1">
       <form id="MyContainer" method="post" runat="server">
         <FRAGMENT:SIMPLE id="UserCon1" runat="server"></FRAGMENT:SIMPLE>
       </form>
       <HR size="1">
       <Font size="6">This page was created at 
             <Font color="red"><B id="CreatedStamp" runat="server">	</B></Font>
       </Font>
    </body>
    </HTML>
    
    Visual Basic .NET Sample Code
    <%@ Page %>
    <%@ Register TagPrefix="Fragment" TagName="Simple" Src="fragmentCache_byControl.ascx" %>
    <HTML>
     <HEAD>		
       <Script Language="vb" runat="server"> 
         Public Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
           Dim Created As DateTime
           Created = DateTime.Now
           CreatedStamp.InnerHtml = Created.ToString("s")
          ' Uncomment the following line to work around the problem:
          ' GetPostBackEventReference(Me)
         End Sub
       </Script>		
     </HEAD>
     <body MS_POSITIONING="GridLayout">
    	<Font size="6">Fragment Cache VaryByControl example:</Font>
    	<HR size="1">
    	<form id="MyContainer" method="post" runat="server">
        	  <Fragment:simple id="UserCon1" runat="server" />
    	</form>	
    	<HR size="1">
    	<Font size="6">This page was created at <Font color="red">
              <B id="CreatedStamp" runat="server"></B></Font>
            </Font>
     </body>
    </HTML>
    
  5. In Solution Explorer, right-click your project name, point to Add, and then click Add New Item.
  6. Click Web User Control under Templates, and then name the control FragmentCache_byControl.ascx.
  7. In Design view, right-click WebForm1, and then click View HTML Source.
  8. Replace the existing code with the following sample code:

    Visual C# .NET Sample Code
    <%@ OutputCache Duration="20" varybyparam="none" VaryByControl="Category"%>
    <%@ Control Language="C#" AutoEventWireup="true"  %>
    <Script runat="server">
     public void Page_Load()
     {
      // Get the Date and Time. This should not change after the first run.       
      DateTime NowTime = DateTime.Now;
      DateTime Expires = NowTime.AddSeconds(60);			
      CreatedStamp.InnerHtml = NowTime.ToString("r");
      ExpiresStamp.InnerHtml = Expires.ToString("r");			
      }
    </Script>
    <BR>
    Category:
    <asp:DropDownList id="Category" AutoPostBack="True" runat="server">
      <asp:ListItem></asp:ListItem>
      <asp:ListItem Value="business">psychology</asp:ListItem>
      <asp:ListItem Value="psychology">business</asp:ListItem>
      <asp:ListItem Value="literature">literature</asp:ListItem>
    </asp:DropDownList>
    
    <Font size="3"><B id="CategoryItem" runat="server"></B>
      <P>
       Fragment Cache created: <Font color="red"><B id="CreatedStamp" runat="server"></B></Font>
       <BR>
       Fragment Cache expires: <Font color="red"><B id="ExpiresStamp" runat="server"></B></Font>
      </P>
    </Font>
    
    Visual Basic .NET Sample Code
    <%@ Control Language="vb" AutoEventWireup="true"  %>
    <%@ OutputCache Duration="20" varybyparam="none" VaryByControl="Category"%>
    <Script runat="server">
     Public Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       Dim NowTime As DateTime
       Dim Expires As DateTime     
       NowTime = DateTime.Now
       Expires = NowTime.AddSeconds(60)
       Dim Created As DateTime
       CreatedStamp.InnerHtml = Created.Now.ToString("s")
       ExpiresStamp.InnerHtml = Expires.ToString("s")    
     End Sub
    </Script>
    <BR>
    Category:
    <asp:DropDownList id="Category" AutoPostBack="True" runat="server">
      <asp:ListItem></asp:ListItem>
      <asp:ListItem Value="business">psychology</asp:ListItem>
      <asp:ListItem Value="psychology">business</asp:ListItem>
      <asp:ListItem Value="literature">literature</asp:ListItem>
    </asp:DropDownList>
    <Font size="3"><B id="CategoryItem" runat="server"></B>
      <P>
       Fragment Cache created: <Font color="red"><B id="CreatedStamp" runat="server"></B></Font>
       <BR>
       Fragment Cache expires: <Font color="red"><B id="ExpiresStamp" runat="server"></B></Font>
      </P>
    </Font>
    
  9. On the Debug menu, click Start to save and then run the project.
  10. Click the first item in the drop-down list box. Notice that a new fragment cache time stamp is created.
  11. Click the second item in the drop-down list box. Notice that a different fragment cache time stamp is created.
  12. Repeat steps 9 and 10.
  13. Notice that the time stamps do not change, regardless of the item that you select in the drop-down list box.

REFERENCES

For additional information, click the following article numbers to view the articles in the Microsoft Knowledge Base:

307225 INFO: ASP.NET Caching Overview

308378 HOW TO: Perform Fragment Caching in ASP.NET by Using Visual C# .NET

308645 HOW TO: Perform Fragment Caching in ASP.NET by Using Visual Basic .NET

For more information, visit the following visit the following Microsoft Web site:For information about ASP.NET caching and samples of ASP.NET caching from the ASP.NET QuickStart guides, visit the following Microsoft Web site:

Modification Type:MajorLast Reviewed:8/8/2003
Keywords:kbCaching kbServerControls kbForms kbControl kbWebForms kbprb KB822317 kbAudDeveloper