<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>My Fried Tech! - VB.Net</title>
    <link>http://www.myfriedmind.com/techBlog/</link>
    <description>oddities from my work</description>
    <language>en-us</language>
    <copyright>Matt Mcknight</copyright>
    <lastBuildDate>Thu, 19 Nov 2009 22:29:18 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>matt@em.org</managingEditor>
    <webMaster>matt@em.org</webMaster>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was setting up a Man in the Middle webservice to intercept a message coming in so
that I could do some processing of it on the side. Don't worry, it was our webservice.
My process is fairly simple:
</p>
        <ol>
          <li>
accept the submitted object 
</li>
          <li>
forward the object to the old web service 
</li>
          <li>
do what I wanted with the info</li>
        </ol>
        <p>
Step #2 appears fairly straightforward, and for the most part it is. 
</p>
        <ol>
          <li>
Create a (new) Web Service. 
</li>
          <li>
Expose the same public WebMethods. 
</li>
          <li>
Add a 'Web Reference' to the (old) Web Service 
</li>
          <li>
Create a new Web Service object of the old Web Service 
</li>
          <li>
Pass the received object onward</li>
        </ol>
        <p>
The problem that occurs is that because the (new) Web Service has to be all-inclusive
it creates its own object type. While this is acceptable in .Net (since it goes by
.net classnames) this gets all out of whack in the XML. This is because the XML uses
a different namespace process - and since the (new) Web Service uses the same object
as the (old) Web Service, albeit with a different .net namespace one of the things
that it includes as an Attribute is the XML namespace. So
</p>
        <ul>
          <li>
The two classes have different .net namespaces 
</li>
          <li>
The two classes have the exact same XML namespace</li>
        </ul>
        <p>
The compiler does not catch this because it is only looking at the .net namespace.
So it will give you all sorts of helpful suggestions. 
</p>
        <p>
However....
</p>
        <p>
There is a simpler way to do it. Basically, since you KNOW that the incoming and outgoing
objects are the same, you are simply going to override the class that the Web Reference
uses to tell it to use the original class.
</p>
        <p>
If you initially open up the Web Reference to your (old) Web Service you are not going
to see the file you need. You need to go up to the File Menu and select Project, Show
All Files. 
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/MiMXMLShowAll.gif" border="1" />
        </p>
        <p>
Now you will see the file that you want over in the Solution Exploerer -&gt; Reference.cs. 
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/MiMXMLReference.gif" border="1" />
        </p>
        <p>
Open that puppy up and make the necessary changes, just remember to wipe out the (new)
objects that will be in there. All you want to leave are the methods, and those should
now be passing the classes from the (old) Web Service.
</p>
        <p>
Happy coding!
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea" />
      </body>
      <title>Man in the Middle Web Services and XML Serialization errors</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/11/19/ManInTheMiddleWebServicesAndXMLSerializationErrors.aspx</link>
      <pubDate>Thu, 19 Nov 2009 22:29:18 GMT</pubDate>
      <description>&lt;p&gt;
I was setting up a Man in the Middle webservice to intercept a message coming in so
that I could do some processing of it on the side. Don't worry, it was our webservice.
My process is fairly simple:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
accept the submitted object 
&lt;li&gt;
forward the object to the old web service 
&lt;li&gt;
do what I wanted with the info&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Step #2&amp;nbsp;appears fairly straightforward, and for the most part it is. 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Create a (new) Web Service. 
&lt;li&gt;
Expose the same public WebMethods. 
&lt;li&gt;
Add a 'Web Reference' to the&amp;nbsp;(old) Web Service 
&lt;li&gt;
Create a new Web Service object of the old Web Service 
&lt;li&gt;
Pass the received object onward&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The problem that occurs is that because the (new) Web Service has to be all-inclusive
it creates its own object type. While this is acceptable in .Net (since it goes by
.net classnames) this gets all out of whack in the XML. This is because the XML uses
a different namespace process - and since the (new) Web Service uses the same object
as the (old) Web Service, albeit with a different .net namespace one of the things
that it includes as an Attribute is the XML namespace. So
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The two classes have different .net namespaces 
&lt;li&gt;
The two classes have the exact same XML namespace&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The compiler does not catch this because it is only looking at the .net namespace.
So it will give you all sorts of helpful suggestions. 
&lt;/p&gt;
&lt;p&gt;
However....
&lt;/p&gt;
&lt;p&gt;
There is a simpler way to do it. Basically, since you KNOW that the incoming and outgoing
objects are the same, you are simply going to override the class that the Web Reference
uses to tell it to use the original class.
&lt;/p&gt;
&lt;p&gt;
If you initially open up the Web Reference to your (old) Web Service you are not going
to see the file you need. You need to go up to the File Menu and select Project, Show
All Files. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/MiMXMLShowAll.gif" border=1&gt;
&lt;/p&gt;
&lt;p&gt;
Now you will see the file that you want over in the Solution Exploerer -&amp;gt; Reference.cs. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/MiMXMLReference.gif" border=1&gt;
&lt;/p&gt;
&lt;p&gt;
Open that puppy up and make the necessary changes, just remember to wipe out the (new)
objects that will be in there. All you want to leave are the methods, and those should
now be passing the classes from the (old) Web Service.
&lt;/p&gt;
&lt;p&gt;
Happy coding!
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,b41b4f63-6aaa-49cb-b1b8-de5b2dabfcea.aspx</comments>
      <category>Asp.Net</category>
      <category>c#</category>
      <category>Coding Tricks</category>
      <category>VB.Net</category>
      <category>Web Services</category>
    </item>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=2a008128-730b-4dd5-9cfa-e336a0b0a568</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,2a008128-730b-4dd5-9cfa-e336a0b0a568.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,2a008128-730b-4dd5-9cfa-e336a0b0a568.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=2a008128-730b-4dd5-9cfa-e336a0b0a568</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Part 1 - <a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx">Introduction</a><br />
Part 2 - <a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx">Basic
Example</a><br />
Part 3 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx">Complex
Example</a><br />
Part 4 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx">Final
Notes</a><br />
Bonus - <a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx">Ajax
History and the Memento Pattern</a></p>
        <p>
There is some clean up I need to do in regards to my posts for Ajax History. 
</p>
        <p>
Where can I see an example?
</p>
        <p>
You can download the zipped files here -&gt; <a href="http://www.myfriedmind.com/techBlog/content/binary/AjaxExamples.zip">AjaxExamples.zip</a> or
go to <a href="http://www.myfriedmind.com/AjaxExamples">http://www.myfriedmind.com/AjaxExamples</a> and
poke around
</p>
        <h3>What version of .net do I need?
</h3>
        <p>
I want to reiterate that you must be using .net 3.5 (or higher) for this to function.
The methods and properties that are used are packaged into .net 3.5 (as is Ajax itself).
</p>
        <h3>How long does my history last (ie going back/forward)?
</h3>
        <p>
Your history lasts only as long as you are on that particular page. You can go forward
and backward over your Ajax history all you want, but once you got to a different
page, either preceding or following, you lose your pathway. This does not mean that
if you get one of the intermediate URIs either through bookmarks, links, manually
typing, etc that it will not return that particular page. It will. But the tracking
of the entries in your browser history will be lost. 
</p>
        <p>
This also means that if the user modifies the URI manuallyto change what is in
the has, it will lose that history since it considers you having gone to a new
page.
</p>
        <h3>What if I need to keep a perfect snapshot of the page itself? 
</h3>
        <p>
If that is the case then you are going to need to look at a different way to store/retrieve
the data. You will probably need to store each page, as it appears, into the database
and then recall it from there. Do NOT store it in the History Points Remember,
what is stored in the History Points must be tiny!
</p>
        <h3>Why does Opera NOT WORK???
</h3>
        <p>
          <a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx">http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx</a> (thanks
to Tomi for discovering this issue)
</p>
        <img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=2a008128-730b-4dd5-9cfa-e336a0b0a568" />
      </body>
      <title>Ajax History - a how to - Part 4 - final notes</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,2a008128-730b-4dd5-9cfa-e336a0b0a568.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx</link>
      <pubDate>Thu, 09 Jul 2009 16:57:00 GMT</pubDate>
      <description>&lt;p&gt;
Part 1 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"&gt;Introduction&lt;/a&gt;
&lt;br&gt;
Part 2 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx"&gt;Basic
Example&lt;/a&gt;
&lt;br&gt;
Part 3 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx"&gt;Complex
Example&lt;/a&gt;
&lt;br&gt;
Part 4 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx"&gt;Final
Notes&lt;/a&gt;
&lt;br&gt;
Bonus - &lt;a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"&gt;Ajax
History and the Memento Pattern&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
There is some clean up I need to do in regards to my posts for Ajax History. 
&lt;/p&gt;
&lt;p&gt;
Where can I see an example?
&lt;/p&gt;
&lt;p&gt;
You can download the zipped files here -&amp;gt; &lt;a href="http://www.myfriedmind.com/techBlog/content/binary/AjaxExamples.zip"&gt;AjaxExamples.zip&lt;/a&gt;&amp;nbsp;or
go to &lt;a href="http://www.myfriedmind.com/AjaxExamples"&gt;http://www.myfriedmind.com/AjaxExamples&lt;/a&gt; and
poke around
&lt;/p&gt;
&lt;h3&gt;What version of .net do I need?
&lt;/h3&gt;
&lt;p&gt;
I want to reiterate that you must be using .net 3.5 (or higher) for this to function.
The methods and properties that are used are packaged into .net 3.5 (as is Ajax itself).
&lt;/p&gt;
&lt;h3&gt;How long does my history last (ie going back/forward)?
&lt;/h3&gt;
&lt;p&gt;
Your history lasts only as long as you are on that particular page. You can go forward
and backward over your Ajax history all you want, but once you got to a different
page, either preceding or following, you lose your pathway. This does not mean that
if you get one of the intermediate URIs either through bookmarks, links, manually
typing, etc that it will not return that particular page. It will. But the tracking
of the entries in your browser history will be lost. 
&lt;/p&gt;
&lt;p&gt;
This also means that if the user modifies the URI manuallyto change what is&amp;nbsp;in
the has,&amp;nbsp;it will lose that history since it considers you having gone to a new
page.
&lt;/p&gt;
&lt;h3&gt;What if I need to keep a perfect snapshot of the page itself? 
&lt;/h3&gt;
&lt;p&gt;
If that is the case then you are going to need to look at a different way to store/retrieve
the data. You will probably need to store each page, as it appears, into the database
and then recall it from there. Do NOT store it in the History Points&amp;nbsp;Remember,
what is stored in the History Points must be tiny!
&lt;/p&gt;
&lt;h3&gt;Why does Opera NOT WORK???
&lt;/h3&gt;
&lt;p&gt;
&lt;a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx"&gt;http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx&lt;/a&gt;&amp;nbsp;(thanks
to Tomi for discovering this issue)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=2a008128-730b-4dd5-9cfa-e336a0b0a568" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,2a008128-730b-4dd5-9cfa-e336a0b0a568.aspx</comments>
      <category>Ajax</category>
      <category>Asp.Net</category>
      <category>c#</category>
      <category>Coding Tricks</category>
      <category>VB.Net</category>
    </item>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Part 1 - <a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"><font color="#5c80b1">Introduction</font></a><br />
Part 2 - <a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx"><font color="#5c80b1">Basic
Example</font></a><br />
Part 3 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx"><font color="#5c80b1">Complex
Example</font></a><br />
Part 4 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx"><font color="#5c80b1">Final
Notes</font></a><br />
Bonus - <a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"><font color="#5c80b1">Ajax
History and the Memento Pattern</font></a><br />
Extra Bonus - <a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx"><font color="#5c80b1">Issues
with Opera</font></a></p>
        <p>
Handling Ajax history has been a critical issue since Ajax first started. With the
advent of .net 3.5 the ability to easily deal with that is rolled into the code. This
is part 2, here we will look at a simple example of handling Ajax history to give
a basic understanding of the process. If you have not read <a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx">Part
1</a>, I suggest you do that now. Part 3 will expand on handling Ajax history when
the data is more complex.<br />
For simplicity sake we are only going to look at an example of very, very basic history.
We are going to look at a page that displays changes made to the time.
</p>
        <p>
A basic assumption is that you are fairly familiar with Ajax (<a href="http://ajax.asp.net">http://ajax.asp.net</a>).
We are going to be using the ScriptManager (of course) and an UpdatePanel. 
<br />
Our basic page looks like this
</p>
        <p>
&lt;%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxHistory.aspx.cs" Inherits="AjaxHistory"
%&gt;
</p>
        <p>
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>"&gt;
</p>
        <p>
&lt;html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"&gt;<br />
&lt;head runat="server"&gt;<br />
    &lt;title&gt;&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
    &lt;form id="form1" runat="server"&gt;<br />
    &lt;asp:ScriptManager runat="server" ID="sm1" EnablePartialRendering="true"
/&gt;<br />
    &lt;div&gt;<br />
        &lt;asp:UpdatePanel runat="server" ID="upME"&gt;<br />
            &lt;ContentTemplate&gt;<br />
               
&lt;asp:Button runat="server" ID="uxChangeTime" 
<br />
                   
OnClick="uxChangeTime_Click" Text="-- change:" /&gt;<br />
               
&lt;asp:Label runat="server" ID="lblTime" /&gt;<br />
            &lt;/ContentTemplate&gt;<br />
            &lt;Triggers&gt;<br />
               
&lt;asp:AsyncPostBackTrigger ControlID="uxChangeTime"<br />
                    
EventName="Click" /&gt;<br />
            &lt;/Triggers&gt;<br />
        &lt;/asp:UpdatePanel&gt;<br />
    &lt;/div&gt;<br />
    &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;
</p>
        <p>
The codebehind sets the label text to be the current date/time on every click:
</p>
        <p>
(c# code)<br />
protected void uxChangeTime_Click(object sender, EventArgs e)<br />
{<br />
    string _currentDateTime = DateTime.Now.ToString("F");<br />
    lblTime.Text = _currentDateTime;<br />
}
</p>
        <p>
(vb code)<br />
Protected Sub uxChangeTime_Click(ByVal sender As Object, &amp;_<br />
  ByVal e As System.EventArgs) Handles uxChangeTime.Click<br />
    Dim _currentDateTime As String = DateTime.Now.ToString("F")<br />
    lblTime.Text = _currentDateTime<br />
End Sub
</p>
        <p>
As you can see this is fairly straightforward. Clicking on the button displays the
current DateTime in the label. However, there is no history. Clicking back will not
display the last DateTime displayed but either be grayed out (if this was the first
page loaded) or take you back to the page before this one.
</p>
        <p>
To enable history is very, very simple in 3.5
</p>
        <ol>
          <li>
modify the ScriptManager, setting a property or two and registering an event (Navigate)
for the ScriptManager 
</li>
          <li>
modify the Click handler to notify the ScriptManager to record a History Point 
</li>
          <li>
handle the event called by the ScriptManager to rollback, when required, the page</li>
        </ol>
        <h3>Step 1: Modify the ScriptManager
</h3>
        <p>
The modifications are very simple - set EnableHistory equal to true and specify what
should handle the Navigate event. You can also specify if you want the HistoryState
to be 'secure' by setting EnableSecurityHistoryState equal to true, but this is optional.
</p>
        <p>
Your ScriptManager should now look like this:
</p>
        <p>
&lt;asp:ScriptManager runat="server" ID="sm1"<br />
     <strong><font color="#ff0000">EnableHistory="true" OnNavigate="sm1_Navigate"<br />
     EnableSecureHistoryState="true"</font></strong> /&gt;
</p>
        <h3>Step 2: Add an AsyncPostBackTrigger for the Navigate event of the ScriptManager
</h3>
        <p>
&lt;asp:UpdatePanel ...&gt;<br />
    ...<br />
    &lt;Triggers&gt;<br />
         &lt;asp:AsyncPostBackTrigger ControlID="uxChangeTime"<br />
                    
EventName="Click" /&gt;<br />
         <font color="#ff0000">&lt;asp:AsyncPostBackTrigger
ControlID="sm1" EventName="Navigate" /&gt;<br /></font>    &lt;/Triggers&gt;<br />
&lt;/asp:UpdatePanel&gt;
</p>
        <h4>Step 3: Modify the Click handler (or whatever event it is that would trigger a
HistoryPoint to be recorded
</h4>
        <p>
What you are doing here is notifying the ScriptManager what information to store as
a HistoryPoint by calling its AddHistoryPoint method. There are three possible overloads
and we will look at the other two next blog, but for now we will use one of the simplest,
a single key/value string pair to store the current DateTime with the key "myTime":
</p>
        <p>
(c# code)<br />
protected void uxChangeTime_Click(object sender, EventArgs e)<br />
{<br />
    string _currentDateTime = DateTime.Now.ToString("F");<br />
    lblTime.Text = _currentDateTime;<br />
    <strong><font color="#ff0000">ScriptManager.GetCurrent(this).AddHistoryPoint("myTime",
_currentDateTime);<br /></font></strong>}
</p>
        <p>
(vb code)<br />
Protected Sub uxChangeTime_Click(ByVal sender As Object, &amp;_<br />
  ByVal e As System.EventArgs) Handles uxChangeTime.Click<br />
    Dim _currentDateTime As String = DateTime.Now.ToString("F")<br />
    lblTime.Text = _currentDateTime<br />
    <strong><font color="#ff0000">ScriptManager.GetCurrent(Me).AddHistoryPoint("myTime",
_currentDateTime)<br /></font></strong>End Sub
</p>
        <h4>Step 4: handle the ScriptManager Navigate event
</h4>
        <p>
In this event we retrive the State property of the HistoryEventArgs and use that to
set the page to be what we want it to be. In this very simple example we will use
it to set the value of the label to be the DateTime that that particular page displayed:
</p>
        <p>
(c# code)<br />
protected void sm1_Navigate(object sender, HistoryEventArgs e)<br />
{<br />
    string _historyValue = e.State["myTime"];<br />
    if (_historyValue != null)<br />
    {<br />
        lblTime.Text = _historyValue;<br />
    }<br />
}
</p>
        <p>
(vb code)<br />
Protected Sub sm1_Navigate(ByVal sender As Object, &amp;_<br />
  ByVal e As System.HistoryEventArgs) Handles sm1.Navigate<br />
    Dim _historyValue As String = e.State["myTime"]<br />
    if(_historyValue &lt;&gt; Nothing)<br />
    {<br />
       lblTime.Text = _historyValue<br />
    }<br />
End Sub
</p>
        <p>
Voila! We now have a functional Ajax page with history. Try it!
</p>
        <p>
What has happened is that we are using History Points. When we click the button it
determines the current DateTime, displays it, and stores it as a history point. When
we click the "Back" button it retrieves the previous history point (which was the
current DateTime in string format) and displays that (see chart below).
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/clickbackdisplay.gif" border="0" />
        </p>
        <p>
Next blog: a look at more intensive use of History Points...<br />
btw, for prep, take a looksee at my blog on the Memento pattern and Ajax history to
understand my basic approach: <a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx">http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx</a></p>
        <img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0" />
      </body>
      <title>Ajax History - a how to - Part 2 - a basic example</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx</link>
      <pubDate>Wed, 01 Jul 2009 14:45:56 GMT</pubDate>
      <description>&lt;p&gt;
Part 1 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"&gt;&lt;font color=#5c80b1&gt;Introduction&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 2 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx"&gt;&lt;font color=#5c80b1&gt;Basic
Example&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 3 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx"&gt;&lt;font color=#5c80b1&gt;Complex
Example&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 4 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx"&gt;&lt;font color=#5c80b1&gt;Final
Notes&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Bonus - &lt;a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"&gt;&lt;font color=#5c80b1&gt;Ajax
History and the Memento Pattern&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Extra Bonus - &lt;a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx"&gt;&lt;font color=#5c80b1&gt;Issues
with Opera&lt;/font&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Handling Ajax history has been a critical issue since Ajax first started. With the
advent of .net 3.5 the ability to easily deal with that is rolled into the code. This
is part 2, here we will look at a simple example of handling Ajax history to give
a basic understanding of the process. If you have not read &lt;a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"&gt;Part
1&lt;/a&gt;, I suggest you do that now. Part 3 will expand on handling Ajax history when
the data is more complex.&lt;br&gt;
For simplicity sake we are only going to look at an example of very, very basic history.
We are going to look at a page that displays changes made to the time.
&lt;/p&gt;
&lt;p&gt;
A basic assumption is that you are fairly familiar with Ajax (&lt;a href="http://ajax.asp.net"&gt;http://ajax.asp.net&lt;/a&gt;).
We are going to be using the ScriptManager (of course) and an UpdatePanel. 
&lt;br&gt;
Our basic page looks like this
&lt;/p&gt;
&lt;p&gt;
&amp;lt;%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxHistory.aspx.cs" Inherits="AjaxHistory"
%&amp;gt;
&lt;/p&gt;
&lt;p&gt;
&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "&lt;a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&lt;/a&gt;"&amp;gt;
&lt;/p&gt;
&lt;p&gt;
&amp;lt;html xmlns="&lt;a href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/a&gt;"&amp;gt;&lt;br&gt;
&amp;lt;head runat="server"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br&gt;
&amp;lt;/head&amp;gt;&lt;br&gt;
&amp;lt;body&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;form id="form1" runat="server"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:ScriptManager runat="server" ID="sm1" EnablePartialRendering="true"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:UpdatePanel runat="server" ID="upME"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ContentTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:Button runat="server" ID="uxChangeTime" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
OnClick="uxChangeTime_Click" Text="-- change:" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:Label runat="server" ID="lblTime" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ContentTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Triggers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:AsyncPostBackTrigger ControlID="uxChangeTime"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
EventName="Click" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Triggers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:UpdatePanel&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/form&amp;gt;&lt;br&gt;
&amp;lt;/body&amp;gt;&lt;br&gt;
&amp;lt;/html&amp;gt;
&lt;/p&gt;
&lt;p&gt;
The codebehind sets the label text to be the current date/time on every click:
&lt;/p&gt;
&lt;p&gt;
(c# code)&lt;br&gt;
protected void uxChangeTime_Click(object sender, EventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string _currentDateTime = DateTime.Now.ToString("F");&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; lblTime.Text = _currentDateTime;&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
(vb code)&lt;br&gt;
Protected Sub uxChangeTime_Click(ByVal sender As Object, &amp;amp;_&lt;br&gt;
&amp;nbsp; ByVal e As System.EventArgs) Handles uxChangeTime.Click&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _currentDateTime As String = DateTime.Now.ToString("F")&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; lblTime.Text = _currentDateTime&lt;br&gt;
End Sub
&lt;/p&gt;
&lt;p&gt;
As you can see this is fairly straightforward. Clicking on the button displays the
current DateTime in the label. However, there is no history. Clicking back will not
display the last DateTime displayed but either be grayed out (if this was the first
page loaded) or take you back to the page before this one.
&lt;/p&gt;
&lt;p&gt;
To enable history is very, very simple in 3.5
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
modify the ScriptManager, setting a property or two and registering an event (Navigate)
for the ScriptManager 
&lt;li&gt;
modify the Click handler to notify the ScriptManager to record a History Point 
&lt;li&gt;
handle the event called by the ScriptManager to rollback, when required, the page&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Step 1: Modify the ScriptManager
&lt;/h3&gt;
&lt;p&gt;
The modifications are very simple - set EnableHistory equal to true and specify what
should handle the Navigate event. You can also specify if you want the HistoryState
to be 'secure' by setting EnableSecurityHistoryState equal to true, but this is optional.
&lt;/p&gt;
&lt;p&gt;
Your ScriptManager should now look like this:
&lt;/p&gt;
&lt;p&gt;
&amp;lt;asp:ScriptManager runat="server" ID="sm1"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;font color=#ff0000&gt;EnableHistory="true" OnNavigate="sm1_Navigate"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EnableSecureHistoryState="true"&lt;/font&gt;&lt;/strong&gt; /&amp;gt;
&lt;/p&gt;
&lt;h3&gt;Step 2: Add an AsyncPostBackTrigger for the Navigate event of the ScriptManager
&lt;/h3&gt;
&lt;p&gt;
&amp;lt;asp:UpdatePanel ...&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Triggers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:AsyncPostBackTrigger ControlID="uxChangeTime"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
EventName="Click" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#ff0000&gt;&amp;lt;asp:AsyncPostBackTrigger
ControlID="sm1" EventName="Navigate" /&amp;gt;&lt;br&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Triggers&amp;gt;&lt;br&gt;
&amp;lt;/asp:UpdatePanel&amp;gt;
&lt;/p&gt;
&lt;h4&gt;Step 3: Modify the Click handler (or whatever event it is that would trigger a
HistoryPoint to be recorded
&lt;/h4&gt;
&lt;p&gt;
What you are doing here is notifying the ScriptManager what information to store as
a HistoryPoint by calling its AddHistoryPoint method. There are three possible overloads
and we will look at the other two next blog, but for now we will use one of the simplest,
a single key/value string pair to store the current DateTime with the key "myTime":
&lt;/p&gt;
&lt;p&gt;
(c# code)&lt;br&gt;
protected void uxChangeTime_Click(object sender, EventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string _currentDateTime = DateTime.Now.ToString("F");&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; lblTime.Text = _currentDateTime;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;font color=#ff0000&gt;ScriptManager.GetCurrent(this).AddHistoryPoint("myTime",
_currentDateTime);&lt;br&gt;
&lt;/font&gt;&lt;/strong&gt;}
&lt;/p&gt;
&lt;p&gt;
(vb code)&lt;br&gt;
Protected Sub uxChangeTime_Click(ByVal sender As Object, &amp;amp;_&lt;br&gt;
&amp;nbsp; ByVal e As System.EventArgs) Handles uxChangeTime.Click&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _currentDateTime As String = DateTime.Now.ToString("F")&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; lblTime.Text = _currentDateTime&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;font color=#ff0000&gt;ScriptManager.GetCurrent(Me).AddHistoryPoint("myTime",
_currentDateTime)&lt;br&gt;
&lt;/font&gt;&lt;/strong&gt;End Sub
&lt;/p&gt;
&lt;h4&gt;Step 4: handle the ScriptManager Navigate event
&lt;/h4&gt;
&lt;p&gt;
In this event we retrive the State property of the HistoryEventArgs and use that to
set the page to be what we want it to be. In this very simple example we will use
it to set the value of the label to be the DateTime that that particular page displayed:
&lt;/p&gt;
&lt;p&gt;
(c# code)&lt;br&gt;
protected void sm1_Navigate(object sender, HistoryEventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string _historyValue = e.State["myTime"];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_historyValue != null)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblTime.Text = _historyValue;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
(vb code)&lt;br&gt;
Protected Sub sm1_Navigate(ByVal sender As Object, &amp;amp;_&lt;br&gt;
&amp;nbsp; ByVal e As System.HistoryEventArgs) Handles sm1.Navigate&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _historyValue As String = e.State["myTime"]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if(_historyValue &amp;lt;&amp;gt; Nothing)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblTime.Text = _historyValue&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
End Sub
&lt;/p&gt;
&lt;p&gt;
Voila! We now have a functional Ajax page with history. Try it!
&lt;/p&gt;
&lt;p&gt;
What has happened is that we are using History Points. When we click the button it
determines the current DateTime, displays it, and stores it as a history point. When
we click the "Back" button it retrieves the previous history point (which was the
current DateTime in string format) and displays that (see chart below).
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/clickbackdisplay.gif" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Next blog: a look at more intensive use of History Points...&lt;br&gt;
btw, for prep, take a looksee at my blog on the Memento pattern and Ajax history to
understand my basic approach:&amp;nbsp;&lt;a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"&gt;http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,b4b6d1b6-78ee-4163-afe9-29a9fb47a6d0.aspx</comments>
      <category>Ajax</category>
      <category>Asp.Net</category>
      <category>c#</category>
      <category>Coding Tricks</category>
      <category>VB.Net</category>
    </item>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=d2c8095a-c083-4c09-ac19-6df6edf8a627</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,d2c8095a-c083-4c09-ac19-6df6edf8a627.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,d2c8095a-c083-4c09-ac19-6df6edf8a627.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=d2c8095a-c083-4c09-ac19-6df6edf8a627</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Part 1 - <a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"><font color="#5c80b1">Introduction</font></a><br />
Part 2 - <a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx"><font color="#5c80b1">Basic
Example</font></a><br />
Part 3 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx"><font color="#5c80b1">Complex
Example</font></a><br />
Part 4 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx"><font color="#5c80b1">Final
Notes</font></a><br />
Bonus - <a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"><font color="#5c80b1">Ajax
History and the Memento Pattern</font></a><br />
Extra Bonus - <a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx"><font color="#5c80b1">Issues
with Opera</font></a></p>
        <p>
One of the most exciting prospects with .net 3.5 is the ability to handle Ajax History. 
</p>
        <p>
Ajax, for those of you who may be only vaguely familiar, is a way to do partial postbacks
of web pages. This allows you to modify only a portion of the screen rather than updating
the entire transaction. This increases the potential speed exponentially. One form
are CallBacks, another used by the UpdatePanel is a full PostBack but only a redrawing
of the appropriate sections of the page.
</p>
        <p>
However, there are three main problems with Ajax when using controls like the UpdatePanel:
</p>
        <ol>
          <li>
Hitting the “Back” button loads the page that was loaded BEFORE the ajax page 
</li>
          <li>
Refreshing the page has the effect of losing whatever Ajax calls have been made (ie
the page itself is reloaded from the start). 
</li>
          <li>
There is no effective method to ‘link’ to the page resulting from ajax calls. All
links lose any Ajax calls because the URL does not display the necessary information
to recreate the page at the appropriate place.</li>
        </ol>
        <p>
All of these can be resolved (as we shall see) by using Ajax History. 
</p>
        <p>
This first blog entry will lay out the problems in greater detail and the general
means by which Ajax History resolves them. Later entries will go more into detail
on how to do Ajax History (yes, there is some additional work, but not very much).
</p>
        <h3>Hitting the “Back” button loads the page that was loaded BEFORE the ajax page
</h3>
        <p>
The issue here is caused by two factors:
</p>
        <ol>
          <li>
The "Back" button loads the last entry in url history 
</li>
          <li>
Ajax does not automatically change the url history</li>
        </ol>
        <p>
An example of what I am talking about can be seen in my (non-artistic) image below. 
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/PostbackVsCallBack.jpg" border="0" />
        </p>
        <p>
Hitting the "Back" button after doing regular Postbacks will take you to the most
recent page of information. However, hitting the "Back" button after doing CallBacks
takes you all the way back to the page that was loaded BEFORE you even got to the
Ajax page.
</p>
        <p>
The reason for this lies in the way that the href property of the Html Document Object
Model is handled. By default whenever a full PostBack occurs or a modification to
the hash in the URI (such as an internal link), the URI of the new entry is stored
in the location history. This is handled by the browser behind the scenes and has
been since the early days. However, since Ajax calls are not full PostBacks the browser
mechanism does not, by default, record their entry.
</p>
        <p>
To get around this, a rather ingenious method is used. Because modifications to the
URI’s hash portion is included in the history but DOES NOT require full PostBack (think
internal anchor links) .net 3.5 writes to the hash portion of the page to trigger
the entry being recorded, by the browser, in the href history. Pretty slick, hunh?
</p>
        <p>
For those of you unfamiliar with the hash concept of the URI, consider the following
quick example:
</p>
        <p>
&lt;html&gt;<br />
&lt;head&gt;&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;a name=’Up’&gt;&lt;/a&gt;<br />
&lt;a href=’upsidedown.html#Down’&gt;Go Down&lt;/a&gt;<br />
&lt;p&gt;&amp;nbsp;&lt;/p&gt;<br />
&lt;a name=’Down’&gt;&lt;/a&gt;<br />
&lt;a href=’upsidedown.html#Up’&gt;Go Up&lt;/a&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;
</p>
        <p>
I have posted this basic page to my site. Note that there are anchor tags (&lt;a…)
that have names and others that have a hash sign (#) in them that refer to that name.
These are commonly used to enable users to just to a particular portion of the page
without having to scroll and are known as Internal Links (because they link to an
internal portion of the page and not to an external page).<br /><br />
When the page first loads you can see that the URI is simply <a href="http://www.myfriedmind.com/updown.html">http://www.myfriedmind.com/updown.html</a>.
There is one link visible (the other would be visible if you scrolled but I shrunk
the browser window to give an idea of what internal links are generally used for. 
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/updownStart.JPG" border="0" />
        </p>
        <p>
Once the link is clicked it moves the page down to where the “named” anchor is. In
other words, clicking on the anchor tag that references #Down (&lt;a href=’upsidedown.html#Down’&gt;Go
Down&lt;/a&gt;) moves the page to the anchor that contains the name that matches the
one after the hash sign – so you are moved WITHIN the page (to &lt;a name=’Down’&gt;&lt;/a&gt;).
This is very important – note that the URI has changed, it is now showing the hash.
Also critical to note is that THE PAGE DID NOT POSTBACK!
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/updownDown.JPG" border="0" />
        </p>
        <p>
Clicking on the link that has the hash entry for Up (&lt;a href=’upsidedown.html#Up’&gt;Go
Up&lt;/a&gt;) results in moving to the anchor tag that has the name (Up) that matches
what was after the hash mark. Again, the URI is updated to a new hash display and
THE PAGE DID NOT POSTBACK!!!
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/updownUp.JPG" border="0" />
        </p>
        <p>
It is critical that you understand that when this takes place the browser records
the change in its href history. In other words, modifications to the hash are RECORDED
in the browser’s href history. Thus hitting the “Back” button means that we move back
to the previous entry, which is NOT <a href="http://www.myfriedmind.com/updown.html">http://www.myfriedmind.com/updown.html</a>,
but <a href="http://www.myfriedmind.com/updown.html#Down">http://www.myfriedmind.com/updown.html#Down</a> (see
below)
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/updownDown.JPG" />
        </p>
        <p>
Thus the elegant solution – to store Ajax postbacks, record the entries in the hash
of the URI (like you are doing an internal link) and the updated URI will be recorded
in the browser history for you. Any clicks on the “Back” button will load the previous
entry. See the basic example below. Note that the change after CallBack to the URL
(adding a hash entry).
</p>
        <p>
          <img src="http://www.myfriedmind.com/techBlog/content/binary/AjaxHistoryCallbacks.jpg" border="0" />
        </p>
        <p>
I must note here that the adding to the hash is not automatic. You do need to do code
but very, very little. Your code mostly deals with how to effectively package the
info and unpackage when required. If you are curious take a looksee at my (fascinating)
blog on how this is similar to the Memento pattern -&gt;  <a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx">http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx</a>.
</p>
        <p>
Once you grasp this concept – that the Ajax History is stored in the URI’s hash, the
solutions to both of problems #2 and #3 (page refresh and linking) are resolved. 
</p>
        <ul>
          <li>
Refreshing  the page refreshes the URI, INCLUDING the hash. Thus the page that
gets returned is the page that has had the Ajax modifications done 
</li>
          <li>
Sending a link to this page, INCLUDES the URI’s hash, and thus the page will be able
to return the point in its Ajax modifications that a person wants</li>
        </ul>
        <p>
There are a number of very useful examples of how this is used today (Ajax History
is not new with 3.5 but it DOES make it a whole lot simpler). The most commonly used
are mapping websites. One can hunt around (using Ajax) until one gets to the exact
display one desires and then save/send/whatever that display. Without the hash entry
one would always end up at the very beginning and the desired display would be lost.
I can use bing to zoom into the street view of Dunn Bros (the BEST coffee) by my old
alma mater in Saint Paul and shoot that url to a friend.( shortened for display - <a href="http://www.bing.com/maps/#JnE9eX...zMTI1">http://www.bing.com/maps/#JnE9eX...zMTI1</a>)
</p>
        <p>
But this is not limited to mapping sites. Imagine that you have a Ajax based site
that enables users to filter/sort/etc on a GridView display customer accounts. “Ah
ha,” says the manager (they say things like that when no one is listening) “this is
precisely the display I am looking for. I will just save it into my favorites. And
I will also email it to the big boss.” Without the hash they would be exceedingly
frustrated as would the big boss. With proper Ajax history coding the sun shines,
the wind blows, and gas prices drop. Everyone is happy.
</p>
        <p>
;)
</p>
        <p>
Next blog: What exactly is involved in doing Ajax History, the concepts….<br /></p>
        <img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=d2c8095a-c083-4c09-ac19-6df6edf8a627" />
      </body>
      <title>Ajax History - a how to - Part 1</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,d2c8095a-c083-4c09-ac19-6df6edf8a627.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx</link>
      <pubDate>Tue, 30 Jun 2009 16:03:29 GMT</pubDate>
      <description>&lt;p&gt;
Part 1 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"&gt;&lt;font color=#5c80b1&gt;Introduction&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 2 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx"&gt;&lt;font color=#5c80b1&gt;Basic
Example&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 3 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx"&gt;&lt;font color=#5c80b1&gt;Complex
Example&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 4 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx"&gt;&lt;font color=#5c80b1&gt;Final
Notes&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Bonus - &lt;a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"&gt;&lt;font color=#5c80b1&gt;Ajax
History and the Memento Pattern&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Extra Bonus - &lt;a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx"&gt;&lt;font color=#5c80b1&gt;Issues
with Opera&lt;/font&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
One of the most exciting prospects with .net 3.5 is the ability to handle Ajax History. 
&lt;/p&gt;
&lt;p&gt;
Ajax, for those of you who may be only vaguely familiar, is a way to do partial postbacks
of web pages. This allows you to modify only a portion of the screen rather than updating
the entire transaction. This increases the potential speed exponentially. One form
are CallBacks, another used by the UpdatePanel is a full PostBack but only a redrawing
of the appropriate sections of the page.
&lt;/p&gt;
&lt;p&gt;
However, there are three main problems with Ajax when using controls like the UpdatePanel:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Hitting the “Back” button loads the page that was loaded BEFORE the ajax page 
&lt;li&gt;
Refreshing the page has the effect of losing whatever Ajax calls have been made (ie
the page itself is reloaded from the start). 
&lt;li&gt;
There is no effective method to ‘link’ to the page resulting from ajax calls. All
links lose any Ajax calls because the URL does not display the necessary information
to recreate the page at the appropriate place.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
All of these can be resolved (as we shall see) by using Ajax History. 
&lt;/p&gt;
&lt;p&gt;
This first blog entry will lay out the problems in greater detail and the general
means by which Ajax History resolves them. Later entries will go more into detail
on how to do Ajax History (yes, there is some additional work, but not very much).
&lt;/p&gt;
&lt;h3&gt;Hitting the “Back” button loads the page that was loaded BEFORE the ajax page
&lt;/h3&gt;
&lt;p&gt;
The issue here is caused by two factors:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The "Back" button loads the last entry in url history 
&lt;li&gt;
Ajax does not automatically&amp;nbsp;change the url history&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
An example of what I am talking about can be seen in my (non-artistic) image below. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/PostbackVsCallBack.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Hitting the "Back" button after doing regular Postbacks will take you to the most
recent page of information. However, hitting the "Back" button after doing CallBacks
takes you all the way back to the page that was loaded BEFORE you even got to the
Ajax page.
&lt;/p&gt;
&lt;p&gt;
The reason for this lies in the way that the href property of the Html Document Object
Model is handled. By default whenever a full PostBack occurs or a modification to
the hash in the URI (such as an internal link), the URI of the new entry is stored
in the location history. This is handled by the browser behind the scenes and has
been since the early days. However, since Ajax calls are not full PostBacks the browser
mechanism does not, by default, record their entry.
&lt;/p&gt;
&lt;p&gt;
To get around this, a rather ingenious method is used. Because modifications to the
URI’s hash portion is included in the history but DOES NOT require full PostBack (think
internal anchor links) .net 3.5 writes to the hash portion of the page to trigger
the entry being recorded, by the browser, in the href history. Pretty slick, hunh?
&lt;/p&gt;
&lt;p&gt;
For those of you unfamiliar with the hash concept of the URI, consider the following
quick example:
&lt;/p&gt;
&lt;p&gt;
&amp;lt;html&amp;gt;&lt;br&gt;
&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&lt;br&gt;
&amp;lt;body&amp;gt;&lt;br&gt;
&amp;lt;a name=’Up’&amp;gt;&amp;lt;/a&amp;gt;&lt;br&gt;
&amp;lt;a href=’upsidedown.html#Down’&amp;gt;Go Down&amp;lt;/a&amp;gt;&lt;br&gt;
&amp;lt;p&amp;gt;&amp;amp;nbsp;&amp;lt;/p&amp;gt;&lt;br&gt;
&amp;lt;a name=’Down’&amp;gt;&amp;lt;/a&amp;gt;&lt;br&gt;
&amp;lt;a href=’upsidedown.html#Up’&amp;gt;Go Up&amp;lt;/a&amp;gt;&lt;br&gt;
&amp;lt;/body&amp;gt;&lt;br&gt;
&amp;lt;/html&amp;gt;
&lt;/p&gt;
&lt;p&gt;
I have posted this basic page to my site. Note that there are anchor tags (&amp;lt;a…)
that have names and others that have a hash sign (#) in them that refer to that name.
These are commonly used to enable users to just to a particular portion of the page
without having to scroll and are known as Internal Links (because they link to an
internal portion of the page and not to an external page).&lt;br&gt;
&lt;br&gt;
When the page first loads you can see that the URI is simply &lt;a href="http://www.myfriedmind.com/updown.html"&gt;http://www.myfriedmind.com/updown.html&lt;/a&gt;.
There is one link visible (the other would be visible if you scrolled but I shrunk
the browser window to give an idea of what internal links are generally used for. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/updownStart.JPG" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Once the link is clicked it moves the page down to where the “named” anchor is. In
other words, clicking on the anchor tag that references #Down (&amp;lt;a href=’upsidedown.html#Down’&amp;gt;Go
Down&amp;lt;/a&amp;gt;) moves the page to the anchor that contains the name that matches the
one after the hash sign – so you are moved WITHIN the page (to &amp;lt;a name=’Down’&amp;gt;&amp;lt;/a&amp;gt;).
This is very important – note that the URI has changed, it is now showing the hash.
Also critical to note is that THE PAGE DID NOT POSTBACK!
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/updownDown.JPG" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Clicking on the link that has the hash entry for Up (&amp;lt;a href=’upsidedown.html#Up’&amp;gt;Go
Up&amp;lt;/a&amp;gt;) results in moving to the anchor tag that has the name (Up) that matches
what was after the hash mark. Again, the URI is updated to a new hash display and
THE PAGE DID NOT POSTBACK!!!
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/updownUp.JPG" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
It is critical that you understand that when this takes place the browser records
the change in its href history. In other words, modifications to the hash are RECORDED
in the browser’s href history. Thus hitting the “Back” button means that we move back
to the previous entry, which is NOT &lt;a href="http://www.myfriedmind.com/updown.html"&gt;http://www.myfriedmind.com/updown.html&lt;/a&gt;,
but &lt;a href="http://www.myfriedmind.com/updown.html#Down"&gt;http://www.myfriedmind.com/updown.html#Down&lt;/a&gt; (see
below)
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/updownDown.JPG"&gt;
&lt;/p&gt;
&lt;p&gt;
Thus the elegant solution – to store Ajax postbacks, record the entries in the hash
of the URI (like you are doing an internal link) and the updated URI will be recorded
in the browser history for you. Any clicks on the “Back” button will load the previous
entry. See the basic example below. Note that the change after CallBack to the URL
(adding a hash entry).
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.myfriedmind.com/techBlog/content/binary/AjaxHistoryCallbacks.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
I must note here that the adding to the hash is not automatic. You do need to do code
but very, very little. Your code mostly deals with how to effectively package the
info and unpackage when required. If you are curious take a looksee at my (fascinating)
blog on how this is similar to the Memento pattern -&amp;gt; &amp;nbsp;&lt;a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"&gt;http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Once you grasp this concept – that the Ajax History is stored in the URI’s hash, the
solutions to both of problems #2 and #3 (page refresh and linking) are resolved. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Refreshing&amp;nbsp; the page refreshes the URI, INCLUDING the hash. Thus the page that
gets returned is the page that has had the Ajax modifications done 
&lt;li&gt;
Sending a link to this page, INCLUDES the URI’s hash, and thus the page will be able
to return the point in its Ajax modifications that a person wants&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There are a number of very useful examples of how&amp;nbsp;this is used today (Ajax History
is not new with 3.5 but it DOES make it a whole lot simpler). The most commonly used
are mapping websites. One can hunt around (using Ajax) until one gets to the exact
display one desires and then save/send/whatever that display. Without the hash entry
one would always end up at the very beginning and the desired display would be lost.
I can use bing to zoom into the street view of Dunn Bros (the BEST coffee) by my old
alma mater in Saint Paul and shoot that url to a friend.( shortened for display - &lt;a href="http://www.bing.com/maps/#JnE9eX...zMTI1"&gt;http://www.bing.com/maps/#JnE9eX...zMTI1&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
But this is not limited to mapping sites. Imagine that you have a Ajax based site
that enables users to filter/sort/etc on a GridView display customer accounts. “Ah
ha,” says the manager (they say things like that when no one is listening) “this is
precisely the display I am looking for. I will just save it into my favorites. And
I will also email it to the big boss.” Without the hash they would be exceedingly
frustrated as would the big boss. With proper Ajax history coding the sun shines,
the wind blows, and gas prices drop. Everyone is happy.
&lt;/p&gt;
&lt;p&gt;
;)
&lt;/p&gt;
&lt;p&gt;
Next blog: What exactly is involved in doing Ajax History, the concepts….&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=d2c8095a-c083-4c09-ac19-6df6edf8a627" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,d2c8095a-c083-4c09-ac19-6df6edf8a627.aspx</comments>
      <category>Ajax</category>
      <category>Asp.Net</category>
      <category>c#</category>
      <category>Coding Tricks</category>
      <category>VB.Net</category>
    </item>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=52f2adba-43f8-44ce-83ce-3312677761d6</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,52f2adba-43f8-44ce-83ce-3312677761d6.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,52f2adba-43f8-44ce-83ce-3312677761d6.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=52f2adba-43f8-44ce-83ce-3312677761d6</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
okay, I apologize. I promised to do this weeks ago and am only finally getting it
up. Hopefully it will be worth the wait...
</p>
        <p>
If you are planning on simply using a DDL (and not Cascading), look here -&gt; <a href="http://www.myfriedmind.com/techBlog/2009/06/04/DropDownListGridViewAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx">http://www.myfriedmind.com/techBlog/2009/06/04/DropDownListGridViewAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx</a></p>
        <p>
Note that this example uses a remote webservice (rather than a PageMethod) for the
CascadingDropDownList calls and I have not included them to simplify the amount of
code on this page, but they are fairly straightforward -&gt; <a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx">http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx</a></p>
        <p>
Sample DataObject (in c#)
</p>
        <p>
class MyObject<br />
{<br />
   public int ObjId { get; set; }<br />
   public string StateAbbreviation { get; set; }<br />
   public string ZipCode { get; set; }<br />
}
</p>
        <p>
Sample DataObject (in vb.net)
</p>
        <p>
Class MyObject<br />
   Public ObjId As Integer<br />
   Public StateAbbreviation As String<br />
   Public ZipCode As String<br />
End Class
</p>
        <p>
Entry on SampleGridView.aspx page (as simple as you can get it)
</p>
        <p>
&lt;asp:GridView runat="server" ID="lstMyData" DataKeyNames="ObjId"<br />
    AutoGenerateColumns="false" EnableViewState="true"<br />
    AutoGenerateEditButton="true"<br />
    OnRowDataBound="lstMyData_RowDataBound" &gt;<br />
    &lt;Columns&gt;<br />
        &lt;asp:TemplateField&gt;<br />
            &lt;ItemTemplate&gt;<br />
               
&lt;asp:Label runat="server" ID="lblState"     
<br />
                   
Text='&lt;%# Eval("StateAbbreviation") %&gt;' /&gt;<br />
            &lt;/ItemTemplate&gt;<br />
            &lt;EditItemTemplate&gt;<br />
               
&lt;asp:DropDownList runat="server" ID="uxState" /&gt;<br />
               
&lt;aKit:CascadingDropDown ID="ajxState" runat="server" 
<br />
                   
TargetControlID="uxState" Category="State" <br />
                   
ServiceMethod="GetStates" /&gt;<br />
            &lt;/EditItemTemplate&gt;<br />
        &lt;/asp:TemplateField&gt;<br />
        &lt;asp:TemplateField&gt;<br />
            &lt;ItemTemplate&gt;<br />
               
&lt;asp:Label runat="server" ID="lblZipCode"   
<br />
                  
Text='&lt;%# Eval("ZipCode") %&gt;' /&gt;<br />
            &lt;/ItemTemplate&gt;<br />
            &lt;EditItemTemplate&gt;<br />
               
&lt;asp:DropDownList runat="server" ID="uxZipCode" /&gt;<br />
               
&lt;aKit:CascadingDropDown ID="ajxZipCode" runat="server" 
<br />
                   
TargetControlID="uxZipCode" Category="ZipCode" 
<br />
                   
LoadingText="[Loading Zipcode...]"<br />
                   
ServicePath="WebServiceToReturnData.asmx" <br />
                   
ServiceMethod="GetZipCode" 
<br />
                 
ParentControlID="uxState" /&gt;<br />
            &lt;/EditItemTemplate&gt;<br />
        &lt;/asp:TemplateField&gt;<br />
    &lt;/Columns&gt;<br />
&lt;/asp:GridView&gt;
</p>
        <p>
Codebehind (in c#) SampleGridView.apx.cs (note this does NOT include the code to return
the values)
</p>
        <p>
protected void lstMyData_RowDataBound(object sender, 
<br />
        GridViewRowEventArgs e)<br />
{<br />
    // verify this is a DataRow, not a Header, Footer, etc...<br />
    if (e.Row.RowType == DataControlRowType.DataRow)<br />
    {<br />
        // in case you want to do something else
here....<br />
        
<br />
        // see if this is the Row used for Editing<br />
        if ((e.Row.RowState &amp; DataControlRowState.Edit)
!= 0)<br />
        {<br />
            // get the DataItem
that is bound 
<br />
            // and cast it
accordingly<br />
            MyObject _myObject
= (MyObject)e.Row.DataItem;<br /><br />
            // get the CascadingDropDowns<br />
            CascadingDropDown
_ajxState = 
<br />
               
(CascadingDropDown) e.Row.FindControl("ajxState");<br />
            CascadingDropDown
_ajxZipCode = 
<br />
               
(CascadingDropDown) e.Row.FindControl("ajxZipCode");<br /><br />
            // the data
is automatically updated via the Ajax,<br />
            // so we merely
need to select the item<br /><br />
            _ajxState.SelectedValue
= _myObject.StateAbbreviation<br />
            // _ajxState.ContextKey
= this can be set here if you are using it;<br /><br />
            _ajxZipCode.SelectedValue
= myObject.ZipCode;<br />
        }<br />
    }<br />
}
</p>
        <p>
Codebehind (in vb.net) SampleGridView.apx.cs (note this does NOT include the code
to return the values)
</p>
        <p>
Protected Sub lstMyData_RowDataBound(ByVal sender As Object, _<br />
    ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _<br />
    Handles lstMyData.RowDataBound<br />
    If e.Row.RowType = DataControlRowType.DataRow Then
</p>
        <p>
            ' in case you want
to do something else here....
</p>
        <p>
            ' see if this is
the Row used for Editing<br />
            If (e.Row.RowState
And DataControlRowState.Edit) &lt;&gt; 0 Then
</p>
        <p>
          <br />
               
' get the DataItem that is bound<br />
               
' and cast it accordingly<br />
               
Dim _myObject As MyObject = _<br />
                   
DirectCast(e.Row.DataItem, MyObject)
</p>
        <p>
               
' get the CascadingDropDowns<br />
               
Dim _ajxState As CascadingDropDown = _<br />
                   
DirectCast(e.Row.FindControl("ajxState"), CascadingDropDown)<br />
               
Dim _ajxZipcode As CascadingDropDown = _<br />
                   
DirectCast(e.Row.FindControl("ajxZipCode"), CascadingDropDown)
</p>
        <p>
               
' ddl population should be handled by the Ajax<br />
               
' ServiceMethod of the CascadingDropDown
</p>
        <p>
               
' select the appropriate item<br />
               
_ajxState.SelectedValue = _myObject.StateAbbreviation<br />
               
_ajxZipCode.SelectedValue = _myObject.ZipCode
</p>
        <p>
            End If<br />
     End If<br />
End Sub
</p>
        <img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=52f2adba-43f8-44ce-83ce-3312677761d6" />
      </body>
      <title>CascadingDropDownLists, GridViews, and Dynamically selecting the appropriate ListItem during Edit...</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,52f2adba-43f8-44ce-83ce-3312677761d6.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/06/22/CascadingDropDownListsGridViewsAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx</link>
      <pubDate>Mon, 22 Jun 2009 15:16:46 GMT</pubDate>
      <description>&lt;p&gt;
okay, I apologize. I promised to do this weeks ago and am only finally getting it
up. Hopefully it will be worth the wait...
&lt;/p&gt;
&lt;p&gt;
If you are planning on simply using a DDL (and not Cascading), look here -&amp;gt; &lt;a href="http://www.myfriedmind.com/techBlog/2009/06/04/DropDownListGridViewAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx"&gt;http://www.myfriedmind.com/techBlog/2009/06/04/DropDownListGridViewAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Note that this example uses a remote webservice (rather than a PageMethod) for the
CascadingDropDownList calls and I have not included them to simplify the amount of
code on this page, but they are fairly straightforward -&amp;gt; &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx"&gt;http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Sample DataObject (in c#)
&lt;/p&gt;
&lt;p&gt;
class MyObject&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp; public int ObjId { get; set; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; public string StateAbbreviation { get; set; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; public string ZipCode { get; set; }&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
Sample DataObject (in vb.net)
&lt;/p&gt;
&lt;p&gt;
Class MyObject&lt;br&gt;
&amp;nbsp;&amp;nbsp; Public ObjId As Integer&lt;br&gt;
&amp;nbsp;&amp;nbsp; Public StateAbbreviation As String&lt;br&gt;
&amp;nbsp;&amp;nbsp; Public ZipCode As String&lt;br&gt;
End Class
&lt;/p&gt;
&lt;p&gt;
Entry on SampleGridView.aspx page (as simple as you can get it)
&lt;/p&gt;
&lt;p&gt;
&amp;lt;asp:GridView runat="server" ID="lstMyData" DataKeyNames="ObjId"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; AutoGenerateColumns="false" EnableViewState="true"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; AutoGenerateEditButton="true"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; OnRowDataBound="lstMyData_RowDataBound" &amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Columns&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TemplateField&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:Label runat="server" ID="lblState"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Text='&amp;lt;%# Eval("StateAbbreviation") %&amp;gt;' /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;EditItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:DropDownList runat="server" ID="uxState" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;aKit:CascadingDropDown ID="ajxState" runat="server" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
TargetControlID="uxState" Category="State"&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ServiceMethod="GetStates" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/EditItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:TemplateField&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TemplateField&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:Label runat="server" ID="lblZipCode"&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Text='&amp;lt;%# Eval("ZipCode") %&amp;gt;' /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;EditItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:DropDownList runat="server" ID="uxZipCode" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;aKit:CascadingDropDown ID="ajxZipCode" runat="server" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
TargetControlID="uxZipCode" Category="ZipCode" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
LoadingText="[Loading Zipcode...]"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ServicePath="WebServiceToReturnData.asmx"&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ServiceMethod="GetZipCode" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ParentControlID="uxState" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/EditItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:TemplateField&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Columns&amp;gt;&lt;br&gt;
&amp;lt;/asp:GridView&amp;gt;
&lt;/p&gt;
&lt;p&gt;
Codebehind (in c#) SampleGridView.apx.cs (note this does NOT include the code to return
the values)
&lt;/p&gt;
&lt;p&gt;
protected void lstMyData_RowDataBound(object sender, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GridViewRowEventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // verify this is a DataRow, not a Header, Footer, etc...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e.Row.RowType == DataControlRowType.DataRow)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // in case you want to do something else
here....&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // see if this is the Row used for Editing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((e.Row.RowState &amp;amp; DataControlRowState.Edit)
!= 0)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the DataItem
that is bound 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and cast it
accordingly&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject _myObject
= (MyObject)e.Row.DataItem;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the CascadingDropDowns&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CascadingDropDown
_ajxState = 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
(CascadingDropDown) e.Row.FindControl("ajxState");&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CascadingDropDown
_ajxZipCode = 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
(CascadingDropDown) e.Row.FindControl("ajxZipCode");&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;the data
is&amp;nbsp;automatically updated via the Ajax,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;so we merely
need to select the item&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ajxState.SelectedValue
= _myObject.StateAbbreviation&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // _ajxState.ContextKey
= this can be set here if you are using it;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ajxZipCode.SelectedValue
= myObject.ZipCode;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
Codebehind (in vb.net) SampleGridView.apx.cs (note this does NOT include the code
to return the values)
&lt;/p&gt;
&lt;p&gt;
Protected Sub lstMyData_RowDataBound(ByVal sender As Object, _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Handles lstMyData.RowDataBound&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; If e.Row.RowType = DataControlRowType.DataRow Then
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' in case you want
to do something else here....
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' see if this is
the Row used for Editing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (e.Row.RowState
And DataControlRowState.Edit)&amp;nbsp;&amp;lt;&amp;gt; 0 Then
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' get the DataItem that is bound&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' and cast it accordingly&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Dim _myObject As MyObject = _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DirectCast(e.Row.DataItem, MyObject)
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' get the CascadingDropDowns&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Dim _ajxState As CascadingDropDown = _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DirectCast(e.Row.FindControl("ajxState"), CascadingDropDown)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Dim _ajxZipcode As CascadingDropDown = _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DirectCast(e.Row.FindControl("ajxZipCode"), CascadingDropDown)
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' ddl population should be handled by the Ajax&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' ServiceMethod of the CascadingDropDown
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' select the appropriate item&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_ajxState.SelectedValue = _myObject.StateAbbreviation&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_ajxZipCode.SelectedValue = _myObject.ZipCode
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br&gt;
End Sub
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=52f2adba-43f8-44ce-83ce-3312677761d6" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,52f2adba-43f8-44ce-83ce-3312677761d6.aspx</comments>
      <category>Ajax</category>
      <category>c#</category>
      <category>Coding Tricks</category>
      <category>VB.Net</category>
    </item>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=4e1f80c7-9cce-4a3f-82b2-24edb4d52f88</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,4e1f80c7-9cce-4a3f-82b2-24edb4d52f88.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,4e1f80c7-9cce-4a3f-82b2-24edb4d52f88.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=4e1f80c7-9cce-4a3f-82b2-24edb4d52f88</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">I have seen a number of questions regarding
how to specify what the selected ListItem is on a DropDownList used in an EditRow
of A GridView. So I thought it might make a good blog. 
<br /><br />
Note: for an example that uses Ajax, specifically the CascadingDropDown, look here <a href="http://www.myfriedmind.com/techBlog/2009/06/22/CascadingDropDownListsGridViewsAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx">http://www.myfriedmind.com/techBlog/2009/06/22/CascadingDropDownListsGridViewsAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx</a>.<br /><br />
Basically what people are trying to do is use a DropDownList as one of the input controls
on a DataRow when edit is selected for that Row. This, of course, limits what people
can enter which is a good thing. For example, what if you wanted to create a DropDownList
that specified which state someone was from, or what time (using 15-minute increments)?<br /><br />
Creating the DropDownList is fairly straightforward, as is populating it. What is
confusing people is how to specify what the selected value is. To do that you need
to handle the OnRowDataBound event, snag the DataItem and select the ListItem that
matches the appropriate property. Like so:<br /><br />
Sample DataObject (in c#)<br /><br />
class MyObject<br />
{<br />
   public int ObjId {get; set;}<br />
   public string StateAbbreviation {get; set; }<br />
}<br /><br />
Sample DataObject (in vb.net)<br /><br />
Class MyObject<br />
    Public ObjId As Integer<br />
    Public StateAbbreviation As String<br />
End Class<br /><br /><br />
Entry on the SampleGridview.aspx page (as simple as you can get it )<br /><br />
&lt;asp:GridView runat="server" ID="lstMyData" DataKeyNames="ObjId" 
<br />
    AutoGenerateColumns="false" EnableViewState="true"<br />
    AutoGenerateEditButton="true"<br />
    OnRowDataBound="lstMyData_RowDataBound" &gt;<br />
    &lt;Columns&gt;<br />
        &lt;asp:TemplateField&gt;<br />
            &lt;ItemTemplate&gt;<br />
               
&lt;asp:Label runat="server" ID="lblState" Text='&lt;%# Eval("StateAbbreviation")
%&gt;' /&gt;<br />
            &lt;/ItemTemplate&gt;<br />
            &lt;EditItemTemplate&gt;<br />
               
&lt;asp:DropDownList runat="server" ID="uxState" /&gt;<br />
            &lt;/EditItemTemplate&gt;<br />
        &lt;/asp:TemplateField&gt;<br />
    &lt;/Columns&gt;<br />
&lt;/asp:GridView&gt;<br /><br />
Codebehind (in c#) SampleGridview.aspx.cs<br /><br />
protected void lstMyData_RowDataBound(object sender, 
<br />
        GridViewRowEventArgs e)<br />
{<br />
    // verify this is a DataRow, not a Header, Footer, etc...<br />
    if (e.Row.RowType == DataControlRowType.DataRow)<br />
    {<br />
        // in case you want to do something else
here....<br />
        
<br />
        // see if this is the Row used for Editing<br />
        if ((e.Row.RowState &amp; DataControlRowState.Edit) !=
0)<br />
        {<br />
            // get the DataItem
that is bound 
<br />
            // and cast it
accordingly<br />
            MyObject _myObject
= (MyObject)e.Row.DataItem;<br /><br />
            // get the dropdownlist<br />
            DropDownList _uxState
= 
<br />
               
(DropDownList) e.Row.FindControl("uxState");<br /><br />
            // dynamically
create the DDL for demo...<br />
            // this could also
be done statically in the aspx page<br />
            _uxState.Items.Add(new
ListItem("Hawaii", "HI"));<br />
            _uxState.Items.Add(new
ListItem("Iowa", "IA"));<br />
            _uxState.Items.Add(new
ListItem("Minnesota", "MN"));<br />
            _uxState.Items.Add(new
ListItem("Wisconsin", "WI"));<br /><br />
            // find the matching
ListItem and Select it<br />
            ListItem _matchingItem
=<br />
               
_uxState.Items.FindByValue(_myObject.StateAbbreviation);<br />
            if (_matchingItem
== null)<br />
            {<br />
               
// Houston we have a problem, no match... 
<br />
               
// handle this as you see fit<br />
            }<br />
            else<br />
            {<br />
               
_matchingItem.Selected = true;<br />
            }<br />
        }<br />
    }<br />
}<br /><br />
Protected Sub lstMyData_RowDataBound(ByVal sender As Object, _<br />
    ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _<br />
    Handles lstMyData.RowDataBound<br />
    If e.Row.RowType = DataControlRowType.DataRow Then<br /><br />
            ' in case you want
to do something else here....<br /><br />
            ' see if this is
the Row used for Editing<br />
            If (e.Row.RowState
And DataControlRowState.Edit) &lt;&gt; 0 Then<br /><br /><br />
               
' get the DataItem that is bound<br />
               
' and cast it accordingly<br />
               
Dim _myObject As MyObject = _<br />
                   
DirectCast(e.Row.DataItem, MyObject)<br /><br />
               
' get the dropdownlist<br />
               
Dim _uxState As DropDownList = _<br />
                   
DirectCast(e.Row.FindControl("uxState"), DropDownList)<br /><br />
               
' dynamically create the DDL for demo...<br />
               
' this could also be done statically in the aspx page<br />
               
_uxState.Items.Add(New ListItem("Hawaii", "HI"))<br />
               
_uxState.Items.Add(New ListItem("Iowa", "IA"))<br />
               
_uxState.Items.Add(New ListItem("Minnesota", "MN"))<br />
               
_uxState.Items.Add(New ListItem("Wisconsin", "WI"))<br /><br />
               
' find the matching ListItem and Select it<br />
               
Dim _matchingItem As ListItem = _<br />
                   
_uxState.Items.FindByValue(_myObject.StateAbbreviation)<br />
               
If _matchingItem Is Nothing Then<br />
                   
' Houston we have a problem, no match...<br />
                   
' handle this as you see fit<br />
               
Else<br />
                   
_matchingItem.Selected = True<br />
               
End If<br />
            End If<br />
     End If<br />
End Sub<br /><br />
So basically what you are doing is getting a hold of both the value that you want
selected (by using the e.Row.DataItem) and the DropDownList (by using e.Row.FindControl)
and then simply doing a match...<br /><br />
Hope this helps...<br /><p></p><img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=4e1f80c7-9cce-4a3f-82b2-24edb4d52f88" /></body>
      <title>DropDownList, GridView, and Dynamically selecting the appropriate ListItem during Edit...</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,4e1f80c7-9cce-4a3f-82b2-24edb4d52f88.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/06/04/DropDownListGridViewAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx</link>
      <pubDate>Thu, 04 Jun 2009 19:43:23 GMT</pubDate>
      <description>I have seen a number of questions regarding how to specify what the selected ListItem is on a DropDownList used in an EditRow of A GridView. So I thought it might make a good blog. &lt;br&gt;
&lt;br&gt;
Note: for an example that uses Ajax, specifically the CascadingDropDown, look here &lt;a href="http://www.myfriedmind.com/techBlog/2009/06/22/CascadingDropDownListsGridViewsAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx"&gt;http://www.myfriedmind.com/techBlog/2009/06/22/CascadingDropDownListsGridViewsAndDynamicallySelectingTheAppropriateListItemDuringEdit.aspx&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
Basically what people are trying to do is use a DropDownList as one of the input controls
on a DataRow when edit is selected for that Row. This, of course, limits what people
can enter which is a good thing. For example, what if you wanted to create a DropDownList
that specified which state someone was from, or what time (using 15-minute increments)?&lt;br&gt;
&lt;br&gt;
Creating the DropDownList is fairly straightforward, as is populating it. What is
confusing people is how to specify what the selected value is. To do that you need
to handle the OnRowDataBound event, snag the DataItem and select the ListItem that
matches the appropriate property. Like so:&lt;br&gt;
&lt;br&gt;
Sample DataObject (in c#)&lt;br&gt;
&lt;br&gt;
class MyObject&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp; public int ObjId {get; set;}&lt;br&gt;
&amp;nbsp;&amp;nbsp; public string StateAbbreviation {get; set; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
Sample DataObject (in vb.net)&lt;br&gt;
&lt;br&gt;
Class MyObject&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Public ObjId As Integer&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Public StateAbbreviation As String&lt;br&gt;
End Class&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Entry on the SampleGridview.aspx page (as simple as you can get it )&lt;br&gt;
&lt;br&gt;
&amp;lt;asp:GridView runat="server" ID="lstMyData" DataKeyNames="ObjId" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; AutoGenerateColumns="false" EnableViewState="true"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; AutoGenerateEditButton="true"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; OnRowDataBound="lstMyData_RowDataBound" &amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Columns&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TemplateField&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:Label runat="server" ID="lblState" Text='&amp;lt;%# Eval("StateAbbreviation")
%&amp;gt;' /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;EditItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;asp:DropDownList runat="server" ID="uxState" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/EditItemTemplate&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:TemplateField&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Columns&amp;gt;&lt;br&gt;
&amp;lt;/asp:GridView&amp;gt;&lt;br&gt;
&lt;br&gt;
Codebehind (in c#) SampleGridview.aspx.cs&lt;br&gt;
&lt;br&gt;
protected void lstMyData_RowDataBound(object sender, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GridViewRowEventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // verify this is a DataRow, not a Header, Footer, etc...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e.Row.RowType == DataControlRowType.DataRow)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // in case you want to do something else
here....&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // see if this is the Row used for Editing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((e.Row.RowState &amp;amp; DataControlRowState.Edit)&amp;nbsp;!=
0)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the DataItem
that is bound 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and cast it
accordingly&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject _myObject
= (MyObject)e.Row.DataItem;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get the dropdownlist&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DropDownList _uxState
= 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
(DropDownList) e.Row.FindControl("uxState");&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // dynamically
create the DDL for demo...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // this could also
be done statically in the aspx page&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _uxState.Items.Add(new
ListItem("Hawaii", "HI"));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _uxState.Items.Add(new
ListItem("Iowa", "IA"));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _uxState.Items.Add(new
ListItem("Minnesota", "MN"));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _uxState.Items.Add(new
ListItem("Wisconsin", "WI"));&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // find the matching
ListItem and Select it&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListItem _matchingItem
=&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_uxState.Items.FindByValue(_myObject.StateAbbreviation);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_matchingItem
== null)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// Houston we have a problem, no match... 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// handle this as you see fit&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_matchingItem.Selected = true;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
Protected Sub lstMyData_RowDataBound(ByVal sender As Object, _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Handles lstMyData.RowDataBound&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; If e.Row.RowType = DataControlRowType.DataRow Then&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' in case you want
to do something else here....&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' see if this is
the Row used for Editing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (e.Row.RowState
And DataControlRowState.Edit)&amp;nbsp;&amp;lt;&amp;gt; 0 Then&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' get the DataItem that is bound&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' and cast it accordingly&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Dim _myObject As MyObject = _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DirectCast(e.Row.DataItem, MyObject)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' get the dropdownlist&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Dim _uxState As DropDownList = _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DirectCast(e.Row.FindControl("uxState"), DropDownList)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' dynamically create the DDL for demo...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' this could also be done statically in the aspx page&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_uxState.Items.Add(New ListItem("Hawaii", "HI"))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_uxState.Items.Add(New ListItem("Iowa", "IA"))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_uxState.Items.Add(New ListItem("Minnesota", "MN"))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_uxState.Items.Add(New ListItem("Wisconsin", "WI"))&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' find the matching ListItem and Select it&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Dim _matchingItem As ListItem = _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_uxState.Items.FindByValue(_myObject.StateAbbreviation)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
If _matchingItem Is Nothing Then&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' Houston we have a problem, no match...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
' handle this as you see fit&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_matchingItem.Selected = True&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
End If&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br&gt;
End Sub&lt;br&gt;
&lt;br&gt;
So basically what you are doing is getting a hold of both the value that you want
selected (by using the e.Row.DataItem) and the DropDownList (by using e.Row.FindControl)
and then simply doing a match...&lt;br&gt;
&lt;br&gt;
Hope this helps...&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=4e1f80c7-9cce-4a3f-82b2-24edb4d52f88" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,4e1f80c7-9cce-4a3f-82b2-24edb4d52f88.aspx</comments>
      <category>Asp.Net</category>
      <category>c#</category>
      <category>Coding Tricks</category>
      <category>VB.Net</category>
    </item>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=10e72e98-6b95-450f-9486-b38694003487</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,10e72e98-6b95-450f-9486-b38694003487.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,10e72e98-6b95-450f-9486-b38694003487.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=10e72e98-6b95-450f-9486-b38694003487</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">For the c# version look here -&gt; <a href="http://www.myfriedmind.com/techBlog/2009/05/29/GettingErrorsNicelyViaEmailFromYourWebsiteTheCVersion.aspx">http://www.myfriedmind.com/techBlog/2009/05/29/GettingErrorsNicelyViaEmailFromYourWebsiteTheCVersion.aspx</a><br /><br />
It is always nice to get notified that there is an error on your website in some other
way than a user on the other end of the phone.<br /><br />
One of the nicest ways I know of in .net is to use the Application_Error portion of
Global.asax to shoot me an email listing the information that is needed. I have included
some basic code below but you can feel free to modify it as you choose. For example
you may prefer to include the System.Net.Mail info on the SmtpServer in the web.config
so you can use it on other portions of the site rather than repeat it.<br /><br />
In the code I use reflection to roll through both the Request object and the Exception
that is passed. You can modify it if you want to display more (such as innerexceptions,
etc) or to exclude, but Reflection can be nice in pulling up all the data quickly.<br /><br />
=================<br />
In vb.net<br /><br />
In Web.Config<br />
        &lt;customErrors mode="On" defaultRedirect="~/ErrorOnWebsite.aspx"/&gt;<br /><br />
In Global.asax (don't do this and you get an endless loop!)<br />
    Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)<br />
        Server.Transfer("~/ErrorOnWebsite.aspx")<br />
    End Sub<br /><br />
On ErrorOnWebsite.aspx (you don't actually have to use a label, you can provide some
other means of apology)<br />
        &lt;asp:Label runat="server" ID="lblApology"&gt;&lt;/asp:Label&gt;<br /><br />
This is Error.OnWebsite.aspx.vb (I like code-behinds) - note the use of the HtmlTextWriter
and Reflection!<br /><br />
Imports System<br />
Imports System.IO<br />
Imports System.Net.Mail<br />
Imports System.Web.UI<br />
Imports System.Web.UI.WebControls<br />
Imports System.Reflection<br /><br />
Partial Class ErrorOnPage<br />
    Inherits System.Web.UI.Page<br /><br />
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load<br />
        Dim exc As Exception = Server.GetLastError()<br /><br />
        If (exc Is Nothing) Then<br />
            ' there is no error,
why are they here?<br />
            Response.Redirect("~/")<br />
        Else<br />
            SendNotificationEmail(exc)<br />
            WriteApology()<br />
            Server.ClearError()<br />
        End If<br />
    End Sub<br /><br />
    Private Sub WriteApology()<br />
        lblApology.Text = "Oops, sorry, the master
of light and sound has been notified..."<br />
    End Sub<br /><br />
    Private Sub SendNotificationEmail(ByVal exc As Exception)<br />
        ' Create the format holder for the data,
I like tables...<br />
        Dim _infoTable As Table = New Table()<br />
        _infoTable.Attributes.Add("border", "1")<br />
        _infoTable.Attributes.Add("cellpadding",
"3")<br /><br />
        Dim _infoRow As TableRow<br />
        Dim _infoNameCell As TableCell<br />
        Dim _infoDataCell As TableCell<br /><br />
        _infoRow = New TableRow()<br />
        _infoNameCell = New TableCell()<br />
        _infoNameCell.Text = "Server Request Properties"<br />
        _infoNameCell.BackColor = System.Drawing.Color.Gray<br />
        _infoNameCell.ColumnSpan = 2<br />
        _infoRow.Cells.Add(_infoNameCell)<br />
        _infoTable.Rows.Add(_infoRow)<br /><br />
        ' I like to use reflection because I hate
to type...<br />
        Dim _requestType As Type = Request.GetType()<br />
        Dim _pInfo As PropertyInfo<br /><br />
        For Each _pInfo In _requestType.GetProperties()<br /><br />
            If (Not _pInfo.Name
= "Item") Then<br /><br />
               
_infoRow = New TableRow()<br /><br />
               
_infoNameCell = New TableCell()<br />
               
_infoNameCell.Text = _pInfo.Name<br />
               
_infoRow.Cells.Add(_infoNameCell)<br /><br />
               
_infoDataCell = New TableCell()<br />
               
Dim _value As Object = _pInfo.GetValue(Request, Nothing)<br />
               
If _value Is Nothing Then<br />
                   
_infoDataCell.Text = ""<br />
               
Else<br />
                   
_infoDataCell.Text = Server.HtmlEncode(_value.ToString())<br />
               
End If<br />
               
_infoRow.Cells.Add(_infoDataCell)<br /><br />
               
_infoTable.Rows.Add(_infoRow)<br />
            End If<br />
        Next<br /><br />
        _infoRow = New TableRow()<br />
        _infoNameCell = New TableCell()<br />
        _infoNameCell.Text = "Exception Properties"<br />
        _infoNameCell.BackColor = System.Drawing.Color.Gray<br />
        _infoNameCell.ColumnSpan = 2<br />
        _infoRow.Cells.Add(_infoNameCell)<br />
        _infoTable.Rows.Add(_infoRow)<br /><br />
        Dim _exceptionType As Type = exc.GetType()<br />
        For Each _pInfo In _exceptionType.GetProperties()      
 <br />
            _infoRow = New
TableRow()<br /><br />
            _infoNameCell =
New TableCell()<br />
            _infoNameCell.Text
= _pInfo.Name<br />
            _infoRow.Cells.Add(_infoNameCell)<br /><br />
            _infoDataCell =
New TableCell()<br />
            Dim _value As Object
= _pInfo.GetValue(exc, Nothing)<br />
            If (_value Is Nothing)
Then<br />
               
_infoDataCell.Text = ""<br />
            Else<br />
               
_infoDataCell.Text = Server.HtmlEncode(_value.ToString())<br />
            End If<br />
            _infoRow.Cells.Add(_infoDataCell)<br /><br />
            _infoTable.Rows.Add(_infoRow)<br />
        Next<br /><br />
        ' note the use of the HtmlTextWriter to
render the table<br />
        ' into a string<br />
        Dim _bodyWriter As StringWriter = New StringWriter()<br />
        Dim _writeToBody As HtmlTextWriter = New
HtmlTextWriter(_bodyWriter)<br />
        _infoTable.RenderControl(_writeToBody)<br /><br />
        Dim _message As MailMessage = New MailMessage("error@mysite.com",
"myemail@mysite.com")<br />
        _message.Subject = String.Format("Error
on website - {0}", exc.Message)<br />
        _message.Body = _bodyWriter.ToString()<br />
        _message.IsBodyHtml = True<br /><br />
        Dim _mailClient As SmtpClient = New SmtpClient("mymailserver")<br />
        _mailClient.Send(_message)<br /><br />
    End Sub<br /><br />
End Class<br /><br /><p></p><img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=10e72e98-6b95-450f-9486-b38694003487" /></body>
      <title>Getting errors nicely via email from your website the vb.net version</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,10e72e98-6b95-450f-9486-b38694003487.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/05/29/GettingErrorsNicelyViaEmailFromYourWebsiteTheVbnetVersion.aspx</link>
      <pubDate>Fri, 29 May 2009 21:55:09 GMT</pubDate>
      <description>For the c# version look here -&amp;gt; &lt;a href="http://www.myfriedmind.com/techBlog/2009/05/29/GettingErrorsNicelyViaEmailFromYourWebsiteTheCVersion.aspx"&gt;http://www.myfriedmind.com/techBlog/2009/05/29/GettingErrorsNicelyViaEmailFromYourWebsiteTheCVersion.aspx&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
It is always nice to get notified that there is an error on your website in some other
way than a user on the other end of the phone.&lt;br&gt;
&lt;br&gt;
One of the nicest ways I know of in .net is to use the Application_Error portion of
Global.asax to shoot me an email listing the information that is needed. I have included
some basic code below but you can feel free to modify it as you choose. For example
you may prefer to include the System.Net.Mail info on the SmtpServer in the web.config
so you can use it on other portions of the site rather than repeat it.&lt;br&gt;
&lt;br&gt;
In the code I use reflection to roll through both the Request object and the Exception
that is passed. You can modify it if you want to display more (such as innerexceptions,
etc) or to exclude, but Reflection can be nice in pulling up all the data quickly.&lt;br&gt;
&lt;br&gt;
=================&lt;br&gt;
In vb.net&lt;br&gt;
&lt;br&gt;
In Web.Config&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;customErrors mode="On" defaultRedirect="~/ErrorOnWebsite.aspx"/&amp;gt;&lt;br&gt;
&lt;br&gt;
In Global.asax (don't do this and you get an endless loop!)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Server.Transfer("~/ErrorOnWebsite.aspx")&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;br&gt;
&lt;br&gt;
On ErrorOnWebsite.aspx (you don't actually have to use a label, you can provide some
other means of apology)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:Label runat="server" ID="lblApology"&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br&gt;
&lt;br&gt;
This is Error.OnWebsite.aspx.vb (I like code-behinds) - note the use of the HtmlTextWriter
and Reflection!&lt;br&gt;
&lt;br&gt;
Imports System&lt;br&gt;
Imports System.IO&lt;br&gt;
Imports System.Net.Mail&lt;br&gt;
Imports System.Web.UI&lt;br&gt;
Imports System.Web.UI.WebControls&lt;br&gt;
Imports System.Reflection&lt;br&gt;
&lt;br&gt;
Partial Class ErrorOnPage&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Inherits System.Web.UI.Page&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim exc As Exception = Server.GetLastError()&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (exc Is Nothing) Then&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' there is no error,
why are they here?&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.Redirect("~/")&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendNotificationEmail(exc)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteApology()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Server.ClearError()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Private Sub WriteApology()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblApology.Text = "Oops, sorry, the master
of light and sound has been notified..."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Private Sub SendNotificationEmail(ByVal exc As Exception)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Create the format holder for the data,
I like tables...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _infoTable As Table = New Table()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoTable.Attributes.Add("border", "1")&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoTable.Attributes.Add("cellpadding",
"3")&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _infoRow As TableRow&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _infoNameCell As TableCell&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _infoDataCell As TableCell&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoRow = New TableRow()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell = New TableCell()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell.Text = "Server Request Properties"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell.BackColor = System.Drawing.Color.Gray&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell.ColumnSpan = 2&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoRow.Cells.Add(_infoNameCell)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoTable.Rows.Add(_infoRow)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' I like to use reflection because I hate
to type...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _requestType As Type = Request.GetType()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _pInfo As PropertyInfo&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each _pInfo In _requestType.GetProperties()&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Not _pInfo.Name
= "Item") Then&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoRow = New TableRow()&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoNameCell = New TableCell()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoNameCell.Text = _pInfo.Name&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoRow.Cells.Add(_infoNameCell)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoDataCell = New TableCell()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Dim _value As Object = _pInfo.GetValue(Request, Nothing)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
If _value Is Nothing Then&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoDataCell.Text = ""&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoDataCell.Text = Server.HtmlEncode(_value.ToString())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
End If&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoRow.Cells.Add(_infoDataCell)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoTable.Rows.Add(_infoRow)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoRow = New TableRow()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell = New TableCell()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell.Text = "Exception Properties"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell.BackColor = System.Drawing.Color.Gray&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell.ColumnSpan = 2&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoRow.Cells.Add(_infoNameCell)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoTable.Rows.Add(_infoRow)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _exceptionType As Type = exc.GetType()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each _pInfo In _exceptionType.GetProperties()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoRow = New
TableRow()&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell =
New TableCell()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoNameCell.Text
= _pInfo.Name&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoRow.Cells.Add(_infoNameCell)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoDataCell =
New TableCell()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _value As Object
= _pInfo.GetValue(exc, Nothing)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (_value Is Nothing)
Then&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoDataCell.Text = ""&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
_infoDataCell.Text = Server.HtmlEncode(_value.ToString())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoRow.Cells.Add(_infoDataCell)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoTable.Rows.Add(_infoRow)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' note the use of the HtmlTextWriter to
render the table&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' into a string&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _bodyWriter As StringWriter = New StringWriter()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _writeToBody As HtmlTextWriter = New
HtmlTextWriter(_bodyWriter)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _infoTable.RenderControl(_writeToBody)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _message As MailMessage = New MailMessage("error@mysite.com",
"myemail@mysite.com")&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _message.Subject = String.Format("Error
on website - {0}", exc.Message)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _message.Body = _bodyWriter.ToString()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _message.IsBodyHtml = True&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim _mailClient As SmtpClient = New SmtpClient("mymailserver")&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _mailClient.Send(_message)&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;br&gt;
&lt;br&gt;
End Class&lt;br&gt;
&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=10e72e98-6b95-450f-9486-b38694003487" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,10e72e98-6b95-450f-9486-b38694003487.aspx</comments>
      <category>Asp.Net</category>
      <category>Coding Tricks</category>
      <category>VB.Net</category>
    </item>
    <item>
      <trackback:ping>http://www.myfriedmind.com/techBlog/Trackback.aspx?guid=80712240-5305-49d4-aefa-771ef499f69f</trackback:ping>
      <pingback:server>http://www.myfriedmind.com/techBlog/pingback.aspx</pingback:server>
      <pingback:target>http://www.myfriedmind.com/techBlog/PermaLink,guid,80712240-5305-49d4-aefa-771ef499f69f.aspx</pingback:target>
      <dc:creator>papabear</dc:creator>
      <wfw:comment>http://www.myfriedmind.com/techBlog/CommentView,guid,80712240-5305-49d4-aefa-771ef499f69f.aspx</wfw:comment>
      <wfw:commentRss>http://www.myfriedmind.com/techBlog/SyndicationService.asmx/GetEntryCommentsRss?guid=80712240-5305-49d4-aefa-771ef499f69f</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>
            <font color="#ff0000">Note: special thanks to Thomas who catches my error in using
QueryString vs url hash - I have made the appropriate changes in this entry...</font>
          </em>
        </p>
        <p>
Part 1 - <a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"><font color="#5c80b1">Introduction</font></a><br />
Part 2 - <a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx"><font color="#5c80b1">Basic
Example</font></a><br />
Part 3 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx"><font color="#5c80b1">Complex
Example</font></a><br />
Part 4 - <a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx"><font color="#5c80b1">Final
Notes</font></a><br />
Bonus - <a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"><font color="#5c80b1">Ajax
History and the Memento Pattern</font></a><br />
Extra Bonus - <a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx"><font color="#5c80b1">Issues
with Opera</font></a></p>
        <p>
Recently while watching a <a href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&amp;EventID=1032414968">geekspeak
on Ajax history</a> it struck me that it reminded me strongly of a Memento pattern.
I mentioned this to Glen Gordon and he recommended I write a blog on it, so without
further ado...
</p>
        <p>
First off, a little background. Maintaining history has been one of the holy grails
of Ajax since it began. It is a wonderful feeling to produce a zippy, intiutive site
that has fantastic UI, but once someone hits the "back" button everything goes down
the tube. The reason is simple, browsers were created in the time before, even before
Javascript, much less XML. Back then the "back" button, or any sort of history action,
brought you back not to your last action but to the last page that fully loaded.
</p>
        <p>
To give a parallel, for anyone who has used the "undo" command in whatever program,
what it does is "undo" the last action that you did. Imagine typing for hours in Word,
clicking "undo", and having it wipe out EVERYTHING that you had just done, not just
the last little action. No one would want that, but this is what the "back" key effectively
did by default. Hence, the quest to maintain Ajax history. Wouldn't it be nice if
the "back" key, or other "back" command acted as an "undo" vs a true "back to the
previous page"?
</p>
        <p>
In addition, what if after working on a page (say a maps page) that uses Ajax, you
want to send someone the link. The option is to use a URL, but since Ajax by default
modified the page but not the URL, all that work would be useless. You would think
you were sending them a map to your cabin by the lake, they would simply get the default
map of the world. Not good.
</p>
        <p>
There have been ways to resolve this even before .net 3.5 came out. One merely has
to look at some of the larger Ajax enabled sites (such as google maps) to see this,
but this is such a constant and complex requirement in almost any Ajax development
that it is only logical that someone develop a abstractive pattern to simplify and
standardize it. The 3.5 framework does this, one of many reason it makes me squeal
like schoolgirl. But what is especially fun to look at is how it does it, specifically
what pattern was chosen. The pattern, which is extremely logical to choose, is akin
to the Memento pattern.
</p>
        <p>
I won't go into <a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29">Design
Patterns </a>here. If you are not sure, follow this <a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29">link</a>, <a href="http://en.wikipedia.org/wiki/Design_Patterns_%28book%29">buy
the book</a>, <a href="http://art.cafepress.com/item/black-gof-design-patterns-poster/238970064">get
the poster</a>. I want to focus on one pattern, the Memento pattern and how it relates
to Ajax history in the hopes that it will illumine your coding.
</p>
        <p>
The Memento pattern requires two players, commonly refered to as the Originator and
the Caretaker. To clarify the interaction:
</p>
        <ol>
          <li>
The Caretaker is going to change the Originator in some way but the Originator needs
to be able to undo the change. 
</li>
          <li>
The Caretaker receives a small "memento" object and stores it (hence the Caretaker
name). 
</li>
          <li>
The Caretaker then changes the Originator.</li>
        </ol>
        <p>
If the change needs to be undone:
</p>
        <ol>
          <li>
The Caretaker returns the "memento" object to the Originator. 
</li>
          <li>
The Originator uses the "memento" object to undo the change.</li>
        </ol>
        <p>
But it is also critical to understand about the "memento".
</p>
        <ul>
          <li>
The "memento" is an opaque object, meaning the Caretaker can not change it 
</li>
          <li>
The "memento" is small, it is not the entire Originator, merely the minimal information
needed to rollback state 
</li>
          <li>
The Originator is the one who packages and unpackages the "memento" 
</li>
          <li>
The Originator is the one who rolls back state (ie, the Caretaker does not modify
the Originator to roll it back)</li>
        </ul>
        <p>
So how does this apply to how .Net does Ajax history? In short, .Net uses the URL
of the page as the "memento", the History as the Caretaker, with the code you write
in the framework acting as the Originator.
</p>
        <ol>
          <li>
The Ajax action is going to change the webpage someway. 
</li>
          <li>
The current hash is already stored 
</li>
          <li>
The Ajax action makes the change and alters the hash</li>
        </ol>
        <p>
If the change needs to be undone:
</p>
        <ol>
          <li>
The hash (in the URL) that was from the previous page (the rollback
state) is returned. 
</li>
          <li>
The code that YOU wrote rollsback the state.</li>
        </ol>
        <p>
In this case the memento has these characteristics
</p>
        <ul>
          <li>
The "memento" is a url which is unchanged by the Caretaker (browser) 
</li>
          <li>
The "memento" is small (you should make sure of this) 
</li>
          <li>
The framework writes the URL that you need and allows you to access it 
</li>
          <li>
Your code is what rolls back state 
</li>
        </ul>
        <p>
So, what does this mean? Basically the key point is that you can apply the practices
that you have in place for working with the Memento pattern to working with Ajax history.
Chief among these is that the "memento" should be small! Do not try to squeeze too
much into your URL. It is not pretty and there are limits! Instead pare down to the
minimum of what you need to be able to restore state.
</p>
        <p>
One major bonus is that this not merely allows rollback, but enables your users to
use URLs to return an Ajax-enabled page on which certain steps have already been taken.
This is AMAZING!!!!!!! And compared to how we used to have to do it, it is like a
walk in the park! 
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=80712240-5305-49d4-aefa-771ef499f69f" />
      </body>
      <title>Ajax history and the Memento pattern</title>
      <guid isPermaLink="false">http://www.myfriedmind.com/techBlog/PermaLink,guid,80712240-5305-49d4-aefa-771ef499f69f.aspx</guid>
      <link>http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx</link>
      <pubDate>Wed, 20 May 2009 17:17:13 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;&lt;font color=#ff0000&gt;Note: special thanks to Thomas who catches my error in using
QueryString vs url hash - I have made the appropriate changes in this entry...&lt;/font&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Part 1 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/06/30/AjaxHistoryAHowToPart1.aspx"&gt;&lt;font color=#5c80b1&gt;Introduction&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 2 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/01/AjaxHistoryAHowToPart2ABasicExample.aspx"&gt;&lt;font color=#5c80b1&gt;Basic
Example&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 3 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart3ComplexExampleC.aspx"&gt;&lt;font color=#5c80b1&gt;Complex
Example&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Part 4 - &lt;a href="http://www.myfriedmind.com/techBlog/2009/07/09/AjaxHistoryAHowToPart4FinalNotes.aspx"&gt;&lt;font color=#5c80b1&gt;Final
Notes&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Bonus - &lt;a href="http://www.myfriedmind.com/techBlog/2009/05/20/AjaxHistoryAndTheMementoPattern.aspx"&gt;&lt;font color=#5c80b1&gt;Ajax
History and the Memento Pattern&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
Extra Bonus - &lt;a href="http://www.myfriedmind.com/techBlog/2009/09/21/Opera9x10xFailingOnAjaxHistoryAndTheHackToFixIt.aspx"&gt;&lt;font color=#5c80b1&gt;Issues
with Opera&lt;/font&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Recently while watching a &lt;a href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&amp;amp;EventID=1032414968"&gt;geekspeak
on Ajax history&lt;/a&gt; it struck me that it reminded me strongly of a Memento pattern.
I mentioned this to Glen Gordon and he recommended I write a blog on it, so without
further ado...
&lt;/p&gt;
&lt;p&gt;
First off, a little background. Maintaining history has been one of the holy grails
of Ajax since it began. It is a wonderful feeling to produce a zippy, intiutive site
that has fantastic UI, but once someone hits the "back" button everything goes down
the tube. The reason is simple, browsers were created in the time before, even before
Javascript, much less XML. Back then the "back" button, or any sort of history action,
brought you back not to your last action but to the last page that fully loaded.
&lt;/p&gt;
&lt;p&gt;
To give a parallel, for anyone who has used the "undo" command in whatever program,
what it does is "undo" the last action that you did. Imagine typing for hours in Word,
clicking "undo", and having it wipe out EVERYTHING that you had just done, not just
the last little action. No one would want that, but this is what the "back" key effectively
did by default. Hence, the quest to maintain Ajax history. Wouldn't it be nice if
the "back" key, or other "back" command acted as an "undo" vs a true "back to the
previous page"?
&lt;/p&gt;
&lt;p&gt;
In addition, what if after working on a page (say a maps page) that uses Ajax, you
want to send someone the link. The option is to use a URL, but since Ajax by default
modified the page but not the URL, all that work would be useless. You would think
you were sending them a map to your cabin by the lake, they would simply get the default
map of the world. Not good.
&lt;/p&gt;
&lt;p&gt;
There have been ways to resolve this even before .net 3.5 came out. One merely has
to look at some of the larger Ajax enabled sites (such as google maps) to see this,
but this is such a constant and complex requirement in almost any Ajax development
that it is only logical that someone develop a abstractive pattern to simplify and
standardize it. The 3.5 framework does this, one of many reason it makes me squeal
like schoolgirl. But what is especially fun to look at is how it does it, specifically
what pattern was chosen. The pattern, which is extremely logical to choose, is akin
to the Memento pattern.
&lt;/p&gt;
&lt;p&gt;
I won't go into &lt;a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29"&gt;Design
Patterns &lt;/a&gt;here. If you are not sure, follow this &lt;a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29"&gt;link&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns_%28book%29"&gt;buy
the book&lt;/a&gt;, &lt;a href="http://art.cafepress.com/item/black-gof-design-patterns-poster/238970064"&gt;get
the poster&lt;/a&gt;. I want to focus on one pattern, the Memento pattern and how it relates
to Ajax history in the hopes that it will illumine your coding.
&lt;/p&gt;
&lt;p&gt;
The Memento pattern requires two players, commonly refered to as the Originator and
the Caretaker. To clarify the interaction:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The Caretaker is going to change the Originator in some way but the Originator needs
to be able to undo the change. 
&lt;li&gt;
The Caretaker receives a small&amp;nbsp;"memento" object and stores it (hence the Caretaker
name). 
&lt;li&gt;
The Caretaker then changes the Originator.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
If the change needs to be undone:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The Caretaker returns the "memento" object to the Originator. 
&lt;li&gt;
The Originator uses the "memento" object to undo the change.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
But it is also critical to understand about the "memento".
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The "memento" is an opaque object, meaning the Caretaker can not change it 
&lt;li&gt;
The "memento" is small, it is not the entire Originator, merely the minimal information
needed to rollback state 
&lt;li&gt;
The Originator is the one who packages and unpackages the "memento" 
&lt;li&gt;
The Originator is the one who rolls back state (ie, the Caretaker does not modify
the Originator to roll it back)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So how does this apply to how .Net does Ajax history? In short, .Net uses the URL
of the page as the "memento", the History as the Caretaker, with the code you write
in the framework acting as the Originator.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The Ajax action is going to change the webpage someway. 
&lt;li&gt;
The current hash is already stored 
&lt;li&gt;
The Ajax action makes the change and alters the hash&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
If the change needs to be undone:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The&amp;nbsp;hash&amp;nbsp;(in the URL)&amp;nbsp;that was from the previous page (the rollback
state) is returned. 
&lt;li&gt;
The code that YOU wrote rollsback the state.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
In this case the memento has these characteristics
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The "memento" is a url which is unchanged by the Caretaker (browser) 
&lt;li&gt;
The "memento" is small (you should make sure of this) 
&lt;li&gt;
The&amp;nbsp;framework writes the URL that you need and allows you to access it 
&lt;li&gt;
Your code&amp;nbsp;is what&amp;nbsp;rolls back state 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So, what does this mean? Basically the key point is that you can apply the practices
that you have in place for working with the Memento pattern to working with Ajax history.
Chief among these is that the "memento" should be small! Do not try to squeeze too
much into your URL. It is not pretty and there are limits! Instead pare down to the
minimum of what you need to be able to restore state.
&lt;/p&gt;
&lt;p&gt;
One major bonus is that this not merely allows rollback, but enables your users to
use URLs to return an Ajax-enabled page on which certain steps have already been taken.
This is AMAZING!!!!!!! And compared to how we used to have to do it, it is like a
walk in the park! 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.myfriedmind.com/techBlog/aggbug.ashx?id=80712240-5305-49d4-aefa-771ef499f69f" /&gt;</description>
      <comments>http://www.myfriedmind.com/techBlog/CommentView,guid,80712240-5305-49d4-aefa-771ef499f69f.aspx</comments>
      <category>Ajax</category>
      <category>Asp.Net</category>
      <category>c#</category>
      <category>Coding Tricks</category>
      <category>Design Patterns</category>
      <category>VB.Net</category>
    </item>
  </channel>
</rss>