Back in the late 1990s when Classic ASP was Microsoft's Flagship Web Development Programming Language today's Debugging tools were still in concept and a web developer had to resort to a very simple but yet powerful tool in the ASP library: The Response.Write method.
The Response.Write purpose was not for debugging as it was the primary way to output information in dynamic web applications using classic ASP. Almost all dynamic content was filled using Response.Write and its shorthand variant.
When an ASP Web Application was having a strange behavior and perhaps a variable was not having the expected value or just when you thought your application was perfect an error while browsing pops up and just says "errors occurred". That's when you pull out your tools bag and extract the most powerful weapon in debugging back then.
Of course there were other alternatives but it was so easy as well to just select a few points in the application flow and put some Response.Write showing the contents of variables or just outputting text like "Database Open". That would get you to the source of the application problem. After correcting the issue the Response.Write is either deleted or commented out.
Today, even with the Visual Studio debugging capabilities, we still go ahead and do a couple of Response.Write here and there. And not necessarily for debugging purposes. But this article is not only about Response.Write but about his relationship with the UpdatePanelfrom the Microsoft AJAX frameworkwhen they're put together in a web page. Let's take a look at some code.
1 <%@ Page Language="VB" %>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <script runat="server">
4 Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
5 'Response.Write("Hello")
6 lblDateTime.Text = Now.ToString
7 End Sub
8 </script>
9 <html xmlns="http://www.w3.org/1999/xhtml">
10 <head runat="server">
11 <title></title>
12 </head>
13 <body>
14 <form id="form1" runat="server">
15 <asp:ScriptManager ID="ScriptManager1" runat="server">
16 </asp:ScriptManager>
17 <asp:UpdatePanel ID="UpdatePanel1" runat="server">
18 <ContentTemplate>
19 <div>
20 Date and Time:
21 <asp:Label ID="lblDateTime" runat="server"></asp:Label>
22 <br />
23 <asp:Button ID="Button1" runat="server" Text="Update" OnClick="Button1_Click" />
24 </div>
25 </ContentTemplate>
26 </asp:UpdatePanel>
27 </form>
28 </body>
29 </html>
In that previous code snippet we can see we have a very simple page with the Script Manager and an UpdatePanel. Inside the UpdatePanel we have a Div with 2 controls. A Label and a Button. We have defined an event to handle the Button's click event in which the Label's Text property will be set with the Now.ToString value.
The Problem
If you run this page and click the Button you will see that the Label's text is refreshed each time with the current date and time in the server without post backs. If you remove the comment apostrophe that is keeping the page from executing the Response.Write method and run this page again and press the button, nothing will happen. Not even the Label is changing its value and the string Hello is not being printed on screen. What's going on?
The problem resides on the nature of Response.Write as it injects new information into the page output stream when a Partial Update which communicates in XML with the server is in play. The Response.Write breaks the XML and stops the normal processing of the partial update. In a normal postback the Response.Write and the page behave ok.
The solution
What are you doing using Response.Write? Nah, I'm kidding. Now, seriously. If you need the Response.Write for whatever reason in this scenario you either move the button outside of the UpdatePanel.
14 <form id="form1" runat="server">
15 <asp:ScriptManager ID="ScriptManager1" runat="server">
16 </asp:ScriptManager>
17 <asp:UpdatePanel ID="UpdatePanel1" runat="server">
18 <ContentTemplate>
19 <div>
20 Date and Time:
21 <asp:Label ID="lblDateTime" runat="server"></asp:Label>
22 <br />
23 </div>
24 </ContentTemplate>
25 </asp:UpdatePanel>
26 <asp:Button ID="Button1" runat="server" Text="Update" OnClick="Button1_Click" />
27 </form>
Or mark the Button as a PostBackTrigger in the UpdatePanel markup as indicated below. That way you can keep the button inside the UpdatePanel.
26 <Triggers>
27 <asp:PostBackTrigger ControlID="Button1" />
28 </Triggers>
Doing this will yield the same result. A postback will ensue when the Button is clicked and the code will be executed as expected. No partial updates though.
Happy programming!
