<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-263307687327671735</id><updated>2011-11-28T07:31:21.228+07:00</updated><title type='text'>News from asp.net official website</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-7711562280345727576</id><published>2008-03-27T11:19:00.001+07:00</published><updated>2008-03-27T11:19:41.727+07:00</updated><title type='text'>Unit Testing ASP.NET Pages Using WatiN</title><content type='html'>&lt;div&gt;&lt;span id="ctl00_cphCell1_datalistArticles_ctl01_lblArticleDescription"&gt; &lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font size="2" face="Verdana"&gt;Introduction:&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Unit testing is an integral part of the application design. Unit testing is applied at different levels of the application. In this article we will focus on the User Interface level unit testing. We will use &lt;a href="http://watin.sourceforge.net/index.html"&gt;WatiN&lt;/a&gt; to test our &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; application. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;What is WatiN?&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;a href="http://watin.sourceforge.net/index.html"&gt;WatiN&lt;/a&gt; is a tool inspired from &lt;a href="http://wtr.rubyforge.org/"&gt;Watir&lt;/a&gt; (Don&amp;#39;t worry I will write an article on Watir&amp;nbsp; very soon)&amp;nbsp;to test web pages. WatiN stands for &lt;strong&gt;W&lt;/strong&gt;eb &lt;strong&gt;A&lt;/strong&gt;pplication &lt;strong&gt;T&lt;/strong&gt;esting in .&lt;strong&gt;N&lt;/strong&gt;ET. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;What are we testing? &lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;In this article we will be testing a simple &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page. The page will demonstrate an agreement acceptance scenario. The user will type his name in the TextBox, click the "I agree" checkbox and then press the submit button. This is a very simple page to test but after you are familiar with the workings of the WatiN framework you can apply the same concepts for testing large pages. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Here is the screen shot of our page: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.gridviewguy.com/ArticleImages/WatiNImage1.Jpg"&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&amp;nbsp;&lt;/font&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Testing the Agreement Page:&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Add a class library project to your solution and make references to the testing tool (I am using MbUnit but you can use NUnit or VS Team Suite Test Project) and the WatiN library. You can download the WatiN library from the&amp;nbsp;&lt;a href="http://sourceforge.net/project/showfiles.php?group_id=167632"&gt;here&lt;/a&gt;. &amp;nbsp;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Here is the simple test which makes sure that the user has agreed the agreement. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;[TestFixture(ApartmentState = ApartmentState.STA)]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class TestAgreementPage &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; [Test]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void test_can_accept_the_user_agreement()&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; &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; IE ie = new IE(ConfigurationManager.AppSettings[&amp;quot;DefaultPageUrl&amp;quot;] as String);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ie.TextField(&amp;quot;txtName&amp;quot;).TypeText(&amp;quot;Mohammad Azam&amp;quot;);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ie.CheckBox(&amp;quot;chkAgree&amp;quot;).Checked = 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ie.Button(&amp;quot;Btn_Agree&amp;quot;).Click();&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(&amp;quot;Valid&amp;quot;,ie.Span(&amp;quot;lblMessage&amp;quot;).Text);&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; &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;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The class is decorated with the TestFixture attribute which also makes sure that the tests are run in a Single Threaded Apartment state. This is because the test will launch the Internet Explorer. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The IE class contained in the WatiN library does the main work. IE class opens the Internet Explorer and refers to the HTML controls using their name or ID. The line &lt;font face="Courier New"&gt;ie.TextField("txtName").TypeText("Mohammad Azam")&lt;/font&gt; refers to the TextBox with the ID "&lt;strong&gt;txtName&lt;/strong&gt;". When the browser is launched WatiN will write the text "Mohammad Azam" inside the TextBox named "txtName". This will be done right before our eyes and you would be able to see WatiN typing text into the TextBox. Then the CheckBox with the ID "chkAgree" will be checked. Finally, WatiN will press the submit button and the form is submitted. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;If you run this test it will fail. This is because the Label named "lblMessage" is never set to "Valid". Let's do that in the page code behind. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;protected void Btn_Agree_Click(object sender, EventArgs e)&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblMessage.Text = &amp;quot;Valid&amp;quot;;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Now, if you run the test it will pass. But, something does not seem right. Let's remove the following line from our test. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;ie.CheckBox("chkAgree").Checked = true; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;This means we are not going to mark the CheckBox as checked. If you run the test again it will pass. This is not right! The test should only pass when the &lt;strong&gt;CheckBox&lt;/strong&gt; is checked. Let's make a change to the code behind of the page. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;protected void Btn_Agree_Click(object sender, EventArgs e)&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; if (chkAgree.Checked)&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; lblMessage.Text = &amp;quot;Valid&amp;quot;;&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;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Now, the test will only pass when the CheckBox is checked. &lt;br&gt;&lt;/font&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Programmatically Running the Web Server:&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;In the above example you will need to start your WebServer by either manually running the command line tool or by running the Web Application Project. But, sometimes you will want the unit test project to dynamically start a web server. Let's check it out how this can be done. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;First, if you want to start the &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; internal server (WebDev.WebServer) then you can use command line to start it. The syntax is shown below: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;WebDev.WebServer.exe /port:1950 /path: "C:\Projects\MyWebApplication"&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;You will need to be in the same directory where the WebDev.WebServer exists. By default it is located at:&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Now, let's use this information to start the server using unit tests. First, here is the required configuration saved in the configuration file (App.config). &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;lt;configuration&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp; &amp;lt;appSettings&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add key=&amp;quot;WebServerExePath&amp;quot; value=&amp;quot;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe&amp;quot;/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add key=&amp;quot;Port&amp;quot; value=&amp;quot;1950&amp;quot;/&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add key=&amp;quot;WebApplicationPath&amp;quot; value=&amp;quot;c:\projects\demowatiN\demowatiN&amp;quot;/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add key=&amp;quot;DefaultPageUrl&amp;quot; value=&amp;quot;&lt;/font&gt;&lt;a href="http://localhost:1950/Default.aspx%22/"&gt;&lt;font size="2" face="Courier New"&gt;http://localhost:1950/Default.aspx&amp;quot;/&lt;/font&gt;&lt;/a&gt;&lt;font size="2" face="Courier New"&gt;&amp;gt;&amp;nbsp;&amp;nbsp; &lt;br&gt; &amp;nbsp; &amp;lt;/appSettings&amp;gt;&lt;br&gt;&amp;nbsp; &lt;br&gt;&amp;lt;/configuration&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The &lt;strong&gt;BaseTestPage&lt;/strong&gt; class will use this information to start the server and all the test classes will derive from the BaseTestPage class to use this functionality.&amp;nbsp; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Here is the complete code for the &lt;strong&gt;BaseTestPage&lt;/strong&gt; class: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;public class BaseTestPage&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; static Process server = null;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static BaseTestPage()&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; if (Process.GetProcessesByName(&amp;quot;WebDev.WebServer&amp;quot;).Count() == 0)&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; string webServerExePath = (string)ConfigurationManager.AppSettings[&amp;quot;WebServerExePath&amp;quot;];&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; server = new Process();&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; Process.Start(webServerExePath, GetWebServerArguments());&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;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string GetWebServerArguments()&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; string args = String.Format(&amp;quot;/port:{0} /path:\&amp;quot;{1}\&amp;quot;&amp;quot;,GetPort(),GetWebApplicationPath());&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 (String.IsNullOrEmpty(args)) throw new ArgumentNullException(&amp;quot;Arguments is not defined&amp;quot;);&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; return args;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string GetPort()&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; string port = ConfigurationManager.AppSettings[&amp;quot;Port&amp;quot;] as String;&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 (String.IsNullOrEmpty(port)) throw new ArgumentNullException(&amp;quot;Port is null or empty&amp;quot;);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return port; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string GetWebApplicationPath()&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; string webApplicationPath = ConfigurationManager.AppSettings[&amp;quot;WebApplicationPath&amp;quot;] as String;&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 (String.IsNullOrEmpty(webApplicationPath)) throw new ArgumentNullException(&amp;quot;WebApplicationPath is null or empty&amp;quot;);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return webApplicationPath;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;We used a static constructor to make sure that the process is not running. If it is not running we make a new process and start it else we use the old process. The &lt;strong&gt;GetWebServerArguments&lt;/strong&gt;(), &lt;strong&gt;GetPort&lt;/strong&gt;() and &lt;strong&gt;GetWebApplicationPath&lt;/strong&gt;() are just helper methods to improve the readability. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Finally, you will derive all your unit test classes from the BaseTestPage class as shown below: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;public class TestAgreementPage : BaseTestPage&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Now, if you run your unit test project will start the WebServer and then run all the tests. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Conclusion:&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;In this article we learned how to unit test our user interface layer. Unit testing the user interface helps us to understand the requirements of the interface and quickly see the expected result based on the user input. If this testing is done manually then it might take a lot of time.&lt;/font&gt;&lt;/p&gt; &lt;/span&gt;&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;By &lt;a href="mailto:azamsharp@gmail.com"&gt;AzamSharp &lt;/a&gt;&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;Source: &lt;a href="http://www.gridviewguy.com/ArticleDetails.aspx?articleID=367"&gt;http://www.gridviewguy.com/ArticleDetails.aspx?articleID=367&lt;/a&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-7711562280345727576?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/7711562280345727576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=7711562280345727576' title='43 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/7711562280345727576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/7711562280345727576'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/unit-testing-aspnet-pages-using-watin.html' title='Unit Testing ASP.NET Pages Using WatiN'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>43</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-8651238824272617686</id><published>2008-03-26T09:44:00.001+07:00</published><updated>2008-03-26T09:44:57.619+07:00</updated><title type='text'>Supporting Complex Types in Property Window</title><content type='html'>&lt;h2&gt;ntroduction&lt;/h2&gt; &lt;p&gt;Whenever you set any property of a control in the property window, the property window needs to save this property value in the .aspx file. This process is known as code serialization. For properties that are of simple types (such as integer and string) this code serialization happens automatically. However, when property &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink2" class="kLink" href="http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;data &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;types&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; are user defined complex types then you need to do that work yourself. This is done via what is called as Type Converters. This article is going to examine what type converters are and how to create one for your custom control.&lt;/p&gt;  &lt;h2&gt;Type Converters&lt;/h2&gt; &lt;p&gt;A type converter is a class that converts values entered in the property window to the actual data type of the property and vice a versa. The type converter class is inherited from TypeConverter or ExpandableObjectConverter &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink3" class="kLink" href="http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;base &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;class&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;. If you inherit from TypeConverter base class then you need to supply a delimited string in the property window where each part of the string corresponds to a property of the underlying complex type. If you inherit from ExpandableObjectConverter base class then &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink4" class="kLink" href="http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;Visual &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;Studio&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; makes your job easy by providing an expandable tree to enter the individual property values. The following figure shows how this expandable region looks like:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.bipinjoshi.net/articles/content/Images/BK_Type_Converter_01.jpg"&gt;&lt;/p&gt; &lt;h2&gt;Creating an Expandable Type Converter&lt;/h2&gt; &lt;p&gt;As an example of creating a type converter let&amp;#39;s assume that you have a custom control that displays full name in the web form. The Name property of the control allows you to specify the full name to be displayed. The Name property is of type FullName. The FullName class consists of two public properties namely FirstName and LastName. &lt;/p&gt;  &lt;h4&gt;Creating FullName class&lt;/h4&gt; &lt;p&gt;To begin developing this example first of all create a new Web Control project in Visual Studio. Add a new class to the project and name it as FullName. Code the FullName class as shown below:&lt;/p&gt;&lt;pre&gt;[Serializable] public class FullName { private string strFName; private string strLName;  public string FirstName  { get { return strFName; } set { strFName = value; } }  public string LastName { get { return strLName; } set { strLName = value; } }  public FullName() { }  public FullName(string fname, string lname) { strFName = fname; strLName = lname; } }&lt;/pre&gt; &lt;p&gt;The FullName class simply consists of two public properties namely FirstName and LastName. Notice that the FullName class is marked as [Serializable] &lt;/p&gt; &lt;h4&gt;Creating FullNameConverter class&lt;/h4&gt; &lt;p&gt;Now add another class to the project and name it as FullNameConvertor. Inherit the FullNameConvertor class from ExpandableObjectConverter base class. As a convention the type converter class names should have name of the class they convert attached with &amp;quot;Converter&amp;quot; at the end. Once created you need to override certain methods of the base class. These methods are explained next.&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)&lt;br&gt;The CanConvertFrom method tells the property window whether the source type can be converted to the property data type. Most of the cases you will ensure that if the source type is string then the &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink5" class="kLink" href="http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;method &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;returns&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; true; false otherwise.&lt;br&gt; &lt;/li&gt; &lt;li&gt;bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)&lt;br&gt;The CanConvertTo method tells the property window whether a property value can be converted to the destination data type. Most of the cases you will ensure that if the destination type is string then the method returns true; false otherwise.&lt;br&gt; &lt;/li&gt; &lt;li&gt;object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)&lt;br&gt;The actual task of converting a source value (string) into the destination type (FullName) is done inside ConvertFrom method&lt;br&gt; &lt;/li&gt; &lt;li&gt;object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)&lt;br&gt;The actual task of converting a property value (FullName) to the destination type (string) is done inside ConvertTo method.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The following code shows all these methods for FullNameConverter class.&lt;/p&gt;&lt;pre&gt;public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) { return true; } else { return base.CanConvertFrom(context, sourceType); } }  public override bool CanConvertTo (ITypeDescriptorContext context,  Type destinationType) { if (destinationType == typeof(string)) { return true; } else { return base.CanConvertTo(context, destinationType); } }  public override object ConvertFrom (ITypeDescriptorContext context,  System.Globalization.CultureInfo culture,  object value) { if(value is string) { string[] names = ((string)value).Split(&amp;#39; &amp;#39;); if (names.Length == 2) { return new FullName(names[0],names[1]); } else { return new FullName(); } } else { return base.ConvertFrom(context,culture,value); } }  public override object ConvertTo (ITypeDescriptorContext context,  System.Globalization.CultureInfo culture,  object value, Type destinationType) { if (value is string) { FullName name = value as FullName; return name.FirstName + &amp;quot; &amp;quot; + name.LastName; } else { return base.ConvertTo(context, culture, value,  destinationType); } }&lt;/pre&gt; &lt;p&gt;The CanConvertFrom() method checks if the data type of proposed value is string. If so it returns true otherwise base class version of CanConvertFrom() method is called. Similar job is done inside CanConvertTo() method. Remember that these two methods though sound similar are called at different times. The CanConvertFrom() method is called when you enter a value in the property window whereas CanConvertTo() method is called when property window reads previously serialized property value.&lt;/p&gt;  &lt;p&gt;The ConvertFrom() method converts a supplied string value into an instance of type FullName. It does so by splitting the source string (e.g. Nancy Davalio) at the occurrence of a &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink6" class="kLink" href="http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;white &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;space&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;. An instance of FullName class is returned based on the supplied FirstName and LastName values.&lt;/p&gt;  &lt;p&gt;The ConvertTo() method does reverse of ConvertFrom() method. It converts a FullName instance into its string representation. This is done by simply concatenating FirstName property, a white space and the LastName property. The resultant string is returned from the ConvertTo() method.&lt;/p&gt;  &lt;p&gt;Note that in the above example we inherited FullNameConverter class from ExpandableObjectConverter base class. Even if you inherit from TypeConverter base class the process of overriding the methods remains the same.&lt;/p&gt;  &lt;h4&gt;Attaching type converter to FullName class&lt;/h4&gt; &lt;p&gt;Now that you have completed the FullNameConverter class it&amp;#39;s time to attach it to the FullName class. This is done as follows:&lt;/p&gt;&lt;pre&gt;&lt;strong&gt;[TypeConverter(typeof(FullNameConvertor))] &lt;/strong&gt;[Serializable] public class FullName ...&lt;/pre&gt; &lt;p&gt;You need to decorate the FullName class with [TypeConverter] attribute. The TypeConverter attribute accepts the type information of a class that is acting as a type converter for this class.&lt;/p&gt; &lt;h4&gt;Synchronizing markup and property window&lt;/h4&gt; &lt;p&gt;Whenever you make any change in the property window immediately the new values should be saved to the .aspx file. To enable this behavior you need to mark the FirstName and LastName properties with the following additional attributes.&lt;/p&gt; &lt;pre&gt;[RefreshProperties(RefreshProperties.All)] [NotifyParentProperty(true)]&lt;/pre&gt; &lt;p&gt;The RefreshProperties() attribute should be familiar to you because we discussed it in the &lt;a href="http://www.bipinjoshi.net/articles/45c86a20-855f-4811-a701-e58184de5217.aspx"&gt;previous article&lt;/a&gt; of this series. It simply refreshes the property window by re-querying all the property values. More important is the NotifyParentProperty() attribute. This attribute governs whether the parent property (Name) is to be notified when any of the child properties (FirstName and LastName) are changed. This way the parent property can reflect the newly assigned values.&lt;/p&gt;  &lt;h4&gt;Coding the custom control&lt;/h4&gt; &lt;p&gt;Now it&amp;#39;s time to develop our custom control. We will call it as FullNameLabel and it resembles as shown below:&lt;/p&gt;&lt;pre&gt;public class FullNameLabel : WebControl { &lt;strong&gt;[DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)] &lt;/strong&gt;[&lt;strong&gt;PersistenceMode(PersistenceMode.InnerProperty)] &lt;/strong&gt;public FullName Name { get { return ViewState[&amp;quot;_fullname&amp;quot;] as FullName; } set { ViewState[&amp;quot;_fullname&amp;quot;] = value; } }  protected override void Render(HtmlTextWriter writer) { if (Name != null) { writer.WriteFullBeginTag(&amp;quot;span&amp;quot;); writer.Write(Name.FirstName); writer.Write(&amp;quot;&amp;amp;nbsp;&amp;quot;); writer.Write(Name.LastName); writer.WriteEndTag(&amp;quot;span&amp;quot;); } } }&lt;/pre&gt; &lt;p&gt;The code inside the FullNameLabel control is not a rocket science. It simply declares a public property called Name that is of type FullName. It then emits the first name and last name separated by a white space in the overridden Render() method.&lt;/p&gt;  &lt;p&gt;Carefully notice the declaration of FullNameLabel class. It is marked with two special attributes viz. [DesignerSerializationVisibility] and [PersistenceMode]. The [DesignerSerializationVisibility] attribute governs whether a property will be serialized. The DesignerSerializationVisibility enumeration has four possible values viz. Default, Visible, Content, Hidden. The value of Content indicates that the contents of the property will be serialized. &lt;/p&gt;  &lt;p&gt;The [PersistenceMode] attribute governs how a property will be serialized. The PersistenceMode enumeration has four values namely Attribute, InnerProperty, InnerDefaultProperty and EncodedInnerDefaultProperty. The value of InnerProperty indicates that the Name property will be serialized as a nested tag of the custom control tag. &lt;/p&gt;  &lt;p class="Note"&gt;You can see details of other enumerated values of DesignerSerializationVisibility and PersistenceMode enumeration in &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink7" class="kLink" href="http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Arial" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Arial" class="kLink"&gt;MSDN&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; help.&lt;/p&gt;  &lt;p&gt;If you use the FullNameLabel control on a web form you should see its Name property in the property window as shown below:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.bipinjoshi.net/articles/content/Images/BK_Type_Converter_02.jpg"&gt;&lt;/p&gt; &lt;p&gt;Notice how the FirstName and LastName properties appear as sub-properties of Name property. The serialized markup of the control after the Name property is set looks like this:&lt;/p&gt;&lt;pre&gt;&amp;lt;cc1:FullNameLabel ID=&amp;quot;FullNameLabel1&amp;quot;  runat=&amp;quot;server&amp;quot; EnableTheming=&amp;quot;True&amp;quot;&amp;gt; &lt;strong&gt;&amp;lt;Name FirstName=&amp;quot;Nancy&amp;quot; LastName=&amp;quot;Davalio&amp;quot; /&amp;gt; &lt;/strong&gt;&amp;lt;/cc1:FullNameLabel&amp;gt;&lt;/pre&gt; &lt;p&gt;Notice how the Name tag appears as a nested tag of &amp;lt;FullNameLabel&amp;gt; tag. &lt;/p&gt; &lt;div&gt;In the next article of this series I will show how to create custom editors to set a property value. Stay tuned.&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;Source: &lt;a href="http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx"&gt;http://www.bipinjoshi.net/articles/c1eee649-4e4b-486a-9fd3-2151d6821f0e.aspx&lt;/a&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-8651238824272617686?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/8651238824272617686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=8651238824272617686' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/8651238824272617686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/8651238824272617686'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/supporting-complex-types-in-property.html' title='Supporting Complex Types in Property Window'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-4033691775890611167</id><published>2008-03-25T09:41:00.001+07:00</published><updated>2008-03-25T09:41:23.972+07:00</updated><title type='text'>Adding Multiple Rows in the GridView Control</title><content type='html'>&lt;span id="ctl00_cphCell1_datalistArticles_ctl01_lblArticleDescription"&gt; &lt;p align="left"&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Introduction:&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;A while back an article was published on &lt;/font&gt;&lt;a href="http://www.gridviewguy.com/"&gt;&lt;font size="2" face="Verdana"&gt;www.gridviewguy.com&lt;/font&gt;&lt;/a&gt;&lt;font size="2" face="Verdana"&gt; which explained how to add a single row at the bottom of the GridView control. You can read the article using &lt;a href="http://www.gridviewguy.com/ArticleDetails.aspx?articleID=98_Adding_a_New_Row_in_GridView"&gt;this&lt;/a&gt; link. Many readers were interested in the idea of adding multiple rows to the GridView. This article explains how to add multiple rows to the GridView control. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Populating the GridView Control: &lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The first task is to populate the GridView control. We will be using the LINQ to SQL Classes to populate the GridView but you can use any data container that you like. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;private void BindData()&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; NorthwindDataContext northwind = new NorthwindDataContext();&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; gvReport.DataSource = GetProducts(); &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; gvReport.DataBind(); &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // since the product list is long I am only selecting three products&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private List&amp;lt;Product&amp;gt; GetProducts()&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; NorthwindDataContext northwind = new NorthwindDataContext();&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; return (from p in northwind.Products&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; select p).Take(3).ToList&amp;lt;Product&amp;gt;(); &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The database is the &lt;strong&gt;Northwind&lt;/strong&gt; database and we are using the &lt;strong&gt;Products&lt;/strong&gt; table of the database. The &lt;font face="Courier New"&gt;GetProducts&lt;/font&gt; method returns the top three products from the Products table (You can return all the rows it does not really matter). &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Here is the ASPX part of the code: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;lt;asp:GridView ID=&amp;quot;gvReport&amp;quot; runat=&amp;quot;server&amp;quot; AutoGenerateColumns=&amp;quot;false&amp;quot;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Columns&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TemplateField HeaderText=&amp;quot;ProductName&amp;quot;&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;%# Eval(&amp;quot;ProductName&amp;quot;) %&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TextBox ID=&amp;quot;txtProductName&amp;quot; runat=&amp;quot;server&amp;quot; Visible=&amp;#39;&amp;lt;%# DoesProductExists( (string) Eval(&amp;quot;ProductName&amp;quot;))&amp;nbsp; %&amp;gt;&amp;#39; /&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:TemplateField&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TemplateField HeaderText=&amp;quot;CategoryID&amp;quot;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;lt;asp:DropDownList ID=&amp;quot;ddlCategories&amp;quot; DataSource=&amp;lt;%# GetCategories() %&amp;gt; DataTextField=&amp;quot;CategoryName&amp;quot; DataValueField=&amp;quot;id&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:TemplateField&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Columns&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:GridView&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The first column displays the "&lt;strong&gt;ProductName&lt;/strong&gt;". If the ProductName is not available then a TextBox is created which is used to enter a new ProductName. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The &lt;font face="Courier New"&gt;GetCategories&lt;/font&gt; method is used to populate the DropDownList in the second column of the GridView control. Here is the implementation of the GetCategories method. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp; protected List&amp;lt;Category&amp;gt; GetCategories()&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; NorthwindDataContext northwind = new NorthwindDataContext();&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; return northwind.Categories.ToList&amp;lt;Category&amp;gt;();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Adding New Rows to the GridView Control:&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Now, let's see how to add new rows to the GridView control. The rows are added using the "&lt;strong&gt;Add&lt;/strong&gt;" Button control. Here is the implementation of the add button click. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;// adds the new row &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void Button1_Click(object sender, EventArgs e)&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; Count += 1; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var list = GetProducts();&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; // add empty elements at the end of the list &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; list.AddRange(new Product[Count]); &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; gvReport.DataSource = list;&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; gvReport.DataBind(); &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Let's first talk about how we are going to add empty rows to the GridView control. Each time a button is clicked the postback is triggered. So, we need a way to know how many empty rows have to be created. We will use ViewState to store the number of rows that have to be created and then add the rows in the product list as empty products. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The &lt;strong&gt;Count&lt;/strong&gt; property in the button click code is used to store the number of empty rows to be created. Here is the implementation of the Count property. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;public int Count&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&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; if (ViewState[&amp;quot;Count&amp;quot;] == 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&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; return (int) ViewState[&amp;quot;Count&amp;quot;];&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; set&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; &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; ViewState[&amp;quot;Count&amp;quot;] = value; &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;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The &lt;font face="Courier New"&gt;list.AddRange(new Product[Count]);&lt;/font&gt; line is used to append the rows to the product list. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The effect is shown in the GIF Animation below: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;img src="http://www.gridviewguy.com/ArticleImages/VideoAddingMultipleGridViewRows.gif"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;&lt;font size="2" face="Verdana"&gt;I have also used UpdatePanel to eliminate the server postback. &lt;/font&gt;&lt;/p&gt; &lt;div&gt;&lt;font size="2" face="Verdana"&gt;I hope you liked the article, happy coding!&lt;/font&gt;&lt;/div&gt; &lt;div&gt;&lt;font face="Verdana"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;font face="Verdana"&gt;Author: &lt;a href="mailto:azamsharp@gmail.com"&gt;AzamSharp &lt;/a&gt;&lt;/font&gt;&lt;/div&gt; &lt;div&gt;&lt;font face="Verdana"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;font face="Verdana"&gt;Source: &lt;a href="http://gridviewguy.com/ArticleDetails.aspx?articleID=374_Adding_Multiple_Rows_in_the_GridView_Control"&gt;http://gridviewguy.com/ArticleDetails.aspx?articleID=374_Adding_Multiple_Rows_in_the_GridView_Control&lt;/a&gt;&lt;/font&gt;&lt;/div&gt; &lt;/span&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-4033691775890611167?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/4033691775890611167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=4033691775890611167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4033691775890611167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4033691775890611167'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/adding-multiple-rows-in-gridview_25.html' title='Adding Multiple Rows in the GridView Control'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-2514421411944908398</id><published>2008-03-22T11:09:00.001+07:00</published><updated>2008-03-22T11:09:54.923+07:00</updated><title type='text'>Building a Volta Control : A Flickr Widget</title><content type='html'>&lt;p&gt;By: &lt;span id="ctl00_ArticleInfo1_author"&gt;&lt;a href="http://dotnetslackers.com/community/members/TanzimSaqib.aspx"&gt;Tanzim Saqib&lt;/a&gt;&lt;/span&gt; &lt;span id="ctl00_ArticleInfo1_download"&gt;&lt;br&gt;&lt;a href="http://dotnetslackers.com/code/VoltaFlickrWidget.zip"&gt;Download Sample Code&lt;/a&gt;&lt;/span&gt; &lt;/p&gt;  &lt;p&gt;&lt;span id="ctl00_ArticleInfo1_desc"&gt;This article illustrates how to create a Volta control around Flickr, the popular image hosting service.&lt;/span&gt;&lt;/p&gt; &lt;div class="KonaBody"&gt; &lt;h3&gt;What is Volta? &lt;/h3&gt; &lt;p&gt;Microsoft Live Labs Volta is Microsoft&amp;#39;s emerging toolset that enables developers to build multi-tier web applications by applying familiar .NET techniques and patterns. The intended use of this toolset is for Developers to build web application as .NET client application, and then specify the portions of the codes that will run on the client and server side. The compiler then creates cross browser JavaScript, Web Services, communication, serialization, security etc. to tie the tiers together. This article is based on the first CTP of Volta considering its current limitations. We will see how we can create a Volta control that the compiler can convert into an AJAX Widget without requiring us writing a single line of JavaScript code. We will write code in our very familiar C# language. In this article, you will end up creating a Flickr widget like the one shown in figure 1. &lt;/p&gt;  &lt;h4&gt;Figure 1: The Flickr widget built using Volta &lt;/h4&gt; &lt;p&gt;&lt;img src="http://dotnetslackers.com/images/articleimages/VoltaFlickrWidgetDemo.jpg"&gt;&lt;/p&gt; &lt;p&gt;Currently Volta is at its first CTP release, which was made publicly available on December 5 last year. Volta requirements and the installer can be found at &lt;a href="http://labs.live.com/volta/download/" target="_blank"&gt;http://labs.live.com/volta/download/&lt;/a&gt; Since it&amp;#39;s just the first CTP, there are still a lot of limitations. I hope they will get over those in the next CTP or so. &lt;/p&gt;  &lt;h3&gt;The Specification of the Widget &lt;/h3&gt; &lt;p&gt;The widget will have the following features: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;The photos for a particular Flickr user will be shown in a 3x3 grid.&lt;/li&gt; &lt;li&gt;The tooltip of each of the photos will display the title of the image.&lt;/li&gt; &lt;li&gt;There will be &amp;quot;prev&amp;quot; and &amp;quot;next&amp;quot; buttons for navigation.&lt;/li&gt; &lt;li&gt;On click of each of the photos, a new window will open with the original Flickr source.&lt;/li&gt; &lt;li&gt;There will not be a single line of JavaScript code.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;The Flickr API &lt;/h3&gt; &lt;p&gt;Flickr is a very popular photo hosting and sharing service. It is considered to be one of the leading examples of Web 2.0 applications. Users of Flickr can host hundreds of photos and share them with others. Flickr allows users to tag their photos, which make them easy to find. It has some of the best photo management features, which let users control access to photos pretty efficiently. A few of the interesting features of Flickr are the possibility of marking photos as favourites, grouping photo pool and Flickr Interestingness. Flickr also offers users the ability to release images under certain common usage licenses. &lt;/p&gt;  &lt;p&gt;Flickr has an open API besides RSS and Atom feeds. The Flickr API offers numerous methods. It supports different popular request and response formats that should be familiar to the third party developers: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;REST&lt;/li&gt; &lt;li&gt;XML-RPC&lt;/li&gt; &lt;li&gt;SOAP&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;We choose REST because it is the simplest among others, and it is performed by simple HTTP GET or POST actions. &lt;/p&gt; &lt;h3&gt;The Flickr Methods &lt;/h3&gt; &lt;p&gt;The Flickr API exposes 115 methods so far. The methods are categorized in Authentication, Photos, User Activity, Photo Pool, Photo Upload and many more. Few of them are named as follows: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;flickr.photos.getInfo&lt;/li&gt; &lt;li&gt;flickr.photos.search&lt;/li&gt; &lt;li&gt;flickr.interestingness.getList&lt;/li&gt; &lt;li&gt;flickr.photos.transform.rotate&lt;/li&gt; &lt;li&gt;flickr.test.echo&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;A full listing can be found at: &lt;a href="http://www.flickr.com/services/api/" target="_blank"&gt;http://www.flickr.com/services/api/&lt;/a&gt;. &lt;/p&gt; &lt;h3&gt;The Flickr Request, Response format &lt;/h3&gt; &lt;p&gt;The general format of a Flickr request is: &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;&lt;a href="http://api.flickr.com/services/rest/"&gt;http://api.flickr.com/services/rest/&lt;/a&gt;?&lt;/span&gt;&lt;span class="attribute"&gt;api_key&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;__API_KEY__&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span class="attribute"&gt;method&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;__METHOD_NAME__&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span class="attribute"&gt;param1&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;value1&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span class="attribute"&gt;param2&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;value2&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t1"&gt;&lt;a href="http://api.flickr.com/services/rest/?api_key=__API_KEY__&amp;amp;method=__METHOD_NAME__&amp;amp;param1=value1&amp;amp;param2=value2"&gt;http://api.flickr.com/services/rest/?api_key=__API_KEY__&amp;amp;method=__METHOD_NAME__&amp;amp;param1=value1&amp;amp;param2=value2&lt;/a&gt; &lt;/textarea&gt;  &lt;p&gt;__API_KEY__ is replaced by the API key &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;&lt;a href="http://api.flickr.com/services/rest/"&gt;http://api.flickr.com/services/rest/&lt;/a&gt;?&lt;/span&gt;&lt;span class="attribute"&gt;api_key&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;9163070a740049b1bfe553864a4f1519&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span class="attribute"&gt;method&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;flickr&lt;/span&gt;&lt;span&gt;.interestingness.getList&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t2"&gt;&lt;a href="http://api.flickr.com/services/rest/?api_key=9163070a740049b1bfe553864a4f1519&amp;amp;method=flickr.interestingness.getList"&gt;http://api.flickr.com/services/rest/?api_key=9163070a740049b1bfe553864a4f1519&amp;amp;method=flickr.interestingness.getList&lt;/a&gt; &lt;/textarea&gt;  &lt;p&gt;The response of a REST query can be rendered by the browser. Simply copy the URL above and paste it into the browser&amp;#39;s address bar; then hit enter. You will see a response text somewhat like the following: &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="tag-name"&gt;xml&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;version&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;?&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;rsp&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;stat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;ok&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;photos&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;page&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;pages&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;perpage&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;100&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;total&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;500&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;photo&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;621909774&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;owner&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;30959251@N00&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;secret&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;70cdeec6f7&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;server&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1411&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;farm&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Yeah,&amp;nbsp;holidays!&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ispublic&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfriend&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfamily&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;photo&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;620373432&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;owner&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;80176513@N00&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;secret&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;7c9d5769ab&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;server&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1151&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;farm&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;In&amp;nbsp;the&amp;nbsp;Mood&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ispublic&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfriend&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfamily&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;photo&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;619761326&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;owner&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;50008412@N00&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;secret&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;5aec4bf2ec&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;server&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1037&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;farm&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Hear&amp;nbsp;me&amp;nbsp;roar!!!!&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ispublic&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfriend&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfamily&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;photo&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;619727916&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;owner&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;46355903@N00&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;secret&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;76680dafa6&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;server&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1146&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;farm&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Rain,&amp;nbsp;rain,&amp;nbsp;go&amp;nbsp;away,&amp;nbsp;I&amp;nbsp;want&amp;nbsp;to&amp;nbsp;do&amp;nbsp;some&amp;nbsp;Sunrise&amp;nbsp;photos&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ispublic&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;isfriend&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfamily&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;photo&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;620355782&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;owner&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;42009080@N00&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;secret&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;148cbdb6b0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;server&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1145&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;farm&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Beneath&amp;nbsp;A&amp;nbsp;Black&amp;nbsp;Sky&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ispublic&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfriend&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfamily&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;photo&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;621726130&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;owner&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;35373726@N00&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;secret&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;6b3d8fa0ca&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;server&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1114&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;farm&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ispublic&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfriend&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;isfamily&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;...&amp;nbsp;...&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;photos&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;rsp&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t3"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt; &amp;lt;rsp stat=&amp;quot;ok&amp;quot;&amp;gt; &amp;lt;photos page=&amp;quot;1&amp;quot; pages=&amp;quot;5&amp;quot; perpage=&amp;quot;100&amp;quot; total=&amp;quot;500&amp;quot;&amp;gt;  &amp;lt;photo id=&amp;quot;621909774&amp;quot; owner=&amp;quot;30959251@N00&amp;quot; secret=&amp;quot;70cdeec6f7&amp;quot; server=&amp;quot;1411&amp;quot;    farm=&amp;quot;2&amp;quot; title=&amp;quot;Yeah, holidays!&amp;quot; ispublic=&amp;quot;1&amp;quot; isfriend=&amp;quot;0&amp;quot; isfamily=&amp;quot;0&amp;quot; /&amp;gt;  &amp;lt;photo id=&amp;quot;620373432&amp;quot; owner=&amp;quot;80176513@N00&amp;quot; secret=&amp;quot;7c9d5769ab&amp;quot; server=&amp;quot;1151&amp;quot;     farm=&amp;quot;2&amp;quot; title=&amp;quot;In the Mood&amp;quot; ispublic=&amp;quot;1&amp;quot; isfriend=&amp;quot;0&amp;quot; isfamily=&amp;quot;0&amp;quot; /&amp;gt;  &amp;lt;photo id=&amp;quot;619761326&amp;quot; owner=&amp;quot;50008412@N00&amp;quot; secret=&amp;quot;5aec4bf2ec&amp;quot; server=&amp;quot;1037&amp;quot;    farm=&amp;quot;2&amp;quot; title=&amp;quot;Hear me roar!!!!&amp;quot; ispublic=&amp;quot;1&amp;quot; isfriend=&amp;quot;0&amp;quot; isfamily=&amp;quot;0&amp;quot; /&amp;gt;  &amp;lt;photo id=&amp;quot;619727916&amp;quot; owner=&amp;quot;46355903@N00&amp;quot; secret=&amp;quot;76680dafa6&amp;quot; server=&amp;quot;1146&amp;quot; farm=&amp;quot;2&amp;quot;     title=&amp;quot;Rain, rain, go away, I want to do some Sunrise photos&amp;quot; ispublic=&amp;quot;1&amp;quot;     isfriend=&amp;quot;0&amp;quot; isfamily=&amp;quot;0&amp;quot; /&amp;gt; &amp;lt;photo id=&amp;quot;620355782&amp;quot; owner=&amp;quot;42009080@N00&amp;quot; secret=&amp;quot;148cbdb6b0&amp;quot; server=&amp;quot;1145&amp;quot; farm=&amp;quot;2&amp;quot;     title=&amp;quot;Beneath A Black Sky&amp;quot; ispublic=&amp;quot;1&amp;quot; isfriend=&amp;quot;0&amp;quot; isfamily=&amp;quot;0&amp;quot; /&amp;gt; &amp;lt;photo id=&amp;quot;621726130&amp;quot; owner=&amp;quot;35373726@N00&amp;quot; secret=&amp;quot;6b3d8fa0ca&amp;quot; server=&amp;quot;1114&amp;quot; farm=&amp;quot;2&amp;quot;    title=&amp;quot;&amp;quot; ispublic=&amp;quot;1&amp;quot; isfriend=&amp;quot;0&amp;quot; isfamily=&amp;quot;0&amp;quot; /&amp;gt;  ... ...  &amp;lt;/photos&amp;gt; &amp;lt;/rsp&amp;gt; &lt;/textarea&gt;  &lt;p&gt;As you see the response is pretty straightforward. It simply has a bunch of &lt;code&gt;photo&lt;/code&gt; tags and each of the tags has information about that particular photo. A &lt;code&gt;photo&lt;/code&gt; tag has the unique identifier of the photo, owner identifier, server information and also a title. In our widget, we need to parse such XML and display the photos. &lt;/p&gt;  &lt;p&gt;Note the &lt;code&gt;rsp&lt;/code&gt; tag with a &lt;code&gt;stat&lt;/code&gt; attribute that has &lt;code&gt;ok&lt;/code&gt; as value. It means the API call was completely errorless and successful. Let us make some mistakes intentionally to see how Flickr reacts. Hit the browser using the previous URL with a wrong API Key. You will receive an XML as response like the following: &lt;/p&gt;  &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="tag-name"&gt;xml&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;version&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;?&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;rsp&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;stat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;fail&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;err&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;code&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;100&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;msg&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Invalid&amp;nbsp;API&amp;nbsp;Key&amp;nbsp;(Key&amp;nbsp;not&amp;nbsp;found)&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;rsp&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t4"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;  &amp;lt;rsp stat=&amp;quot;fail&amp;quot;&amp;gt;   &amp;lt;err code=&amp;quot;100&amp;quot; msg=&amp;quot;Invalid API Key (Key not found)&amp;quot; /&amp;gt; &amp;lt;/rsp&amp;gt; &lt;/textarea&gt;  &lt;p&gt;Here the &lt;code&gt;stat&lt;/code&gt; attribute has &lt;code&gt;fail&lt;/code&gt; as value, which means some kind of problem has occurred during the API call and the Flickr API notifies it so that the code can decide whether it should crawl any further or not. &lt;/p&gt;  &lt;h3&gt;The User NSID &lt;/h3&gt; &lt;p&gt;User NSID is an alphanumeric string which uniquely identifies a user. It is often useful, especially in our case where our widget will display the photos of a particular user. In order to retrieve the NSID for a user, Flickr offers a method named &lt;code&gt;flickr.people.findByUsername&lt;/code&gt; which takes the Flickr screen name of the user and returns an XML like the following: &lt;/p&gt;  &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="tag-name"&gt;xml&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;version&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;encoding&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;?&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;rsp&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;stat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;ok&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;user&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;9198206@N07&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;nsid&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;9198206@N07&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;username&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;your_screen_name&lt;/span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;username&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;user&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;rsp&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t5"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt; &amp;lt;rsp stat=&amp;quot;ok&amp;quot;&amp;gt;   &amp;lt;user id=&amp;quot;9198206@N07&amp;quot; nsid=&amp;quot;9198206@N07&amp;quot;&amp;gt;     &amp;lt;username&amp;gt;your_screen_name&amp;lt;/username&amp;gt;   &amp;lt;/user&amp;gt; &amp;lt;/rsp&amp;gt; &lt;/textarea&gt;  &lt;h3&gt;The Solution Structure &lt;/h3&gt; &lt;p&gt;First of all, create a new Volta Application and name it &lt;code&gt;VoltaFlickrWidgetDemo&lt;/code&gt;. Then, add a new Volta Control application named &lt;code&gt;VoltaFlickrWidget&lt;/code&gt; to the solution. Add a class to the Volta control project named FlickrHelper.cs. This class contains very useful methods that fetch Flickr photo data and make them easily accessible by the control. Now include the &lt;code&gt;VoltaFlickrWidget&lt;/code&gt; project in the References of the &lt;code&gt;VoltaFlickrWidgetDemo&lt;/code&gt; project. The resulting solution structure will be like the one shown in the following figure. &lt;/p&gt;  &lt;h4&gt;Figure 2: Solution Structure &lt;/h4&gt; &lt;p&gt;&lt;img src="http://dotnetslackers.com/images/articleimages/SolutionStructure.jpg"&gt;&lt;/p&gt; &lt;h3&gt;The Flickr Volta Control &lt;/h3&gt; &lt;p&gt;The Flickr Volta control we are going to develop should be easy to add to the Volta page considering that there is a div element with an id of &lt;code&gt;divWidgetContainer&lt;/code&gt; present in the Volta page: &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;var&amp;nbsp;divWidgetConatiner&amp;nbsp;=&amp;nbsp;Document.GetById&amp;lt;Div&amp;gt;(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;divWidgetContainer&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;VoltaControl1&amp;nbsp;flickrWidget&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;VoltaControl1(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;screen_name&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;9149b1bfe387273833553864a4f1519&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Flickr&amp;nbsp;Widget&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;300,&amp;nbsp;270);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;flickrWidget.AddToDiv(divWidgetConatiner);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;flickrWidget.DownloadPhotos();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t6"&gt;var divWidgetConatiner = Document.GetById&amp;lt;Div&amp;gt;(&amp;quot;divWidgetContainer&amp;quot;);  VoltaControl1 flickrWidget = new VoltaControl1(&amp;quot;screen_name&amp;quot;, &amp;quot;9149b1bfe387273833553864a4f1519&amp;quot;, &amp;quot;Flickr Widget&amp;quot;, 300, 270);  flickrWidget.AddToDiv(divWidgetConatiner); flickrWidget.DownloadPhotos(); &lt;/textarea&gt;  &lt;p&gt;Here &lt;code&gt;VoltaControl1&lt;/code&gt; is the Flickr control we are going to build. Sorry for the naming, but Volta is still immature and can&amp;#39;t rename the underlying HTML file of the Volta Control which we will discuss later. Thus, instead of making it confusing, we are keeping it called &lt;code&gt;VoltaControl1&lt;/code&gt;. In the above code snippet, &lt;code&gt;VoltaControl1&lt;/code&gt; is initialized with the screen name, API key, control&amp;#39;s title, height and width properties. The &lt;code&gt;AddToDiv&lt;/code&gt; method of the control adds itself to the div passed as a parameter and then the &lt;code&gt;DownloadPhotos&lt;/code&gt; method starts downloading the photos. As soon as &lt;code&gt;AddToDiv&lt;/code&gt; is called, the control&amp;#39;s HTML file content is injected into the DOM, and HTML elements become accessible like so: &lt;/p&gt;  &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;Document.GetById&amp;lt;Div&amp;gt;(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;divSomeDiv&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t7"&gt;Document.GetById&amp;lt;Div&amp;gt;(&amp;quot;divSomeDiv&amp;quot;); &lt;/textarea&gt;  &lt;h3&gt;The FlickrHelper &lt;/h3&gt; &lt;p&gt;The FlickrHelper class basically performs two operations. One of them is retrieving the NSID of the user against the screen name; and the other is fetching the photo collection of the specified user. The following &lt;code&gt;GetNSID&lt;/code&gt; method performs an Asynchronous REST call to the Flickr API and receives the NSID back: &lt;/p&gt;  &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;GetNSID()&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IHttpRequest&amp;nbsp;request&amp;nbsp;=&amp;nbsp;HttpRequestFactory.Create();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;request.AsyncSend(&lt;span class="string"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;URL_USER_NSID&amp;nbsp;+&amp;nbsp;ScreenName,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;.Empty,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;delegate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;response)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&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;OnNsidLoaded(&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;NsidLoadedEventArgs(response));&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t8"&gt;public void GetNSID() {     IHttpRequest request = HttpRequestFactory.Create();     request.AsyncSend(&amp;quot;POST&amp;quot;, URL_USER_NSID + ScreenName, string.Empty,         delegate(string response)         {             OnNsidLoaded(new NsidLoadedEventArgs(response));         }); } &lt;/textarea&gt;  &lt;p&gt;Both the &lt;code&gt;IHttpRequest&lt;/code&gt; interface and the &lt;code&gt;HttpRequestFactory&lt;/code&gt; class can be found in the &lt;code&gt;Microsoft.LiveLabs.Volta.MultiTier&lt;/code&gt; namespace. The &lt;code&gt;AsyncSend&lt;/code&gt; method performs the asynchronous call and then calls back the delegate, inside of which the &lt;code&gt;OnNsidLoaded&lt;/code&gt; event is fired to notify the user of the FlickrHelper class that the NSID data has just arrived. An instance of the &lt;code&gt;NsidLoadedEventArgs&lt;/code&gt; is passed to the subscriber of that event to make the NSID available after parsing the necessary XML: &lt;/p&gt;  &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;NsidLoadedEventArgs&amp;nbsp;:&amp;nbsp;EventArgs&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;Nsid&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;get&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;set&lt;/span&gt;&lt;span&gt;;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;NsidLoadedEventArgs(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;response)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;xdocument&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;XmlDocument();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xdocument.LoadXml(response);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;xnUser&amp;nbsp;=&amp;nbsp;xdocument.GetElementsByTagName(&lt;span class="string"&gt;&amp;quot;user&amp;quot;&lt;/span&gt;&lt;span&gt;)[0];&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(xnUser&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&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;&lt;span class="keyword"&gt;throw&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Incorrect&amp;nbsp;screenName&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&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;var&amp;nbsp;xelUser&amp;nbsp;=&amp;nbsp;xnUser&amp;nbsp;&lt;span class="keyword"&gt;as&lt;/span&gt;&lt;span&gt;&amp;nbsp;XmlElement;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&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;Nsid&amp;nbsp;=&amp;nbsp;xelUser.GetAttribute(&lt;span class="string"&gt;&amp;quot;nsid&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t9"&gt;public class NsidLoadedEventArgs : EventArgs {     public string Nsid { get; set; }      public NsidLoadedEventArgs(string response)     {         var xdocument = new XmlDocument();         xdocument.LoadXml(response);         var xnUser = xdocument.GetElementsByTagName(&amp;quot;user&amp;quot;)[0];          if (xnUser == null)             throw new Exception(&amp;quot;Incorrect screenName&amp;quot;);         else         {             var xelUser = xnUser as XmlElement;             Nsid = xelUser.GetAttribute(&amp;quot;nsid&amp;quot;);         }     } } &lt;/textarea&gt;  &lt;p&gt;Similarly, an asynchronous call is made for fetching photo feed: &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;DownloadPhotos(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;nsid)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IHttpRequest&amp;nbsp;request&amp;nbsp;=&amp;nbsp;HttpRequestFactory.Create();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;request.AsyncSend(&lt;span class="string"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;URL_PHOTOS&amp;nbsp;+&amp;nbsp;nsid,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;.Empty,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;delegate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;response)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&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;OnPhotosLoaded(&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;PhotosLoadedEventArgs(response,&amp;nbsp;nsid));&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t10"&gt;public void DownloadPhotos(string nsid) {     IHttpRequest request = HttpRequestFactory.Create();     request.AsyncSend(&amp;quot;POST&amp;quot;, URL_PHOTOS + nsid, string.Empty,         delegate(string response)         {             OnPhotosLoaded(new PhotosLoadedEventArgs(response, nsid));         }); } &lt;/textarea&gt;  &lt;p&gt;In the above code snippet, an instance of &lt;code&gt;PhotoLoadedEventArgs&lt;/code&gt; is passed to the subscriber. In this case the photo URL collection is sent back using a &lt;code&gt;Dictionary&lt;/code&gt; object: &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;PhotosLoadedEventArgs&amp;nbsp;:&amp;nbsp;EventArgs&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;Dictionary&amp;lt;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp;PhotoPool&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;get&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;set&lt;/span&gt;&lt;span&gt;;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;PhotosLoadedEventArgs(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;response,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;nsid)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//&amp;nbsp;code&amp;nbsp;edited&amp;nbsp;to&amp;nbsp;save&amp;nbsp;space&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t11"&gt;public class PhotosLoadedEventArgs : EventArgs {     public Dictionary&amp;lt;int, string&amp;gt; PhotoPool { get; set; }      public PhotosLoadedEventArgs(string response, string nsid)     {         ...         // code edited to save space     } } &lt;/textarea&gt;  &lt;h3&gt;The Control Logic &lt;/h3&gt; &lt;p&gt;The contents of VoltaControl1.cs file is basically HTML manipulation, so most of it is self-explanatory and doesn&amp;#39;t need further discussion. Yet there are few points to ponder. The most important part is the &lt;code&gt;DownloadPhotos&lt;/code&gt; method: &lt;/p&gt;  &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;DownloadPhotos()&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_WidgetContent.InnerHtml&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;&amp;quot;&amp;lt;br&amp;nbsp;/&amp;gt;&amp;lt;center&amp;gt;&amp;lt;i&amp;gt;Downloading&amp;nbsp;photos...&amp;lt;/i&amp;gt;&amp;lt;/center&amp;gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flickrHelper.NsidLoaded&amp;nbsp;+=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;NsidLoadedEventHandler(flickrHelper_NsidLoaded);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flickrHelper.GetNSID();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t12"&gt;public void DownloadPhotos() {     _WidgetContent.InnerHtml = &amp;quot;&amp;lt;br /&amp;gt;&amp;lt;center&amp;gt;&amp;lt;i&amp;gt;Downloading photos...&amp;lt;/i&amp;gt;&amp;lt;/center&amp;gt;&amp;quot;;     flickrHelper.NsidLoaded += new NsidLoadedEventHandler(flickrHelper_NsidLoaded);     flickrHelper.GetNSID(); } &lt;/textarea&gt;  &lt;p&gt;It registers the &lt;code&gt;NsidLoaded&lt;/code&gt; event of FlickrHelper, which is handled by &lt;code&gt;flickrHelper_NsidLoaded&lt;/code&gt;. Then, the &lt;code&gt;GetNSID&lt;/code&gt; method is called. Therefore, as soon as the NSID data is available, it will call the &lt;code&gt;flickrHelper_NsidLoaded&lt;/code&gt; method to handle the data: &lt;/p&gt;  &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;flickrHelper_NsidLoaded(&lt;/span&gt;&lt;span class="keyword"&gt;object&lt;/span&gt;&lt;span&gt;&amp;nbsp;sender,&amp;nbsp;NsidLoadedEventArgs&amp;nbsp;e)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(e.Nsid&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;throw&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;Exception(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Invalid&amp;nbsp;NSID&amp;nbsp;supplied.&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_Nsid&amp;nbsp;=&amp;nbsp;e.Nsid;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flickrHelper.PhotosLoaded&amp;nbsp;+=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;PhotosLoadedEventHandler(flickrHelper_PhotosLoaded);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flickrHelper.DownloadPhotos(_Nsid);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flickrHelper.NsidLoaded&amp;nbsp;-=&amp;nbsp;flickrHelper_NsidLoaded;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t13"&gt;void flickrHelper_NsidLoaded(object sender, NsidLoadedEventArgs e) {     if (e.Nsid == null)         throw new Exception(&amp;quot;Invalid NSID supplied.&amp;quot;);     else     {         _Nsid = e.Nsid;         flickrHelper.PhotosLoaded += new PhotosLoadedEventHandler(flickrHelper_PhotosLoaded);         flickrHelper.DownloadPhotos(_Nsid);     }      flickrHelper.NsidLoaded -= flickrHelper_NsidLoaded; } &lt;/textarea&gt;  &lt;p&gt;Unlike the NSID, the &lt;code&gt;DownloadPhotos&lt;/code&gt; method of FlickrHelper returns a Dictionary of photos URLs and the &lt;code&gt;LoadPhotos&lt;/code&gt; method iterates through the photos and displays them in a 3x3 grid using a typical logic for pagination. &lt;/p&gt;  &lt;h3&gt;Construction of the Volta Page &lt;/h3&gt; &lt;p&gt;The construction of the Volta page is simple. The default page would do, but for our project we need an extra div with an id of &lt;code&gt;divWidgetContainer&lt;/code&gt;. Moreover, we will add some other HTML code to beautify it. As for the Volta control, we are keeping the Volta page called &lt;code&gt;VoltaPage1&lt;/code&gt;. We will use some CSS classes, and add a CSS file named Style.css in the root of the Volta application. In the current release of Volta, CSS files are not automatically discovered even if you add it in the page&amp;#39;s HTML as links. To make the Style.css file usable by the Volta page, perform the following steps: &lt;/p&gt;  &lt;ol&gt; &lt;li&gt;Right click on the Style.css from the Solution Explorer and choose Properties&lt;/li&gt; &lt;li&gt;Set the Build Action as Embedded Resource&lt;/li&gt; &lt;li&gt;Open the VoltaPage1.Designer.cs file and add the following line before &lt;code&gt;namespace&lt;/code&gt; &lt;code&gt;VoltaFlickrWidgetDemo&lt;/code&gt;:&lt;/li&gt;&lt;/ol&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;[assembly:&amp;nbsp;VoltaFile(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Style.css&amp;quot;&lt;/span&gt;&lt;span&gt;)]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t14"&gt;[assembly: VoltaFile(&amp;quot;Style.css&amp;quot;)] &lt;/textarea&gt;  &lt;p&gt;As stated before, the control is very convenient to use: &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;VoltaControl1&amp;nbsp;flickrWidget&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;VoltaControl1(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;ajaxwidget&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="string"&gt;&amp;quot;9163070a740049b1bfe553864a4f1519&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Flickr&amp;nbsp;Widget&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;300,&amp;nbsp;270);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;flickrWidget.AddToDiv(divWidgetConatiner);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;flickrWidget.DownloadPhotos();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t15"&gt;VoltaControl1 flickrWidget = new VoltaControl1(&amp;quot;ajaxwidget&amp;quot;,     &amp;quot;9163070a740049b1bfe553864a4f1519&amp;quot;, &amp;quot;Flickr Widget&amp;quot;, 300, 270);  flickrWidget.AddToDiv(divWidgetConatiner); flickrWidget.DownloadPhotos(); &lt;/textarea&gt;  &lt;p&gt;This is pretty much it. When you download and run this project, you will see Flickr REST calls and photo navigation all performed within an AJAX application created without writing any JavaScript code. Volta generated the necessary client code for us to run the application in multiple browsers. &lt;/p&gt;  &lt;h3&gt;Summary &lt;/h3&gt; &lt;p&gt;You have learned how to create a Volta control around the Flickr API. The code was purely written in .NET, yet we achieved complete AJAX functionality without writing a single line of JavaScript code introducing typical ContentProxy kind of things. &lt;/p&gt;  &lt;p&gt;Source: &lt;a href="http://dotnetslackers.com/articles/aspnet/BuildingAVoltaControlAFlickrWidget.aspx"&gt;http://dotnetslackers.com/articles/aspnet/BuildingAVoltaControlAFlickrWidget.aspx&lt;/a&gt;&lt;/p&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-2514421411944908398?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/2514421411944908398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=2514421411944908398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/2514421411944908398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/2514421411944908398'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/building-volta-control-flickr-widget.html' title='Building a Volta Control : A Flickr Widget'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-4304384346305908604</id><published>2008-03-21T23:30:00.001+07:00</published><updated>2008-03-21T23:30:41.178+07:00</updated><title type='text'>Extending the GridView to Include Sort Arrows</title><content type='html'>&lt;p&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;br&gt;Before &lt;a href="http://aspnet.4guysfromrolla.com/2.0/"&gt;ASP.NET version 2.0&lt;/a&gt; was released, I &lt;a href="http://www.4guysfromrolla.com/ASPScripts/Goto.asp?ID=148"&gt;wrote a book&lt;/a&gt; and dozens of articles on the DataGrid control, which was the most functional data Web control in the &lt;a href="http://aspnet.4guysfromrolla.com/1.x/"&gt;ASP.NET 1.x&lt;/a&gt; toolbox. While the DataGrid still exists in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 2.0, the GridView control serves as a much more functional and feature-rich choice. The GridView can be bound to data source controls like the SqlDataSource and ObjectDataSource, and paging, sorting, editing, and deleting can be implemented without having to write a single line of code. &lt;/p&gt;  &lt;p&gt;While the DataGrid (and GridView) offer built-in sorting support, there is no visual feedback as to what column the data is sorted by. In &lt;a href="http://aspnet.4guysfromrolla.com/articles/061505-1.aspx"&gt;Part 18&lt;/a&gt; of the &lt;a href="http://aspnet.4guysfromrolla.com/articles/040502-1.aspx"&gt;An Extensive Examination of the DataGrid Web Control&lt;/a&gt; article series, I showed how to dynamically update a sortable DataGrid&amp;#39;s header columns so that an up or down arrow image would appear next to the sorted column name depending on whether the column was sorted ascendingly or descendingly (view a &lt;a href="http://aspnet.4guysfromrolla.com/demos/dgExample37.aspx"&gt;live demo&lt;/a&gt;). This was accomplished by programmatically looping through the DataGrid&amp;#39;s &lt;code&gt;Columns&lt;/code&gt; collection and adding the up or down arrow image to column whose &lt;code&gt;SortExpression&lt;/code&gt; value matched the DataGrid&amp;#39;s &lt;code&gt;SortExpression&lt;/code&gt;. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;center&gt;&lt;img border="1" alt="A down arrow image is shown in the Price column because the data is sorted in descending order, by price." src="http://aspnet.4guysfromrolla.com/images/UpDownSortImage1.png" width="326" height="126"&gt; &lt;/center&gt;  &lt;div&gt;I recently needed to implement this functionality in a GridView control. Rather than adding this code to an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page, like I did with the DataGrid demo, I decided to instead create a custom Web server control that extended the GridView control, adding the necessary functionality. In this article we will look at the steps for building such a custom control as well as how to use the control in an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page. The custom control&amp;#39;s complete source code and a demo application are available for download at the end of this article. Read on to learn more! &lt;/div&gt;  &lt;div&gt; &lt;p&gt;&lt;b&gt;A Quick Primer on GridView Sorting&lt;/b&gt;&lt;br&gt;The GridView control makes sorting a breeze. Simply set the grid&amp;#39;s &lt;a href="http://msdn2.microsoft.com/en-US/library/system.web.ui.webcontrols.gridview.allowsorting.aspx"&gt;&lt;code&gt;AllowSorting&lt;/code&gt; property&lt;/a&gt; to True. Doing so renders each column&amp;#39;s header as a LinkButton. When this LinkButton is clicked, a postback ensues and the GridView&amp;#39;s &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sorting.aspx"&gt;&lt;code&gt;Sorting&lt;/code&gt; event&lt;/a&gt; is fired. If the GridView is bound to a data source control that supports sorting, the GridView will internally re-bind to the data source using the new sort order. If you have programmatically bound data to the GridView, then you will need to create an event handler for the &lt;code&gt;Sorting&lt;/code&gt; event, and manually sort and re-bind the data. After the &lt;code&gt;Sorting&lt;/code&gt; event has fired and the data has been re-sorted, the GridView fires its &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sorted.aspx"&gt;&lt;code&gt;Sorted&lt;/code&gt; event&lt;/a&gt;, thereby completing the sorting workflow. &lt;/p&gt;  &lt;p&gt;Each column in the GridView has a &lt;code&gt;SortExpression&lt;/code&gt; property that indicates the data field by which the data should be sorted if that column&amp;#39;s sorting LinkButton is clicked. When the LinkButton in a column header is clicked, the GridView sets its &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sortexpression.aspx"&gt;&lt;code&gt;SortExpression&lt;/code&gt; property&lt;/a&gt; value to the value of the clicked column&amp;#39;s &lt;code&gt;SortExpression&lt;/code&gt;. If the GridView&amp;#39;s &lt;code&gt;SortExpression&lt;/code&gt; matches the &lt;code&gt;SortExpression&lt;/code&gt; of the sorted column, then the GridView&amp;#39;s &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sortdirection.aspx"&gt;&lt;code&gt;SortDirection&lt;/code&gt; property&lt;/a&gt; is toggled. This functionality enables the GridView control to provide built-in, bi-directional sorting. &lt;/p&gt;  &lt;p&gt;The following diagram depicts the sorting workflow, including the GridView&amp;#39;s assignment of its &lt;code&gt;SortExpression&lt;/code&gt; and &lt;code&gt;SortDirection&lt;/code&gt; properties. Keep in mind that the entire process is kicked off by the user clicking a LinkButton in one of the sortable column&amp;#39;s headers, and completes by displaying the data in the requested sorted order. So, from the end user&amp;#39;s perspective, she clicks the text in a particular column header and the data is sorted by that column. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;center&gt;&lt;img border="0" alt="The GridView&amp;#39;s sorting workflow." src="http://aspnet.4guysfromrolla.com/images/SortingWorkflow.png" width="433" height="376"&gt; &lt;/center&gt; &lt;p&gt;For more information on sorting with the GridView, along with a downloadable demo, check out the &lt;a href="http://asp.net/learn/data-access/tutorial-24-vb.aspx"&gt;Paging and Sorting Report Data&lt;/a&gt; tutorial. &lt;/p&gt; &lt;p&gt;&lt;b&gt;Creating a Custom Server Control that Extends the GridView&lt;/b&gt;&lt;br&gt;When I implemented the up and down arrow images for the DataGrid control in &lt;a href="http://aspnet.4guysfromrolla.com/articles/061505-1.aspx"&gt;Part 18&lt;/a&gt; of the &lt;a href="http://aspnet.4guysfromrolla.com/articles/040502-1.aspx"&gt;An Extensive Examination of the DataGrid Web Control&lt;/a&gt; article series, I put the code that added (or removed) the arrow images in the &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page&amp;#39;s code-behind class. Specifically, the code enumerated the DataGrid&amp;#39;s &lt;code&gt;Columns&lt;/code&gt; collection and, for every column, started by removing any &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; elements that were present in the &lt;code&gt;HeaderText&lt;/code&gt;. This &amp;quot;cleaned out&amp;quot; the up or down arrow image from &lt;i&gt;all&lt;/i&gt; columns. After removing any &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; elements, the code checked to see if the current column&amp;#39;s &lt;code&gt;SortExpression&lt;/code&gt; matched the DataGrid&amp;#39;s &lt;code&gt;SortExpression&lt;/code&gt;. If so, then an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element was tacked on to the end of the column&amp;#39;s &lt;code&gt;HeaderText&lt;/code&gt;, displaying the up or down arrow image depending on whether the data was being sorted in ascending or descending order. &lt;/p&gt;  &lt;p&gt;Like the DataGrid, the GridView has a &lt;code&gt;Columns&lt;/code&gt; collection; each column has a &lt;code&gt;SortExpression&lt;/code&gt;; the GridView has &lt;code&gt;SortExpression&lt;/code&gt; and &lt;code&gt;SortDirection&lt;/code&gt; properties. In short, I could have implemented the up and down arrow images in the GridView using code in the &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page very similar to that used for the DataGrid. However, I decided that instead of having to write code for each page where I wanted to show up and down arrow images, I decided to instead build a custom server control that extended the GridView control. I could then bake in the necessary code by overriding the necessary GridView methods. &lt;/p&gt;  &lt;p&gt;To create a custom server control that extends an existing control, create a public class that derives from the Web control that you want to extend. I created a class named &lt;code&gt;GridView&lt;/code&gt; in my &lt;code&gt;skmControls2&lt;/code&gt; Class Library project. (The &lt;code&gt;skmControls2&lt;/code&gt; Class Library project was first created and discussed in &lt;a href="http://aspnet.4guysfromrolla.com/articles/103107-1.aspx"&gt;Creating a TextBox Word / Character Counter Control&lt;/a&gt;.) &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;public class GridView : &lt;b&gt;System.Web.UI.WebControls.GridView&lt;/b&gt;&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &lt;i&gt;Override necessary GridView methods here&lt;/i&gt; ...&lt;br&gt;} &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;The GridView has a &lt;code&gt;virtual&lt;/code&gt; &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.initializerow.aspx"&gt;&lt;code&gt;InitializeRow&lt;/code&gt; method&lt;/a&gt; that is called each time a row is added to the GridView, including the header row. My first thought was to override this method and, for the header row, enumerate the fields and update each column&amp;#39;s &lt;code&gt;HeaderText&lt;/code&gt; appropriately (removing any image markup first, and then adding the up or down arrow image for the sorted row). However, if you attempt to update a GridView&amp;#39;s field&amp;#39;s properties during the databinding stage, the field reports to the GridView that its state has been changed and that the data needs to be re-bound. Consequently, I ended up stuck in an infinite loop: &lt;/p&gt;  &lt;ol&gt; &lt;li&gt;Databinding would commence&lt;/li&gt; &lt;li&gt;The &lt;code&gt;InitializeRow&lt;/code&gt; method would be executed for the header row&lt;/li&gt; &lt;li&gt;I&amp;#39;d update the &lt;code&gt;HeaderText&lt;/code&gt; for the cells in the header row&lt;/li&gt; &lt;li&gt;Updating the &lt;code&gt;HeaderText&lt;/code&gt; would signal the GridView to re-bind its data, taking us back to Step 1! Eep.&lt;/li&gt;&lt;/ol&gt;Instead, I needed to modify the &lt;code&gt;HeaderText&lt;/code&gt; properties either before or after the databinding process. After some thought, I realized that I really only needed to update the &lt;code&gt;HeaderText&lt;/code&gt; properties after the data has been sorted. The GridView&amp;#39;s &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.onsorted.aspx"&gt;&lt;code&gt;OnSorted&lt;/code&gt; method&lt;/a&gt; is what raises the &lt;code&gt;Sorted&lt;/code&gt; event, which occurs after the data has been sorted. Therefore, I decided to override this method and update the &lt;code&gt;HeaderText&lt;/code&gt; properties there.  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;public class GridView : System.Web.UI.WebControls.GridView&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;protected override void OnSorted(EventArgs e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string imgArrowUp = ...;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string imgArrowDown = ...;&lt;br&gt; &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;foreach (DataControlField field in this.Columns)&lt;br&gt;&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;// strip off the old ascending/descending icon&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int iconPosition = field.HeaderText.IndexOf(@&amp;quot; &amp;lt;img border=&amp;quot;&amp;quot;0&amp;quot;&amp;quot; src=&amp;quot;&amp;quot;&amp;quot;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (iconPosition &amp;gt; 0)&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;field.HeaderText = field.HeaderText.Substring(0, iconPosition);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// See where to add the sort ascending/descending icon&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (field.SortExpression == this.SortExpression)&lt;br&gt; &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;if (this.SortDirection == SortDirection.Ascending)&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;field.HeaderText += imgArrowUp;&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;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;field.HeaderText += imgArrowDown;&lt;br&gt;&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;}&lt;br&gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.OnSorted(e);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;} &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;The overridden &lt;code&gt;OnSorted&lt;/code&gt; method starts by defining the URLs for the up and down arrow images. We&amp;#39;ll discuss how these image URLs are determined later on in this article. Next, the GridView&amp;#39;s &lt;code&gt;Columns&lt;/code&gt; collection is enumerated. For each column, if there is an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element it is stripped off. Next, a check is performed to see if the current column&amp;#39;s &lt;code&gt;SortExpression&lt;/code&gt; matches the GridView&amp;#39;s. If so, the HTML to display the up or down arrow image is appended to the column&amp;#39;s &lt;code&gt;HeaderText&lt;/code&gt; depending on the value of the GridView&amp;#39;s &lt;code&gt;SortDirection&lt;/code&gt; property. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;An HTML Encoding Gotcha&lt;/b&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt; &lt;table class="noteBox" align="center"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;th&gt;This Control Has Been Enhanced!&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;The &amp;quot;HTML Encoding Gotcha&amp;quot; outlined here is no longer an issue with the enhancements made to this control on February 6th, 2008. For more information on these enhancements, see: &lt;a href="http://aspnet.4guysfromrolla.com/articles/020608-1.aspx"&gt;Improving the Sort Arrows GridView Control&lt;/a&gt;. &lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;One subtlety that I quickly stumbled upon when testing, is that the BoundField HTML encodes its &lt;code&gt;HeaderText&lt;/code&gt;&amp;#39;s content, by default. That is, when the BoundField was being rendered it was taking the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag added in the &lt;code&gt;OnSorted&lt;/code&gt; method and HTML encoding it, replacing &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; with &lt;code&gt;&amp;amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;amp;gt;&lt;/code&gt;, respectively. In other words, it was transforming a &lt;code&gt;HeaderText&lt;/code&gt; value of: &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;Price &amp;lt;img border=&amp;quot;0&amp;quot; src=&amp;quot;up.gif&amp;quot; /&amp;gt; &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;To: &lt;/p&gt; &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;Price &amp;amp;lt;img border=&amp;quot;0&amp;quot; src=&amp;quot;up.gif&amp;quot; /&amp;amp;gt; &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;Consequently, the browser would display the sorted column&amp;#39;s header text as &lt;code&gt;Price &amp;lt;img border=&amp;quot;0&amp;quot; src=&amp;quot;up.gif&amp;quot; /&amp;gt;&lt;/code&gt; rather than showing an image. &lt;/p&gt; &lt;p&gt;This BoundField has an &lt;code&gt;HtmlEncode&lt;/code&gt; property that, if True (the default), HTML encodes the entire content of the BoundField. One way to fix the header text being HTML encoded, then, would be to set the BoundField&amp;#39;s &lt;code&gt;HtmlEncode&lt;/code&gt; property to False. But what if you wanted the data rows to be HTML encoded, but not the header text? &lt;/p&gt;  &lt;p&gt;To allow for this level of flexibility, I created another custom class in the &lt;code&gt;skmControls2&lt;/code&gt; project. This one extended the BoundField class and overrode the &lt;code&gt;InitializeCell&lt;/code&gt; method, which is where the HTML encoding takes place. The BoundField HTML encodes its content only if &lt;b&gt;both&lt;/b&gt; its &lt;code&gt;HtmlEncode&lt;/code&gt; and &lt;code&gt;SupportsHtmlEncode&lt;/code&gt; properties are True. &lt;code&gt;SupportsHtmlEncode&lt;/code&gt; is a read-only property that, for the BoundField, always returns True. I overrode this property and instead had it return a value based on a private member variable. Then, in the &lt;code&gt;InitializeCell&lt;/code&gt; method I set this member variable to false when initializing a header cell. &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;public class BoundField : System.Web.UI.WebControls.BoundField&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool allowHtmlEncode = true;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;protected override bool SupportsHtmlEncode&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt; &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;return allowHtmlEncode;&lt;br&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (this.HtmlEncode &amp;amp;&amp;amp; cellType == DataControlCellType.Header)&lt;br&gt;&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;allowHtmlEncode = false;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.InitializeCell(cell, cellType, rowState, rowIndex);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;allowHtmlEncode = true;&lt;br&gt; &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;else&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.InitializeCell(cell, cellType, rowState, rowIndex);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;} &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;Since the BoundField is the only GridView field that HTML encodes its data, this hack is only needed for the BoundField. All other fields - the TemplateField, CheckBoxField, ButtonField, and so on - will correctly display the up and down arrow images without any extra hacks. We&amp;#39;ll see how to use this custom BoundField class in the &amp;quot;Using the Custom GridView Control in an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; Web Page&amp;quot; section. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Specifying the Image URLs for the Up and Down Arrows&lt;/b&gt;&lt;br&gt;At this point you may be wondering how the custom GridView control determines the URLs for the up and down image arrows. The simplest option would be to require the page developer to specify the URLs for these two images. I created two such properties: &lt;code&gt;ArrowUpImageUrl&lt;/code&gt; and &lt;code&gt;ArrowDownImageUrl&lt;/code&gt;. But I also wanted to allow the page developer to have a working GridView even if she didn&amp;#39;t want to spend the time to find up and down arrow images. Therefore, I embedded an up and down arrow image into the &lt;code&gt;skmControls2&lt;/code&gt; assembly and use these in the case where the developer does not specify a value for the &lt;code&gt;ArrowUpImageUrl&lt;/code&gt; and &lt;code&gt;ArrowDownImageUrl&lt;/code&gt; properties. &lt;/p&gt;  &lt;p&gt;For more information on embedding resources into an assembly, and retrieving these resources through an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page, be sure to read &lt;a href="http://aspnet.4guysfromrolla.com/articles/080906-1.aspx"&gt;Accessing Embedded Resources through a URL Using &lt;code&gt;WebResource.axd&lt;/code&gt;&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Using the Custom GridView Control in an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; Web Page&lt;/b&gt;&lt;br&gt;The download available at the end of this article includes the complete source code for the custom GridView and BoundField controls, as well as a demo &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; website. To use the &lt;code&gt;skmControls2&lt;/code&gt; controls in an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; website, copy the DLL to the website&amp;#39;s &lt;code&gt;/Bin&lt;/code&gt; directory and then add the following &lt;code&gt;@Register&lt;/code&gt; directive to the tops of the &lt;code&gt;.aspx&lt;/code&gt; pages where you want to use the controls: &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;&amp;lt;%@ Register Assembly=&amp;quot;skmControls2&amp;quot; Namespace=&amp;quot;skmControls2&amp;quot; TagPrefix=&amp;quot;skm&amp;quot; %&amp;gt; &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;(Alternatively, you can add this &lt;code&gt;@Register&lt;/code&gt; directive in the &lt;code&gt;Web.config&lt;/code&gt; file so that you do not need to add it to every &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page that uses the controls. See &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/11/26/tip-trick-how-to-register-user-controls-and-custom-controls-in-web-config.aspx"&gt;Tip/Trick: How to Register User Controls and Custom Controls in &lt;code&gt;Web.config&lt;/code&gt;&lt;/a&gt;.) &lt;/p&gt;  &lt;p&gt;Then just use the same GridView declarative markup you normally would, but replace the &amp;quot;asp&amp;quot; in the &lt;code&gt;&amp;lt;asp:GridView&amp;gt;&lt;/code&gt; tags with &amp;quot;skm&amp;quot;, as in &lt;code&gt;&amp;lt;skm:GridView&amp;gt;&lt;/code&gt;. That&amp;#39;s it! Likewise, if you&amp;#39;re using any BoundFields that have their &lt;code&gt;HtmlEncode&lt;/code&gt; properties set to True (the default), you will want to replace the &amp;quot;asp&amp;quot; in &lt;code&gt;&amp;lt;asp:BoundField&lt;/code&gt; with &amp;quot;skm&amp;quot;. &lt;/p&gt;  &lt;p&gt;The demo included in the download has an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page that shows the &lt;code&gt;ProductID&lt;/code&gt;, &lt;code&gt;ProductName&lt;/code&gt;, &lt;code&gt;CategoryName&lt;/code&gt;, &lt;code&gt;UnitPrice&lt;/code&gt;, and &lt;code&gt;Discontinued&lt;/code&gt; fields from the Northwind&amp;#39;s &lt;code&gt;Products&lt;/code&gt; database table in a sortable GridView using BoundFields (namely, &lt;code&gt;skmControls2&lt;/code&gt; BoundFields), a TemplateField, and a CheckBoxField. &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;&amp;lt;&lt;b&gt;skm&lt;/b&gt;:GridView ID=&amp;quot;ProductsGrid&amp;quot; runat=&amp;quot;server&amp;quot; AutoGenerateColumns=&amp;quot;False&amp;quot; DataSourceID=&amp;quot;NorthwindDataSource&amp;quot; &lt;b&gt;AllowSorting=&amp;quot;True&amp;quot;&lt;/b&gt;&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;lt;&lt;b&gt;skm&lt;/b&gt;:BoundField DataField=&amp;quot;ProductID&amp;quot; HeaderText=&amp;quot;ID&amp;quot; InsertVisible=&amp;quot;False&amp;quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SortExpression=&amp;quot;ProductID&amp;quot; /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;asp:TemplateField HeaderText=&amp;quot;Name&amp;quot; SortExpression=&amp;quot;ProductName&amp;quot;&amp;gt;&lt;br&gt; &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;lt;asp:Label runat=&amp;quot;server&amp;quot; Text=&amp;#39;&amp;lt;%# Bind(&amp;quot;ProductName&amp;quot;) %&amp;gt;&amp;#39; id=&amp;quot;Label1&amp;quot; Font-Bold=&amp;quot;True&amp;quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br&gt;&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;lt;/asp:TemplateField&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;b&gt;skm&lt;/b&gt;:BoundField DataField=&amp;quot;CategoryName&amp;quot; HeaderText=&amp;quot;Category Name&amp;quot; SortExpression=&amp;quot;CategoryName&amp;quot; /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;b&gt;skm&lt;/b&gt;:BoundField HtmlEncode=&amp;quot;False&amp;quot; DataFormatString=&amp;quot;{0:c}&amp;quot; DataField=&amp;quot;UnitPrice&amp;quot; HeaderText=&amp;quot;Price&amp;quot; SortExpression=&amp;quot;UnitPrice&amp;quot; /&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;asp:CheckBoxField DataField=&amp;quot;Discontinued&amp;quot; HeaderText=&amp;quot;Discontinued&amp;quot; SortExpression=&amp;quot;Discontinued&amp;quot; /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Columns&amp;gt;&lt;br&gt;&amp;lt;/&lt;b&gt;skm&lt;/b&gt;:GridView&amp;gt; &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt; &lt;p&gt;Note that the grid&amp;#39;s declarative markup does not set the &lt;code&gt;ArrowUpImageUrl&lt;/code&gt; or &lt;code&gt;ArrowDownImageUrl&lt;/code&gt; properties. Consequently, the grid displays the standard up and down arrow images (see the first screen shot below). If you want to use custom arrow images, specify the URL either declaratively or programmatically. The properties can be set to absolute URLs (like &lt;code&gt;&lt;a href="http://www.example.com/images/UpArrow.gif"&gt;http://www.example.com/images/UpArrow.gif&lt;/a&gt;&lt;/code&gt;) or relative paths using the &lt;code&gt;~&lt;/code&gt; character, like &lt;code&gt;~/Images/UpArrow.png&lt;/code&gt;. The demo page includes a checkbox that allows you to toggle between using the default arrow images and custom ones. &lt;/p&gt;  &lt;p&gt;The following two screen shots show the demo page in action. The first one shows the grid sorted by price in descending order. The built-in up and down arrow images are used here. &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;center&gt;&lt;img border="0" alt="The grid sorted by price in descending order" src="http://aspnet.4guysfromrolla.com/images/UpDownSortImage2.png" width="525" height="158"&gt; &lt;/center&gt; &lt;p&gt;The second image shows the grid sorted by product name in ascending order. Here, a custom up arrow image is used. &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;center&gt;&lt;img border="0" alt="The grid sorted by product name in ascending order" src="http://aspnet.4guysfromrolla.com/images/UpDownSortImage3.png" width="526" height="182"&gt; &lt;/center&gt; &lt;p&gt; &lt;table style="BORDER-RIGHT: rgb(51,51,51) 1px solid; PADDING-RIGHT: 6px; PADDING-LEFT: 6px; BORDER-TOP: rgb(51,51,51) 1px solid; PADDING-BOTTOM: 6px; BORDER-LEFT: rgb(51,51,51) 1px solid; WIDTH: 88%; PADDING-TOP: 6px; BORDER-BOTTOM: rgb(51,51,51) 1px solid; BACKGROUND-COLOR: lightyellow" align="center"&gt;  &lt;tbody&gt; &lt;tr&gt; &lt;th&gt;Custom BoundField Markup is Lost When Using the Fields Dialog Box&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;If you use the custom BoundField controls from the &lt;code&gt;skmControls2&lt;/code&gt; library - e.g., &lt;code&gt;&amp;lt;skm:BoundField ... /&amp;gt;&lt;/code&gt; - it is important to know that if you use the Fields dialog box to modify the GridView&amp;#39;s columns, Visual Studio will replace the custom BoundField markup with the default markup (namely, &lt;code&gt;&amp;lt;asp:BoundField ... /&amp;gt;&lt;/code&gt;). The Fields dialog box is the dialog box displayed when you click the &amp;quot;Edit Columns&amp;quot; link from the GridView&amp;#39;s Smart Tag. &lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br&gt;In this article we looked at building a custom GridView server control (along with a custom BoundField control) in order to automatically display up and down arrow images for the sorted column. This arrow provides the user with visual feedback as to what column the data is sorted by, as well as whether the data is sorted in ascending or descending order. Best of all, this functionality is wrapped up in a custom server control, so you can utilize this behavior without having to write any code in your &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; page&amp;#39;s code-behind class. Be sure to download the source code and the demo application available at the end of this article. &lt;/p&gt;  &lt;p&gt;Happy Programming! &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;li&gt;By &lt;a href="http://www.4guysfromrolla.com/ScottMitchell.shtml"&gt;Scott Mitchell&lt;/a&gt;&lt;/li&gt;&lt;/div&gt; &lt;p&gt;Source: &lt;a href="http://aspnet.4guysfromrolla.com/articles/012308-1.aspx"&gt;http://aspnet.4guysfromrolla.com/articles/012308-1.aspx&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-4304384346305908604?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/4304384346305908604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=4304384346305908604' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4304384346305908604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4304384346305908604'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/extending-gridview-to-include-sort.html' title='Extending the GridView to Include Sort Arrows'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-3511150906310414149</id><published>2008-03-20T09:26:00.001+07:00</published><updated>2008-03-20T09:26:50.842+07:00</updated><title type='text'>How to open popup windows in IE/Firefox and return values using ASP.NET and Javascript</title><content type='html'>&lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;With the forums flooded with questions of opening a popup window, passing values to the popup window and then return values back to the parent p&lt;span&gt;age using both Internet Explorer and Firefox, I decided to take a plunge into the subject and experiment with an easy implementation. This article explains how to transfer values between the Parent page and a Pop-up window. The code has been tested against IE7 and Firefox.&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2" face="Verdana"&gt;Internet Explorer(IE) contains the &lt;/font&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms536759.aspx"&gt;&lt;font color="#0000ff" size="2" face="Verdana"&gt;showModalDialog()&lt;/font&gt;&lt;/a&gt;&lt;font size="2" face="Verdana"&gt; method which proves very effective while creating a &lt;u&gt;modal&lt;/u&gt; dialog box and displaying a html document in it. One caveat being, showModalDialog() is not a W3C implementation. So it is not supported in Firefox (as of version &lt;a href="http://2.0.0.11"&gt;2.0.0.11&lt;/a&gt;). Firefox supports the &lt;/font&gt;&lt;a href="http://developer.mozilla.org/en/docs/DOM:window.open"&gt;&lt;font color="#0000ff" size="2" face="Verdana"&gt;window.open()&lt;/font&gt;&lt;/a&gt;&lt;font size="2" face="Verdana"&gt; method. However there is no built in functionality in Firefox that keeps the popup modal. At the most, you can use 'modal=yes' to make the popup appear in front. However unlike the showModalDialog() in IE, you cannot restrict the user to access the parent page when the popup is opened in Firefox. In short, it is not truly modal. There are different ways to get around this problem, however in this article, we will only focus on exchanging values between the parent and popup page.&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2" face="Verdana"&gt;In this article, we will see how to take a simple approach and create a popup window using both IE and Firefox. In the first part, we will pass in the first name from the parent page to the popup window. In the second part, the popup window will reverse the name and return the reversed string to the parent window. All set!! Let us get started.&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;b&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Part 1 - Passing value to Popup window&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 1:&lt;/b&gt; Open Visual Studio. Create a new website (File &amp;gt; New &amp;gt; Website). Set the location, filename and language of the project.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 2:&lt;/b&gt; In your Default.aspx, add a label (lblFName), textbox (txtFName) and a button (btnPopup). Set the 'Text' property of the label to 'FirstName'. Similarly set the 'Text' property of the button control to 'Show Popup'.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 3:&lt;/b&gt; Now add the popup form. Right click your project &amp;gt; Add New Item &amp;gt; Web Form &amp;gt; Rename form as 'PopupWin.aspx' and click on Add.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 4:&lt;/b&gt; In the PopupWin.aspx, add a textbox (txtReverse) and a button (btnReverse).&lt;/font&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2" face="Verdana"&gt;Well now we have two pages, Default.aspx which is the parent page and PopupWin.aspx which will be the popup page. Let us now pass a value from Default.aspx to the popup window.&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 5:&lt;/b&gt; We will invoke the popup window on the button (btnPopup) click of Default.aspx. To do so, we will use Button.Attribute.Add and call a javascript function that will open the popup window. The javascript function will be contained in a seperate pop.js file which we will create shortly. Add this code in the code behind file of your Default.aspx.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2" face="Verdana"&gt;C#&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;protected&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Page_Load(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; sender, &lt;span style="COLOR: rgb(43,145,175)"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; btnPopup.Attributes.Add(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;onClick&amp;quot;&lt;/span&gt;, &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;javascript:InvokePop(&amp;#39;&amp;quot;&lt;/span&gt; + txtFName.ClientID + &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;&amp;#39;);&amp;quot;&lt;/span&gt;);&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2" face="Verdana"&gt;&lt;a href="http://VB.NET"&gt;VB.NET&lt;/a&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Protected&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: blue"&gt;Sub&lt;/span&gt; Page_Load(&lt;span style="COLOR: blue"&gt;ByVal&lt;/span&gt; sender &lt;span style="COLOR: blue"&gt;As&lt;/span&gt; &lt;span style="COLOR: blue"&gt;Object&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;ByVal&lt;/span&gt; e &lt;span style="COLOR: blue"&gt;As&lt;/span&gt; System.EventArgs) &lt;span style="COLOR: blue"&gt;Handles&lt;/span&gt; &lt;span style="COLOR: blue"&gt;Me&lt;/span&gt;.Load&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; btnPopup.Attributes.Add(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;onClick&amp;quot;&lt;/span&gt;, &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;javascript:InvokePop(&amp;#39;&amp;quot;&lt;/span&gt; &amp;amp; txtFName.ClientID &amp;amp; &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;&amp;#39;);&amp;quot;&lt;/span&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;End&lt;/span&gt; &lt;span style="COLOR: blue"&gt;Sub&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2" face="Verdana"&gt;Over here we are passing the ClientID of the textbox. ClientID is the identifier of the &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink0" class="kLink" href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=99&amp;amp;AspxAutoDetectCookieSupport=1#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;server &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;control&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;, generated by &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt;. You must be wondering why I am not passing the value of the textbox directly. Well passing the control has an advantage where there is more than one control that is passed to the popup page. While returning back the values from the popup to the parent page; it helps you to decide and determine which control receives which value. Even though we will be using only one textbox for simplicity, I thought of creating a sample which can be extended later by you to suit your needs. If the use of ClientID is not clear to you, wait till we get to part 2 of this article, and I will again touch upon the subject.&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 6:&lt;/b&gt; Let us now create the javascript functionality which will open the Popup. Right click your project &amp;gt; Add New Item &amp;gt; Jscript file &amp;gt; Rename the file to pop.js. Add the following function to the pop.js file&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;function&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; InvokePop(fname)&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; val = document.getElementById(fname).value;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// to handle in IE 7.0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (window.showModalDialog) &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retVal = window.showModalDialog(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;PopupWin.aspx?Control1=&amp;quot;&lt;/span&gt; + fname + &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;&amp;amp;ControlVal=&amp;quot;&lt;/span&gt; + val ,&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;#39;Show Popup Window&amp;#39;&lt;/span&gt;,&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;dialogHeight:90px,dialogWidth:250px,resizable:yes,center:yes,&amp;quot;&lt;/span&gt;);&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(fname).value = retVal;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// to handle in Firefox&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;else&lt;/span&gt; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retVal = window.open(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;PopupWin.aspx?Control1=&amp;quot;&lt;/span&gt;+fname + &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;&amp;amp;ControlVal=&amp;quot;&lt;/span&gt; + val,&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;#39;Show Popup Window&amp;#39;&lt;/span&gt;,&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;#39;height=90,width=250,resizable=yes,modal=yes&amp;#39;&lt;/span&gt;);&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retVal.focus();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;This function accepts the textbox control, retrieve's the value of the textbox that needs to be reversed and passes the textbox control and its value to PopupWin.aspx through query string. This is the function which will be called on the btnPopup click.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 7:&lt;/b&gt; To wire up the .js with your &lt;a href="http://asp.net"&gt;asp.net&lt;/a&gt; pages, add a link to the javascript file in both the pages as shown below:&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Default.aspx&lt;/font&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21); FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;head&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;server&amp;quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;title&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;Parent Page&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;title&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;script&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span style="COLOR: red"&gt;src&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;pop.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21); FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;head&lt;/span&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;PopupWin.aspx&lt;/font&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21); FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;head&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;server&amp;quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;title&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;Popup Page&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;title&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;script&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span style="COLOR: red"&gt;src&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;pop.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21); FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;head&lt;/span&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 8:&lt;/b&gt; In the code behind file of PopupWin.aspx, add the following code at the Page_Load() to retrieve the value from the querystring and display the value in the TextBox 'txtReverse', placed in the popup window.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;C#&lt;/font&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;protected&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Page_Load(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; sender, &lt;span style="COLOR: rgb(43,145,175)"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; txtReverse.Text = Request.QueryString[&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;ControlVal&amp;quot;&lt;/span&gt;].ToString();&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;a href="http://VB.NET"&gt;VB.NET&lt;/a&gt;&lt;/font&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Protected&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: blue"&gt;Sub&lt;/span&gt; Page_Load(&lt;span style="COLOR: blue"&gt;ByVal&lt;/span&gt; sender &lt;span style="COLOR: blue"&gt;As&lt;/span&gt; &lt;span style="COLOR: blue"&gt;Object&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;ByVal&lt;/span&gt; e &lt;span style="COLOR: blue"&gt;As&lt;/span&gt; System.EventArgs) &lt;span style="COLOR: blue"&gt;Handles&lt;/span&gt; &lt;span style="COLOR: blue"&gt;Me&lt;/span&gt;.Load&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; txtReverse.Text = Request.QueryString(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;ControlVal&amp;quot;&lt;/span&gt;).ToString()&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;End&lt;/span&gt; &lt;span style="COLOR: blue"&gt;Sub&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;If you are eager to test the value going from Parent page to the popup window, you can do so now. Make Default.aspx as 'Set as Start page' and run the sample. Enter your name in txtFName TextBox and click on Show Popup button. A popup window opens with the value entered in the Parent page. &lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;b&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Part 2 - Passing value from Popup window to the Parent page&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;In this second part, we will reverse the string and pass the reversed string back to the parent page. To do so, follow these steps:&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 1:&lt;/b&gt; Add additional functions to the pop.js file which will reverse the string and return the string back to the parent page.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: green; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;// pop.js&lt;/span&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;function&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; ReverseString()&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; originalString = document.getElementById(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;#39;txtReverse&amp;#39;&lt;/span&gt;).value;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; reversedString = Reverse(originalString);&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RetrieveControl();&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// to handle in IE 7.0&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (window.showModalDialog)&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; window.returnValue = reversedString;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; window.close();&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// to handle in Firefox&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;else&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; ((window.opener != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (!window.opener.closed)) &lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; &lt;span style="COLOR: green"&gt;// Access the control.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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;window.opener.document.getElementById(ctr[1]).value = reversedString; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; }&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&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; window.close();&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&amp;nbsp;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;function&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; Reverse(str)&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; revStr = &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;&amp;quot;&lt;/span&gt;; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (i=str.length - 1 ; i &amp;gt; - 1 ; i--)&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp; { &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; revStr += str.substr(i,1); &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; revStr;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&amp;nbsp;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;function&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; RetrieveControl()&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//Retrieve the query string &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; queryStr = window.location.search.substring(1); &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// Seperate the control and its value&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrlArray = queryStr.split(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;); &lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrl1 = ctrlArray[0]; &lt;/font&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//Retrieve the control passed via querystring &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctr = ctrl1.split(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;=&amp;quot;&lt;/span&gt;);&lt;/font&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;}&lt;/span&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;As you saw in part 1, the value was passed from the parent window to the popup window and was kept in the txtReverse TextBox. The function ReverseString() retrieves the value from this textbox and passes the string to the Reverse() function which reverses the string. The reversed string is then kept in the '&lt;/font&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;reversedString'&lt;/span&gt;&lt;font face="Verdana"&gt; variable. The 'RetrieveControl' splits the query string and identifies the control in the parent page to which the reversed string value is to be sent.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;i&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;Note: If you observe, in the IE implementation, I am not really making use of the RetrieveControl(), however in Firefox I am. If you remember, in the beginning of part1 , I had mentioned the use of ClientID, using which both controls and their values can be passed to determine which control recieves which value. This is especially needed when there are multiple controls. Well the RetrieveControl seperates the different controls and you can use the variables in this method to return values to the respective contro.l&lt;/font&gt;&lt;/font&gt;&lt;/i&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;The value is then returned to the parent window and the popup window is closed.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt; &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2"&gt;&lt;font face="Verdana"&gt;&lt;b&gt;Step 2:&lt;/b&gt; Now in order to use these newly added javacript functions, just call the ReverseString() function on the btnReverse click. To do so, add the onclick attribute to the btnReverse.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt"&gt;&lt;font size="2"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21); FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;input&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: red"&gt;class&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span style="COLOR: red"&gt;id&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;btnReverse&amp;quot;&lt;/span&gt; &lt;span style="COLOR: red"&gt;value&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;Reverse value back&amp;quot;&lt;/span&gt; &lt;span style="COLOR: red"&gt;onclick&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&amp;quot;ReverseString();&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2" face="Verdana"&gt;That's it. Now test the code. Pass your name from the Parent window to the Popup window and then reverse the string and pass it back to the Parent window.&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2" face="Verdana"&gt;I would like to mention that there are multiple ways of doing the task demoed in this article. I have seen some cool examples by experts. One of them I would like to mention is that of &lt;/font&gt;&lt;a href="http://forums.asp.net/p/1197714/2075691.aspx"&gt;&lt;font size="2" face="Verdana"&gt;NC01&lt;/font&gt;&lt;/a&gt;&lt;font size="2" face="Verdana"&gt; where he makes use of properties and ViewState, to pass values to the Popup window. I would encourage you to use this article as a base and try out your own implementations that would work on multiple browsers. &lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font size="2" face="Verdana"&gt;The source code of this article, both in C# and &lt;a href="http://VB.NET"&gt;VB.NET&lt;/a&gt;, can be downloaded from &lt;/font&gt;&lt;a href="http://www.dotnetcurry.com/Uploads/PopupIEFirefox.zip"&gt;&lt;font color="#0000ff" size="2" face="Verdana"&gt;here&lt;/font&gt;&lt;/a&gt;&lt;font size="2" face="Verdana"&gt;. I hope this article was useful and I thank you for viewing it. If you liked the article, please subscribe to the RSS feed over &lt;a href="http://feeds.feedburner.com/netCurryRecentArticles"&gt;&lt;span style="COLOR: windowtext"&gt;&lt;font size="2" face="Verdana"&gt;here&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;font size="2" face="Verdana"&gt;.&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;  &lt;div style="MARGIN: 0in 0in 10pt" align="justify"&gt;&lt;font face="Verdana"&gt;Source: &lt;a href="http://www.dotnetcurry.com/ShowArticle.aspx?ID=99&amp;amp;AspxAutoDetectCookieSupport=1"&gt;http://www.dotnetcurry.com/ShowArticle.aspx?ID=99&amp;amp;AspxAutoDetectCookieSupport=1&lt;/a&gt;&lt;/font&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-3511150906310414149?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/3511150906310414149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=3511150906310414149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/3511150906310414149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/3511150906310414149'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/how-to-open-popup-windows-in-iefirefox.html' title='How to open popup windows in IE/Firefox and return values using ASP.NET and Javascript'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-4090750384187578214</id><published>2008-03-19T11:44:00.001+07:00</published><updated>2008-03-19T11:44:30.039+07:00</updated><title type='text'>Creating Client and Server-Side Form Validation using the Validator Toolkit for ASP.NET MVC</title><content type='html'>&lt;span id="intelliTXT" name="intelliTxt"&gt; &lt;div id="contentdiv"&gt; &lt;h2&gt;Introduction&lt;/h2&gt; &lt;p&gt;Microsoft just released the first preview of &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework and it&amp;#39;s Microsoft&amp;#39;s way to develop Web applications based on the model-view-controller architecture. It will not replace the classic &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; WebForms model. For more information about the new Framework, please see the Scott Guthrie&amp;#39;s &lt;a title="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx" href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;blog message&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Since there is just a first preview version available, the final feature list is not complete. At this point of time, there is no built-in solution to validate an HTML form on the client and server-side using a standardized system. The &lt;strong&gt;Validator Toolkit for &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC&lt;/strong&gt; offers a way to do form validation on the client and server-side using validation sets. The toolkit is a new project on Microsoft&amp;#39;s Open Source Community site at &lt;a title="http://www.codeplex.com/MvcValidatorToolkit" href="http://www.codeplex.com/MvcValidatorToolkit"&gt;CodePlex.com&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;NOTICE: The latest version of the source code and the sample site for the Validator Toolkit can be downloaded from the CodePlex project (source code tab).&lt;/p&gt; &lt;p&gt;The screenshots below give you an idea about how the toolkit will work:&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.codeplex.com/MvcValidatorToolkit" href="http://www.codeplex.com/MvcValidatorToolkit"&gt;&lt;/a&gt;&lt;img border="0" hspace="0" alt="Screenshot1.jpg" src="http://www.codeproject.com/kb/aspnet/MvcValidatorToolkit/Screenshot1.jpg" width="640" height="414"&gt;&lt;/p&gt; &lt;img border="0" hspace="0" alt="Screenshot2.jpg" src="http://www.codeproject.com/kb/aspnet/MvcValidatorToolkit/Screenshot2.jpg" width="640" height="414"&gt;  &lt;p&gt;Here&amp;#39;s another screenshot showing how the error messages can be displayed:&lt;/p&gt;&lt;img border="0" hspace="0" alt="Screenshot3.jpg" src="http://www.codeproject.com/kb/aspnet/MvcValidatorToolkit/Screenshot3.jpg" width="640" height="414"&gt;  &lt;p&gt;Now, let&amp;#39;s start!&lt;/p&gt; &lt;h2&gt;Solution &lt;/h2&gt; &lt;p&gt;As mentioned above, the toolkit uses validation sets as a crucial element. Validation sets are special classes that derive from the &lt;code&gt;ValidationSet&lt;/code&gt; base class and define all validation rules (validators) for an HTML form. The toolkit generates client-side JavaScript code based on the defined validators during the view rendering.&lt;/p&gt;  &lt;p&gt;The client-side uses the very powerful &lt;code&gt;jQuery &lt;/code&gt;JavaScript library in conjunction with the &lt;code&gt;jQuery &lt;/code&gt;validation plug-in to fulfil the final task of client validation. For more information regarding &lt;code&gt;jQuery &lt;/code&gt;and the plug-in, please take a look at the following links:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;&lt;a title="http://www.jquery.com" href="http://www.jquery.com/"&gt;JQuery is a new type of JavaScript library&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a title="http://plugins.jquery.com/project/validate" href="http://plugins.jquery.com/project/validate"&gt;Validation&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The validation plug-in used by the toolkit is slightly customized to support all the needed behaviour. Besides using the &lt;code&gt;jQuery &lt;/code&gt;library for client validation, you can use it for a lot of other stuff, like animations or DOM manipulation. There are also a lot of plug-ins developed that extend the core library. Validation sets are also used to validate forms on the server (based on the &lt;code&gt;Request.Form &lt;/code&gt;collection).&lt;/p&gt;  &lt;p&gt;Before we go ahead, let&amp;#39;s have a look at a sample validation set:&lt;/p&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; LoginValidationSet : ValidationSet {     &lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; ValidatorCollection GetValidators() {           &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidatorCollection (          &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateElement(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;)              { Required = &lt;span class="code-keyword"&gt;true&lt;/span&gt;, MinLength = &lt;span class="code-digit"&gt;5&lt;/span&gt;, MaxLength = &lt;span class="code-digit"&gt;30&lt;/span&gt; },          &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateElement(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;password&amp;quot;&lt;/span&gt;)              { Required = &lt;span class="code-keyword"&gt;true&lt;/span&gt;, MinLength = &lt;span class="code-digit"&gt;3&lt;/span&gt;, MaxLength = &lt;span class="code-digit"&gt;50&lt;/span&gt; }       );    } } &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This &lt;code&gt;LoginValidationSet&lt;/code&gt; class defines the rules for validating a simple login form by overriding the &lt;code&gt;GetValidators&lt;/code&gt; method of the base class. The method must return a &lt;code&gt;ValidatorCollection&lt;/code&gt; instance with all validators used to validate the HTML form later on. In this case, the username field is required and the input for it must contain at least 5 characters and a maximum of 30 characters. The password field is required too, but within the boundaries of 3 and 50 characters. &lt;/p&gt;  &lt;p&gt;The order of the defined validators also defines the execution order of validation process. If the toolkit would use custom attributes to set validation rules instead of the method &lt;code&gt;GetValidators&lt;/code&gt;, there is no guarantee for the validation process to validate in the same order the attributes are defined, since the &lt;code&gt;Type.GetCustomAttributes &lt;/code&gt;method returns the attribute list in alphabetical order.&lt;/p&gt;  &lt;p&gt;Of course, you can also write your own custom validators or you may use the &lt;code&gt;ValidateScriptMethod &lt;/code&gt;validator which allows you to call a specific JavaScript function on the client-side and a method within the validation set class for the server-side. More on that later.&lt;/p&gt;  &lt;p&gt;Once a validation set class is defined, you attach it to the view and the HTML form processing controller action using the &lt;code&gt;ValidationSet &lt;/code&gt;attribute, like this:&lt;/p&gt; &lt;div style="WIDTH: 100%; CURSOR: pointer" id="premain1" class="SmallText"&gt;&lt;img id="preimg1" src="http://www.codeproject.com/images/minus.gif" width="9" height="9"&gt;&lt;span style="MARGIN-BOTTOM: 0pt" id="precollapse1"&gt; Collapse&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN-TOP: 0pt" id="pre1" class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; File: LoginController.cs&lt;/span&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt; &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; LoginController : Controller {     [ControllerAction]    &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; Login() {       RenderView(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;Login&amp;quot;&lt;/span&gt;);    }     [ControllerAction]    [ValidationSet(&lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(LoginValidationSet))]    &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; Authenticate() {       &lt;span class="code-keyword"&gt;if&lt;/span&gt;(&lt;span class="code-keyword"&gt;this&lt;/span&gt;.ValidateForm())          RenderView(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;Overview&amp;quot;&lt;/span&gt;);       &lt;span class="code-keyword"&gt;else&lt;/span&gt;          RenderView(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;Login&amp;quot;&lt;/span&gt;);    } }     ...  &lt;span class="code-comment"&gt;//&lt;/span&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; File: Login.aspx.cs (CodeBehind)&lt;/span&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt; [ValidationSet(&lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(LoginValidationSet))] &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;partial&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; Login : ViewPage {     [ValidationSet(&lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(LoginValidationSet))]    &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;partial&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; Login : ViewPage {    } }&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The controller action &lt;code&gt;Authenticate &lt;/code&gt;then calls the &lt;code&gt;ValidateForm &lt;/code&gt;method, which uses the &lt;code&gt;ValidationSet &lt;/code&gt;attribute to do the server-side form validation, based on the &lt;code&gt;NameValueCollection Request:Form&lt;/code&gt;. &lt;/p&gt;  &lt;p&gt;Within the HTML page, you need to initialize script validation for the login form (&lt;code&gt;loginForm&lt;/code&gt;) as follows:&lt;/p&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="html"&gt;&lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;    $(&lt;span class="code-keyword"&gt;function&lt;/span&gt;(){      updateSettingsForSample1ValidationSet($(&lt;span class="code-comment"&gt;&amp;#39;&lt;/span&gt;&lt;span class="code-comment"&gt;#loginForm&amp;#39;).validate({rules:{}}));&lt;/span&gt;    }); &lt;span class="code-keyword"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In the next step, you define the HTML form as usual:&lt;/p&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="html"&gt;&lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;form&lt;/span&gt; &lt;span class="code-attribute"&gt;id&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;loginForm&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;action&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;/Login/Authenticate&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;method&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;post&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;    Username: &lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;input&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;text&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;id&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;username&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;username&amp;quot;&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;br&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;    Password: &lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;input&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;text&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;id&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;password&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;password&amp;quot;&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;br&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;input&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;submit&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;value&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;Login&amp;quot;&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt; &lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;form&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Finally, the script that defines the validation rules must be defined: &lt;/p&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="html"&gt;&lt;span class="code-pagedirective"&gt;&amp;lt;%&lt;/span&gt; this.RenderValidationSetScripts(); &lt;span class="code-pagedirective"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You also need to include the &lt;code&gt;jQuery &lt;/code&gt;JavaScript library into the form or master page. See the &lt;code&gt;Validator &lt;/code&gt;Toolkit sample site for more information. Sample site of the toolkit includes the scripts in the master page:&lt;/p&gt;  &lt;div class="no-vmads"&gt;&lt;pre lang="html"&gt;&lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;src&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;../../Content/jDate.js&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt; &lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;src&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;../../Content/jQuery.Core.js&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt; &lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;src&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;../../Content/jQuery.Delegate.js&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt; &lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="code-attribute"&gt;src&lt;/span&gt;&lt;span class="code-keyword"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;../../Content/jQuery.Validation.js&amp;quot;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;script&lt;/span&gt;&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt; &lt;/div&gt; &lt;p&gt;That&amp;#39;s basically all you need to do - include form validation on the client and server-side. The next section gives you an overview of the standard validators and their usage.&lt;/p&gt; &lt;h2&gt;Standard Validators&lt;/h2&gt; &lt;p&gt;The toolkit offers a handful of standard validators out of the box. The following table gives you an overview of the provided validators:&lt;/p&gt; &lt;table class="ArticleTable" width="640"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;ValidatePresence&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Validates the presence of input value.&lt;br&gt;&lt;br&gt;Sample:&lt;br&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidatePresence(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;ValidateDate&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Validates input value against the given date formats. Setting the &lt;code&gt;DateFormats&lt;/code&gt; property to a comma-separated list of date formats, allows you to check if the value is formatted in one of the specified formats. You may check for date formats like MM/ DD/ YYYY. If &lt;code&gt;DateFormats &lt;/code&gt;is not defined, then the validator will use the culture information of the current thread.&lt;br&gt; &lt;br&gt;Sample:&lt;br&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateDate(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;startDate&amp;quot;&lt;/span&gt;, &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;yyyy-mm-dd,yyyymmdd&amp;quot;&lt;/span&gt;) &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateDate(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;startDate&amp;quot;&lt;/span&gt;)      { DateFormats = &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;yyyy-mm-dd,yyyymmdd&amp;quot;&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;ValidateMin&lt;/code&gt;&lt;br&gt;&lt;code&gt;ValidateMax&lt;/code&gt;&lt;br&gt;&lt;code&gt;ValidateRange&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Validates input value either against a minimum, maximum or integer range.&lt;br&gt;&lt;br&gt;Sample:&lt;br&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateMin(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;step&amp;quot;&lt;/span&gt;, &lt;span class="code-digit"&gt;5&lt;/span&gt;) &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateRange(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;step&amp;quot;&lt;/span&gt;) { Min = &lt;span class="code-digit"&gt;1&lt;/span&gt;, Max = &lt;span class="code-digit"&gt;99&lt;/span&gt; }&lt;/pre&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;ValidateMinLength&lt;/code&gt;&lt;br&gt;&lt;code&gt;ValidateMaxLength&lt;/code&gt;&lt;br&gt;&lt;code&gt;ValidateRangeLength&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Validates input value either against a minimum, maximum or integer range.&lt;br&gt;&lt;br&gt;Sample:&lt;br&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateMaxLength(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;password &amp;quot;&lt;/span&gt;, &lt;span class="code-digit"&gt;30&lt;/span&gt;) &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateRangeLength(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;password&amp;quot;&lt;/span&gt;)      { MinLength = &lt;span class="code-digit"&gt;5&lt;/span&gt;, MaxLength = &lt;span class="code-digit"&gt;30&lt;/span&gt; }  &lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;ValidateElement&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Joins multiple validators into one validator to keep things simple and allows the following to validate: &lt;code&gt;Required&lt;/code&gt;, &lt;code&gt;Min&lt;/code&gt;, &lt;code&gt;Max&lt;/code&gt;, &lt;code&gt;MinLength&lt;/code&gt;, &lt;code&gt;MaxLength&lt;/code&gt;&lt;br&gt;&lt;br&gt; Sample:&lt;br&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateElement(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;)      { Required = &lt;span class="code-keyword"&gt;true&lt;/span&gt;, MinLength = &lt;span class="code-digit"&gt;5&lt;/span&gt; }  &lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;ValidateEqualTo&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Validates input value against another input value. This validator is useful to compare password inputs.&lt;br&gt;&lt;br&gt;Sample:&lt;br&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateEqualTo(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;password&amp;quot;&lt;/span&gt;, &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;passwordAgain&amp;quot;&lt;/span&gt;)  &lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;ValidateScriptMethod&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Validates input value using a custom JavaScript function and validation set class method.&lt;br&gt;&lt;br&gt;Sample:&lt;br&gt; &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateScriptMethod(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;)      { MethodName = &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;valUsername&amp;quot;&lt;/span&gt; } &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateScriptMethod(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;) { MethodName = &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;valiUsername&amp;quot;&lt;/span&gt;,      Parameters = &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;{Opt1:2, Opt2: &amp;quot;&lt;/span&gt;AB&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;}&amp;quot;&lt;/span&gt; } &lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;There are still some validators missing, e.g. a general regular expression validator or a specific email validator.&lt;/p&gt; &lt;h2&gt;Validation Sets &lt;/h2&gt; &lt;p&gt;Each validation set definition class derives from the &lt;code&gt;ValidationSet &lt;/code&gt;base class. This base class contains and offers common functionality for the validation process. Let&amp;#39;s take a look at the sample below to explain some possibilities the validation set offers to validate complex forms:&lt;/p&gt;  &lt;div class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; LoginValidationSet : ValidationSet {     &lt;span class="code-keyword"&gt;string&lt;/span&gt; Username = &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;;    &lt;span class="code-keyword"&gt;string&lt;/span&gt; Password = &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;;     &lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; ValidatorCollection GetValidators() {       &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidatorCollection       (          &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateElement(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;)              { Required = &lt;span class="code-keyword"&gt;true&lt;/span&gt;, MinLength = &lt;span class="code-digit"&gt;5&lt;/span&gt;, MaxLength = &lt;span class="code-digit"&gt;30&lt;/span&gt; },          &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateElement(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;password&amp;quot;&lt;/span&gt;)              { Required = &lt;span class="code-keyword"&gt;true&lt;/span&gt;, MinLength = &lt;span class="code-digit"&gt;3&lt;/span&gt;, MaxLength = &lt;span class="code-digit"&gt;50&lt;/span&gt; },          &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidateScriptMethod(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;, &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;validateUsername&amp;quot;&lt;/span&gt;)       );    }     &lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;bool&lt;/span&gt; ValidateUsername() {       &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; DO HERE SOME VALIDATION AND RETURN RESULT AS BOOLEAN VALUE&lt;/span&gt;       &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;true&lt;/span&gt;;    }     &lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; OnValidate() {       &lt;span class="code-keyword"&gt;if&lt;/span&gt;(Username.StartsWith(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;billy&amp;quot;&lt;/span&gt;) &amp;amp;&amp;amp; Password.StartsWith(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;gat&amp;quot;&lt;/span&gt;))          &lt;span class="code-keyword"&gt;throw&lt;/span&gt; &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidatorException(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;username&amp;quot;&lt;/span&gt;, &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;The username/password combination &amp;quot;&lt;/span&gt;);    } }&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Creating non-public instance member fields of type &lt;code&gt;&lt;span class="code-SDKkeyword"&gt;String&lt;/span&gt; &lt;/code&gt;like the &lt;code&gt;Username &lt;/code&gt;or &lt;code&gt;Password &lt;/code&gt;fields, allows the base class to populate those fields with the accompanying input field values. This is a simple way to access input values without checking the underlying values collection (e.g. &lt;code&gt;Request.Form&lt;/code&gt;).&lt;/p&gt;  &lt;p&gt;The &lt;code&gt;ValidateScriptMethod &lt;/code&gt;validator defines a JavaScript function (&lt;code&gt;validateUsername&lt;/code&gt;) to call during the client-side validation. This function must be defined or included in the HTML page. The &lt;code&gt;ValidationSet &lt;/code&gt;base class checks during the server-side validation if the current validation set class contains a case-insensitive method named &lt;code&gt;validateUsername&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;Once all validators defined with the &lt;code&gt;GetValidators &lt;/code&gt;method are called during the validation process, the base class will call an overall method called &lt;code&gt;OnValidate&lt;/code&gt;. By overriding this method you can do some final validation. If you want to throw an exception you need to throw the &lt;code&gt;ValidatorException &lt;/code&gt;with the field name and message as parameters.&lt;/p&gt;  &lt;p&gt;Using the described techniques, the possibilities of the &lt;code&gt;jQuery&lt;/code&gt; library and the custom validators (see below), you can validate most complex forms quite efficiently. The next section will describe ways to localize the messages.&lt;/p&gt;  &lt;h2&gt;Localization &lt;/h2&gt; &lt;p&gt;It&amp;#39;s easy to localize error messages of the toolkit using the standard folder. If the default settings are not changed, the default error message for each validator is stored in the &lt;em&gt;ValidationSet.resx&lt;/em&gt; file (in the folder &lt;em&gt;App_GlobalResources&lt;/em&gt;). The naming convention for the resource key is as follows: &lt;code&gt;&lt;span class="code-keyword"&gt;&amp;lt;&lt;/span&gt;VALIDATORNAME&lt;span class="code-keyword"&gt;&amp;gt;&lt;/span&gt;_DefaultErrorMessage&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;To change the default name of the &lt;em&gt;ValidationSet.resx&lt;/em&gt; resource file, a derived validation set class can set the name by using the &lt;code&gt;&lt;span class="code-keyword"&gt;static&lt;/span&gt; &lt;/code&gt;field &lt;code&gt;DefaultMessageResourceName &lt;/code&gt;or by adding the &lt;code&gt;MessageResourceName &lt;/code&gt;attribute to the class. It is also possible to combine the techniques and use more than one resource file.&lt;/p&gt;  &lt;p&gt;The sample site within the &lt;code&gt;Validator &lt;/code&gt;Toolkit contains usage examples of localized error messages and field names. The localization is simple and straightforward.&lt;/p&gt; &lt;h2&gt;Custom Validators&lt;/h2&gt; &lt;p&gt;Creating custom validators is quite simple, but requires some basic knowledge of the &lt;code&gt;jQuery &lt;/code&gt;JavaScript library and the validation plug-in if the validator wants to support client validation. The sample site includes a custom validator called &lt;code&gt;ValidateBuga&lt;/code&gt;, which checks the input value against the constant string buga. Each validator derives from the &lt;code&gt;Validator &lt;/code&gt;class, which provides a couple of virtual methods a custom validator must override:&lt;/p&gt;  &lt;table class="ArticleTable" width="640"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;GetClientMethodData&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This method defines by returning an instance of the &lt;code&gt;ValidatorMethodData &lt;/code&gt;class the name of the custom validator (for the &lt;code&gt;jQuery&lt;/code&gt; validation plug-in), the JavaScript function code and the default error message.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;GetClientRule&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This method returns the plug-in client rule to use once the validator is defined within a validation set class.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;GetClientMessage&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This method returns the localized error message for a given element.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;GetDefaultErrorMessageFormat&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This method returns the default error message of the custom validator.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;Validate&lt;/code&gt;&lt;/td&gt; &lt;td&gt;This method validates the input value for the given element. If the input is not valid the validator must call the &lt;code&gt;InsertError &lt;/code&gt;method of the &lt;code&gt;Validator &lt;/code&gt;base class to signal an error.&lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Here is the source code of the &lt;code&gt;ValidateBuga &lt;/code&gt;sample validator:&lt;/p&gt; &lt;div style="WIDTH: 100%; CURSOR: pointer" id="premain14" class="SmallText"&gt;&lt;img id="preimg14" src="http://www.codeproject.com/images/minus.gif" width="9" height="9"&gt;&lt;span style="MARGIN-BOTTOM: 0pt" id="precollapse14"&gt; Collapse&lt;/span&gt;&lt;/div&gt;  &lt;div style="MARGIN-TOP: 0pt" id="pre14" class="no-vmads"&gt;&lt;pre lang="cs"&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; ValidateBuga : Validator {     &lt;span class="code-keyword"&gt;public&lt;/span&gt; ValidateBuga(&lt;span class="code-keyword"&gt;string&lt;/span&gt; elementsToValidate)       : &lt;span class="code-keyword"&gt;base&lt;/span&gt;(elementsToValidate) {    }     &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; ValidatorMethodData GetClientMethodData() {       &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;new&lt;/span&gt; ValidatorMethodData(          &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;buga&amp;quot;&lt;/span&gt;,          &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;function(value,element,parameters){return value==&amp;#39;buga&amp;#39;;}&amp;quot;&lt;/span&gt;,          &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;$.format(&amp;#39;&amp;quot;&lt;/span&gt; + ErrorMessageFormat + &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;&amp;#39;)&amp;quot;&lt;/span&gt;       );    }     &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; &lt;span class="code-keyword"&gt;string&lt;/span&gt; GetClientRule(&lt;span class="code-keyword"&gt;string&lt;/span&gt; element) {       &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;buga:true&amp;quot;&lt;/span&gt;;    }     &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; &lt;span class="code-keyword"&gt;string&lt;/span&gt; GetClientMessage(&lt;span class="code-keyword"&gt;string&lt;/span&gt; element) {       &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;string&lt;/span&gt;.Format(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;buga:&amp;#39;{0}&amp;#39;&amp;quot;&lt;/span&gt;, GetLocalizedErrorMessage(element))          .Replace(&lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;&amp;#39;&amp;quot;&lt;/span&gt;, &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;\&amp;#39;&amp;quot;&lt;/span&gt;);    }     &lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; Validate(&lt;span class="code-keyword"&gt;string&lt;/span&gt; element) {       &lt;span class="code-keyword"&gt;if&lt;/span&gt;(Values.ContainsKey(element) == &lt;span class="code-keyword"&gt;false&lt;/span&gt; || (Values[element] ??          &lt;span class="code-keyword"&gt;string&lt;/span&gt;.Empty).Trim() != &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;buga&amp;quot;&lt;/span&gt;)          InsertError(element);    }     &lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; &lt;span class="code-keyword"&gt;string&lt;/span&gt; GetDefaultErrorMessageFormat() {       &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-string"&gt;&amp;quot;&lt;/span&gt;&lt;span class="code-string"&gt;The field {0} must contain the value \&amp;quot;buga\&amp;quot;&amp;quot;&lt;/span&gt;;    } } &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Another way to use custom validation is by using the validator &lt;code&gt;ValidateScriptMethod&lt;/code&gt;. It allows to call a JavaScript function on the client-side and a specific method of the validation set class on the server-side. The custom validation is part of the validation set class and is not usable in multiple validation sets. &lt;/p&gt;  &lt;h2&gt;Summary &lt;/h2&gt; &lt;p&gt;The &lt;code&gt;Validator &lt;/code&gt;Toolkit is a simple and easy way to add client-side and server-side HTML form validation to the new &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework. It is easy to extend the toolkit by adding custom validators. You may use the toolkit until Microsoft provides a solution for HTML form validation.&lt;/p&gt; &lt;/div&gt;&lt;/span&gt; &lt;form style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; PADDING-BOTTOM: 0pt; MARGIN: 0pt; PADDING-TOP: 0pt" id="aspnetForm" method="post" name="aspnetForm" action="mvcvalidatortoolkit.aspx"&gt; &lt;h2&gt;License&lt;/h2&gt; &lt;div id="ctl00_LicenseTerms"&gt; &lt;p&gt;This article, along with any associated source code and files, is licensed under &lt;a href="http://www.opensource.org/licenses/ms-pl.html"&gt;Microsoft Public License (Ms-PL)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Source: &lt;a href="http://www.codeproject.com/kb/aspnet/mvcvalidatortoolkit.aspx"&gt;http://www.codeproject.com/kb/aspnet/mvcvalidatortoolkit.aspx&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/form&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-4090750384187578214?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/4090750384187578214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=4090750384187578214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4090750384187578214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4090750384187578214'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/creating-client-and-server-side-form.html' title='Creating Client and Server-Side Form Validation using the Validator Toolkit for ASP.NET MVC'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-6846535443131746069</id><published>2008-03-18T11:07:00.001+07:00</published><updated>2008-03-18T11:07:39.850+07:00</updated><title type='text'>Extending Base Type Functionality with Extension Methods</title><content type='html'>&lt;div&gt;&lt;em&gt;&lt;font size="4"&gt;By &lt;/font&gt;&lt;/em&gt;&lt;a href="http://www.4guysfromrolla.com/ScottMitchell.shtml"&gt;&lt;em&gt;&lt;font size="4"&gt;Scott Mitchell&lt;/font&gt;&lt;/em&gt;&lt;/a&gt;&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt; &lt;p&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;br&gt;In November 2007, Microsoft released the .NET Framework version 3.5, Visual Studio 2008, and new versions of the C# and Visual Basic languages (see &lt;a href="http://aspnet.4guysfromrolla.com/articles/112107-1.aspx"&gt;An Overview of ASP.NET 3.5 and Visual Studio 2008&lt;/a&gt; for more details on the release). The new C# and Visual Basic versions include a myriad of exciting new features that make the languages more expressive and open the door for new syntax constructs, like &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx"&gt;LINQ&lt;/a&gt;. One of these new language features is &lt;i&gt;extension methods&lt;/i&gt;, which is the topic for today&amp;#39;s article. &lt;/p&gt;  &lt;p&gt;Extension methods allow a developer to tack on her own methods to an existing class in the .NET Framework. For example, imagine that our developer created a method named &lt;code&gt;StripHtml&lt;/code&gt;, that strips HTML elements from a string using a &lt;a href="http://aspnet.4guysfromrolla.com/articles/022603-1.aspx"&gt;regular expression&lt;/a&gt;. By associating this method with the &lt;code&gt;System.String&lt;/code&gt; class, it could be called as if it was one of the &lt;code&gt;System.String&lt;/code&gt; class&amp;#39;s built-in methods: &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;&amp;#39; VB&lt;br&gt;Dim str As String = &amp;quot;&amp;lt;b&amp;gt;Hello, world!&amp;lt;/b&amp;gt;&amp;quot;&lt;br&gt;Dim strippedString = str.StripHtml()&lt;br&gt;&lt;br&gt;// C#&lt;br&gt;string str = &amp;quot;&amp;lt;b&amp;gt;Hello, world!&amp;lt;/b&amp;gt;&amp;quot;;&lt;br&gt; string strippedString = str.StripHtml(); &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;Extension methods make it easy to add functionality to an existing type using a natural syntax. Also, since the extension methods appear in Visual Studio&amp;#39;s IntelliSense drop-down list, they are easier to find and use than wrapper class equivalents. In this article we will see how to create extension methods in both C# and Visual Basic. Read on to learn more! &lt;/p&gt;  &lt;p&gt;&lt;b&gt;The Impetus Behind Extension Methods&lt;/b&gt;&lt;br&gt;Over the past several years, I&amp;#39;ve worked with a number of clients in building large &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; web applications. In most of these applications there has been a need to define extra functionality on strings. On some pages we need to strip all of the HTML elements from a string before displaying it; on other pages we need to parse the string and censor out an potentially profane words; and on other pages we need to convert URLs into appropriate HTML anchor tags (i.e., converting the text &lt;i&gt;URL&lt;/i&gt; into &lt;code&gt;&amp;lt;a href=&amp;quot;&lt;i&gt;URL&lt;/i&gt;&amp;quot;&amp;gt;&lt;i&gt;URL&lt;/i&gt;&amp;lt;/a&amp;gt;&lt;/code&gt;). &lt;/p&gt;  &lt;p&gt;To provide this function I created a &lt;i&gt;wrapper class&lt;/i&gt; named &lt;code&gt;StringHelpers&lt;/code&gt; with methods for stripping HTML elements, censoring profanity, and converting URLs into hyperlinks. The wrapper class was implemented as a class with a series of static methods that accepted a string as input, perform the intended operation, and then return the resulting string. &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;&amp;#39; VB&lt;br&gt;Public Class StringHelpers&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Public Shared Function StripHtml(ByVal str As String) As String&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &lt;i&gt;Strip the HTML, and return the stripped string&lt;/i&gt; ...&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;End Function&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Public Shared Function RemoveProfanity(ByVal str As String) As String&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &lt;i&gt;Remove the profanity, and return the &amp;quot;clean&amp;quot; string&lt;/i&gt; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;End Function&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Public Shared Function ConvertUrlsToHyperlinks(ByVal str As String) As String&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &lt;i&gt;Replace URLs with the appropriate HTML&lt;/i&gt; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;End Function&lt;br&gt;End Class&lt;br&gt;&lt;br&gt;&lt;br&gt;// C#&lt;br&gt;public class StringHelpers&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static string StripHtml(string str)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &lt;i&gt;Strip the HTML, and return the stripped string&lt;/i&gt; ...&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static string RemoveProfanity(string str)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &lt;i&gt;Remove the profanity, and return the &amp;quot;clean&amp;quot; string&lt;/i&gt; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static string ConvertUrlsToHyperlinks(string str)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... &lt;i&gt;Replace URLs with the appropriate HTML&lt;/i&gt; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;} &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;With the &lt;code&gt;StringHelpers&lt;/code&gt; wrapper class in place, I can exercise this added string functionality using code like: &lt;/p&gt; &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;&amp;#39; VB&lt;br&gt;Dim str As String = &amp;quot;&amp;lt;b&amp;gt;Hello, world!&amp;lt;/b&amp;gt;&amp;quot;&lt;br&gt;Dim strippedString = &lt;b&gt;StringHelpers.StripHtml(str)&lt;/b&gt;&lt;br&gt;&lt;br&gt;// C#&lt;br&gt;string str = &amp;quot;&amp;lt;b&amp;gt;Hello, world!&amp;lt;/b&amp;gt;&amp;quot;;&lt;br&gt; string strippedString = &lt;b&gt;StringHelpers.StripHtml(str);&lt;/b&gt; &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;While wrapper classes offer a simple approach to encapsulate commonly used functionality, there is no tight association between the wrapper class&amp;#39;s functionality and the type its methods operate on. In order to use the wrapper class, a developer must first know of its existence; he must dig into the various methods to see how they operate. Ideally, these string-specific methods (&lt;code&gt;StripHtml&lt;/code&gt;, &lt;code&gt;RemoveProfanity&lt;/code&gt;, and &lt;code&gt;ConvertUrlsToHyperlinks&lt;/code&gt;) would be part of the &lt;code&gt;System.String&lt;/code&gt; type, and I could call them using a more intuitive syntax (&lt;code&gt;&lt;i&gt;StringVariable&lt;/i&gt;.StripHtml()&lt;/code&gt;) and enjoy IntelliSense support through Visual Studio. Extension methods provide these advantages, allowing a developer to more intuitively assign methods to a particular type. &lt;/p&gt;  &lt;p&gt; &lt;table style="BORDER-RIGHT: rgb(51,51,51) 1px solid; PADDING-RIGHT: 6px; PADDING-LEFT: 6px; BORDER-TOP: rgb(51,51,51) 1px solid; PADDING-BOTTOM: 6px; BORDER-LEFT: rgb(51,51,51) 1px solid; WIDTH: 88%; PADDING-TOP: 6px; BORDER-BOTTOM: rgb(51,51,51) 1px solid; BACKGROUND-COLOR: lightyellow" align="center"&gt;  &lt;tbody&gt; &lt;tr&gt; &lt;th&gt;Extending Type Functionality via Inheritance&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;In addition to wrapper classes, another common approach to adding functionality to an existing type is through &lt;i&gt;inheritance&lt;/i&gt;. Inhertiance is a core object-oriented programming principle that enables a developer to take an existing type and extend its functionality by adding new methods, properties, and events. The downside with inheritance is that you need to create a &lt;i&gt;new&lt;/i&gt; type to extend the existing type. Consequently, in order to use the added functionality you have to work with the new type. This is a Good Thing and appropriate design in most cases, but if you just want to add a simple method or two to add new functionality to an existing type, having to use the newly created type can be burdensome. Moreover, not all types can be extended. The &lt;code&gt;System.String&lt;/code&gt; class, for example, is marked as &lt;code&gt;sealed&lt;/code&gt;, meaning that it cannot be extended.  &lt;p&gt;For more on using inheritance, see Ian Stallings article, &lt;a href="http://www.4guysfromrolla.com/webtech/022001-1.shtml"&gt;Using Object-Orientation in ASP.NET: Inheritance&lt;/a&gt;. &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;&lt;b&gt;Creating Extension Methods for &lt;code&gt;System.DateTime&lt;/code&gt;&lt;/b&gt;&lt;br&gt;Let&amp;#39;s look at how to create and use extension methods. Many online messageboard sites - like the &lt;a href="http://forums.asp.net/"&gt;ASP.NET Forums&lt;/a&gt; - display the times the messages were posted using descriptions relative to the current date and time (rather than simply displaying the full date and time). For example, if a post was made within the last minute, the post&amp;#39;s date value might read: &amp;quot;Seconds ago.&amp;quot; Alternatively, if the post happened in the past few minutes, the message might read: &amp;quot;3 minutes ago.&amp;quot; If the post happened within the current date, it might just show the time, like: &amp;quot;10:34 AM&amp;quot;. If the post happened in a prior day, then the entire date and time would be displayed: &amp;quot;December 3rd, 2007 10:34 AM.&amp;quot; &lt;/p&gt;  &lt;p&gt;The &lt;code&gt;System.DateTime&lt;/code&gt; class has a number of formatting methods - &lt;code&gt;ToString()&lt;/code&gt;, &lt;code&gt;ToShortDateString()&lt;/code&gt;, and &lt;code&gt;ToLongTimeString()&lt;/code&gt;, to name a few - but wouldn&amp;#39;t it be nice to have a method like &lt;code&gt;ToRelativeToCurrentTimeString()&lt;/code&gt; method that effected the logic described above? We can add such a method using extension methods. Let&amp;#39;s create two such extension methods on the &lt;code&gt;System.DateTime&lt;/code&gt; class: &lt;code&gt;ToRelativeToCurrentTimeString()&lt;/code&gt; and &lt;code&gt;ToRelativeToCurrentUtcTimeString()&lt;/code&gt;. These methods will both operate on a &lt;code&gt;DateTime&lt;/code&gt; instance and return a string that displays a time description relative to the current time (or &lt;a href="http://aspnet.4guysfromrolla.com/articles/081507-1.aspx"&gt;UTC time&lt;/a&gt;). &lt;/p&gt;  &lt;p&gt;Since the syntax for creating extension methods differs quite a bit between VB and C#, let&amp;#39;s examine first implement these extension methods using VB; after doing so, we will create the extension methods in C#. The download at the end of this article includes two &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; website applications, either of which you can open with Visual Studio 2008: one in VB and one in C#. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Creating the Extension Methods with Visual Basic&lt;/b&gt;&lt;br&gt;In order to create the extension methods in Visual Basic we need to first create a &lt;code&gt;Module&lt;/code&gt;. For each extension method you want to create, add a method whose first input parameter is of the type that you want to add the extension method to. Moreover, prefix the method with the &lt;code&gt;Extension()&lt;/code&gt; attribute. &lt;/p&gt;  &lt;p&gt;The following &lt;code&gt;Module&lt;/code&gt; named &lt;code&gt;DateTimeHelpers&lt;/code&gt; contains two methods: &lt;code&gt;ToRelativeToCurrentTimeString(&lt;i&gt;DateTime&lt;/i&gt;)&lt;/code&gt; and &lt;code&gt;ToRelativeToCurrentUtcTimeString(&lt;i&gt;DateTime&lt;/i&gt;)&lt;/code&gt;, both of which accept a &lt;code&gt;DateTime&lt;/code&gt; instance as their first input parameter. The methods are also marked with the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.compilerservices.extensionattribute%28VS.90%29.aspx"&gt;&lt;code&gt;Extension()&lt;/code&gt; attribute&lt;/a&gt; (which is found in the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.compilerservices%28VS.90%29.aspx"&gt;&lt;code&gt;System.Runtime.CompilerServices&lt;/code&gt; namespace&lt;/a&gt;). The two methods call the private &lt;code&gt;ToRelativeString&lt;/code&gt; method, which returns the appropriate string message based on the difference in time between the two passed-in &lt;code&gt;DateTime&lt;/code&gt; values. &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;Imports System.Runtime.CompilerServices&lt;br&gt;Imports Microsoft.VisualBasic&lt;br&gt;&lt;br&gt;Namespace Helpers&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Public Module DateTimeHelpers&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Extension()&amp;gt; _&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Public Function ToRelativeToCurrentTimeString(ByVal dt As DateTime) As String&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;Return ToRelativeString(dt, DateTime.Now)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Function&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Extension()&amp;gt; _&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Public Function ToRelativeToCurrentUtcTimeString(ByVal dt As DateTime) As String&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;Return ToRelativeString(dt, DateTime.UtcNow)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Function&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Private Function ToRelativeString(ByVal timeInPast As DateTime, ByVal currentTime As DateTime) As String&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;If timeInPast.Date &amp;lt;&amp;gt; currentTime.Date 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;#39; timeInPast happend more than a day ago... show the date &amp;amp; time&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; Return timeInPast.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;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;#39; timeInPast and currentTime happened on the same day...&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 secondsApart As Integer = Convert.ToInt32(currentTime.Subtract(timeInPast).TotalSeconds)&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; &amp;#39; See if the date dt is within the last hour...&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 secondsApart &amp;lt; 10 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; Return &amp;quot;Seconds ago...&amp;quot;&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; ElseIf secondsApart &amp;lt; 60 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; Return &amp;quot;Less than a minute ago...&amp;quot;&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; ElseIf secondsApart &amp;lt; 3600 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; Return String.Format(&amp;quot;{0:N0} minutes ago...&amp;quot;, secondsApart / 60 + 1)&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;&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;#39; Ok, the date is more than an hour old... show the time&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; Return timeInPast.ToShortTimeString()&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;End If&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Function&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Module&lt;br&gt; End Namespace &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;We can now call these extension methods from a &lt;code&gt;DateTime&lt;/code&gt; instance. In order to use an extension method, we first need to add an &lt;code&gt;Imports&lt;/code&gt; directive to the code file, importing the namespace where the extension methods reside (&lt;code&gt;Helpers&lt;/code&gt;). Upon doing that, the extension method is visible in the IntelliSense drop-down list, as the following screen shot illustrates. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;center&gt;&lt;img border="0" src="http://aspnet.4guysfromrolla.com/images/ExtMethods1.gif" width="587" height="544"&gt; &lt;/center&gt; &lt;p&gt;The download at the end of this article includes a demo that allows the visitor to enter a date and time value into a TextBox. On postback, the entered value is converted into a &lt;code&gt;DateTime&lt;/code&gt; and the return value from the &lt;code&gt;ToRelativeToCurrentTimeString()&lt;/code&gt; method is displayed in a Label Web control. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt; &lt;center&gt;&lt;img border="0" src="http://aspnet.4guysfromrolla.com/images/ExtMethods2.gif" width="405" height="268"&gt; &lt;/center&gt; &lt;p&gt; &lt;table style="BORDER-RIGHT: rgb(51,51,51) 1px solid; PADDING-RIGHT: 6px; PADDING-LEFT: 6px; BORDER-TOP: rgb(51,51,51) 1px solid; PADDING-BOTTOM: 6px; BORDER-LEFT: rgb(51,51,51) 1px solid; WIDTH: 88%; PADDING-TOP: 6px; BORDER-BOTTOM: rgb(51,51,51) 1px solid; BACKGROUND-COLOR: lightyellow" align="center"&gt;  &lt;tbody&gt; &lt;tr&gt; &lt;th&gt;Extension Methods with Input Parameters&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;The &lt;code&gt;ToRelativeToCurrentTimeString()&lt;/code&gt; and &lt;code&gt;ToRelativeToCurrentUtcTimeString()&lt;/code&gt; methods are defined in the &lt;code&gt;Module&lt;/code&gt; as having one input parameter of type &lt;code&gt;DateTime&lt;/code&gt;. This results in an extension method applied to the &lt;code&gt;DateTime&lt;/code&gt; type that has no input parameters. But what if we needed to pass in one or more parameters to the &lt;code&gt;ToRelativeToCurrentTimeString()&lt;/code&gt;? For example, maybe we wanted to pass in some integer value like so: &lt;code&gt;&lt;i&gt;DateTimeInstance&lt;/i&gt;.ToRelativeToCurrentTimeString(&lt;i&gt;someIntegerValue&lt;/i&gt;)&lt;/code&gt;.  &lt;p&gt;To accomplish this, simply update the definition of the &lt;code&gt;ToRelativeToCurrentTimeString()&lt;/code&gt; method so that it takes in two input parameters: a &lt;code&gt;DateTime&lt;/code&gt; first and then an &lt;code&gt;Integer&lt;/code&gt; like so: &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;&amp;lt;Extension()&amp;gt; _&lt;br&gt;Public Function ToRelativeToCurrentTimeString(ByVal dt As DateTime, &lt;b&gt;ByVal i As Integer&lt;/b&gt;) As String&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br&gt;End Function &lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt; &lt;p&gt;The order of the input parameter&amp;#39;s are important with extension methods, because the &lt;i&gt;first&lt;/i&gt; parameter is the type that the extension method is applied to. In other words, if you redefined the extension method so that the &lt;code&gt;Integer&lt;/code&gt; parameter was the first input parameter, and the &lt;code&gt;DateTime&lt;/code&gt; the second, then the resulting extension method would be applied to objects of type &lt;code&gt;Integer&lt;/code&gt;. &lt;/p&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;&lt;b&gt;Creating the Extension Methods with C#&lt;/b&gt;&lt;br&gt;The syntax for creating the extension methods in C# is a little different than in Visual Basic. The equivalent of a &lt;code&gt;Module&lt;/code&gt; in C# is a &lt;code&gt;static class&lt;/code&gt;. Also, the methods in a &lt;code&gt;static class&lt;/code&gt; must be marked as &lt;code&gt;static&lt;/code&gt;, as well. Finally, instead of using the &lt;code&gt;Extension()&lt;/code&gt; attribute, C# requires that the &lt;code&gt;this&lt;/code&gt; keyword be used for the input parameter whose type the extension method will be applied. &lt;/p&gt;  &lt;p&gt; &lt;table border="0" width="95%"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td bgcolor="#cccccc" width="100%"&gt;&lt;code&gt;using System;&lt;br&gt;&lt;br&gt;namespace Helpers&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static class DateTimeHelpers&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string ToRelativeToCurrentTimeString(this DateTime dt)&lt;br&gt;&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;return ToRelativeString(dt, DateTime.Now);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string ToRelativeToCurrentUtcTimeString(this DateTime dt)&lt;br&gt;&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;return ToRelativeString(dt, DateTime.UtcNow);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static string ToRelativeString(DateTime timeInPast, DateTime currentTime)&lt;br&gt;&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;if (currentTime.Date != timeInPast.Date)&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; // dt happend more than a day ago... show the date &amp;amp; time&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; return timeInPast.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;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;{&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; // dt and rightNow happened on the same day...&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; int secondsApart = Convert.ToInt32(currentTime.Subtract(timeInPast).TotalSeconds);&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; // See if the date dt is within the last hour...&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 (secondsApart &amp;lt; 10)&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; return &amp;quot;Seconds ago...&amp;quot;;&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 if (secondsApart &amp;lt; 60)&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; return &amp;quot;Less than a minute ago...&amp;quot;;&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 if (secondsApart &amp;lt; 3600)&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; return string.Format(&amp;quot;{0:N0} minutes ago...&amp;quot;, secondsApart / 60 + 1);&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; // Ok, the date is more than an hour old... show the time&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; return timeInPast.ToShortDateString();&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;}&lt;br&gt;&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;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;With the extension methods defined, they can be used in code as if they were native members on the underlying type. Like with the Visual Basic example, in order to use the extension methods in a code file you must import the appropriate namespace (&lt;code&gt;Helpers&lt;/code&gt;) via the &lt;code&gt;using&lt;/code&gt; statement (i.e., &lt;code&gt;using Helpers;&lt;/code&gt;). &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Things to Remember When Using Extension Methods&lt;/b&gt;&lt;br&gt;When using extension methods there are a few things to keep in mind. First, realize that extension methods are simply &lt;a href="http://en.wikipedia.org/wiki/Syntactic_sugar"&gt;syntactic sugar&lt;/a&gt; - they do not introduce any new functionality, but just provide existing functionality in a more human-friendly syntax. Underneath the covers, the design-time experience allows for the IntelliSense functionality, but in actuality an extension method call is compiled into a call to the appropriate method in the static class or &lt;code&gt;Module&lt;/code&gt;. In other words, extension methods are synonymous with wrapper classes - the only difference is the design-time syntax. &lt;/p&gt;  &lt;p&gt;Since extension methods are functionality equivalent to wrapper classes, the same limitations apply. A wrapper class, for instance, can only access public members of the types it is working with. Likewise, an extension method defined on a type can only work with those types public members. It cannot read or write protected members (which is possible with inheritance). Moreover, extension &lt;b&gt;methods&lt;/b&gt; can only be applied to methods - there is no such thing as an extension &lt;i&gt;property&lt;/i&gt; or an extension &lt;i&gt;event&lt;/i&gt;. &lt;/p&gt;  &lt;p&gt;Finally, don&amp;#39;t forget that in order to use an extension method you must import the appropriate namespace into your code. In VB that means you&amp;#39;ll need to do an &lt;code&gt;Import &lt;i&gt;namespace&lt;/i&gt;&lt;/code&gt;. In C# it&amp;#39;s &lt;code&gt;using &lt;i&gt;namespace&lt;/i&gt;;&lt;/code&gt;. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br&gt;In this article we looked at a new feature in C# 3.0 and Visual Basic 9.0: extension methods. We saw how to create and use a simple extension method in both C# and VB. The download at the end of this article includes the code examined in this article along with a simple demo application illustrating the extension method is use. &lt;/p&gt;  &lt;p&gt;Happy Programming! &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;li&gt;By &lt;a href="http://www.4guysfromrolla.com/ScottMitchell.shtml"&gt;Scott Mitchell&lt;/a&gt;&lt;/li&gt;&lt;/div&gt; &lt;p&gt;Source: &lt;a href="http://aspnet.4guysfromrolla.com/articles/120507-1.aspx#postadlink"&gt;http://aspnet.4guysfromrolla.com/articles/120507-1.aspx#postadlink&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-6846535443131746069?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/6846535443131746069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=6846535443131746069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/6846535443131746069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/6846535443131746069'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/extending-base-type-functionality-with.html' title='Extending Base Type Functionality with Extension Methods'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-5578240895281282805</id><published>2008-03-14T10:25:00.001+07:00</published><updated>2008-03-14T10:25:10.950+07:00</updated><title type='text'>Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 2</title><content type='html'>&lt;div&gt;&lt;span class="subtitle"&gt;Abstract&lt;/span&gt; &lt;br&gt;&lt;span id="abstractLabel"&gt;In the second part of the article series about &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework, Keyvan adds controllers to his blogging engine in order to describe how to use controllers in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC and discusses some details related to controllers. He first discusses the concept of URL routing patterns and then explores the anatomy of a controller class. Finally, he examines how to implement the controllers in his sample blog application.&lt;/span&gt;&amp;nbsp;&lt;table&gt; &lt;td class="photo"&gt;&lt;a id="authorLink" href="http://aspalliance.com/author.aspx?uId=58927"&gt;&lt;/a&gt;&lt;/td&gt; &lt;/table&gt;&lt;/div&gt; &lt;div&gt;&lt;table&gt;&lt;tr&gt;&lt;td colspan="2"&gt;by &lt;span id="author" class="author"&gt;&lt;a href="http://aspalliance.com/author.aspx?uId=58927"&gt;Keyvan Nayyeri&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="author"&gt;&lt;/span&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;span class="author"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page1" class="pageTitle"&gt;Introduction&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;In the &lt;a href="http://aspalliance.com/1538_Building_a_Simple_Blog_Engine_with_ASPNET_MVC_and_LINQ__Part_1" target="_blank"&gt;first part&lt;/a&gt; of this article series about &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework, I gave a short introduction to Model View Controller (MVC) pattern, &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC and the basic structure of the sample blogging engine that I am going to build in this article series and have named it KBlog.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;In this second part I am going to cover one of the main three elements in MVC pattern which is controller.&lt;/p&gt; &lt;p class="MsoNormal"&gt;Controller is the most common element of the MVC pattern and is responsible for handling user inputs and executing appropriate codes to load data and display them to the user.&lt;/p&gt; &lt;p class="MsoNormal"&gt;Even though this is not a 100% correct definition, you can consider controller as an intermediate component between the user and view which tries to handle the user inputs and displays the appropriate output to him or her.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Normally, you use some template files to handle different requests in your web applications. It means that you have a page named Post.aspx to handle requests to such a post and the same for other pages. In MVC framework this is different and you use controller classes to handle requests. In other words, you no longer handle user requests with .aspx pages. Instead, you write controller classes that handle requests and pass appropriate data to view pages to be shown to the end users.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;But how do controller classes receive requests? To do this, &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; uses an URL routing mechanism that uses routes to route incoming requests to appropriate controller classes. There is a default definition for routing in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC framework, but you can change it for your own needs as I will do for KBlog in this article series. I will cover routing mechanism in the future parts, but for this part I give a quick overview of the necessary parts.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The other topic that I will cover in this article is the anatomy of controller classes and their structure as well as the action methods and how to pass parameters to action methods in order to route requests to them.&lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page2" class="pageTitle"&gt;Default URL Routing Pattern&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;As I stated, there is a default routing pattern for routing mechanism in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC framework that you can modify for your own. This mechanism can be modified in the &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; Application Class (Global.asax file).&lt;/p&gt;  &lt;p class="MsoNormal"&gt;But here I do not care about routing mechanism details and how to modify it. A future article of this series covers this in good detail, but I just talk quickly about the default routing pattern.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;By default, &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC framework routes requests to &lt;span class="Italic"&gt;/Url/&lt;/span&gt; paths to a controller class with &lt;span class="Italic"&gt;UrlController&lt;/span&gt; name. As an instance, requests to &lt;span class="Italic"&gt;/Post/&lt;/span&gt; URL will be routed to &lt;span class="Italic"&gt;PostController&lt;/span&gt; class by default.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Moreover, all requests to URL&amp;#39;s under &lt;span class="Italic"&gt;/Url/&lt;/span&gt; path will be routed to &lt;span class="Italic"&gt;UrlController&lt;/span&gt; class as well. For instance, requests to &lt;span class="Italic"&gt;/Post/Technology/Surface&lt;/span&gt; will be routed to &lt;span class="Italic"&gt;PostController&lt;/span&gt; class.&lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page3" class="pageTitle"&gt;The Anatomy of a Controller Class&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;A controller class is a class just like other classes. It is not necessary to derive this class from a special class or implement an interface for it, but it is recommended to derive a controller class from System.Web.MVC.Controller base class for ease of development and getting the benefits of this base class in your development.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Controller class provides some tools that can assist you on developing your &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC applications and I do not think any developer wants to avoid using it. Controller class is applied to all project and file item templates in Visual Studio and whenever you create a new MVC controller class in Visual Studio this class appears in your code.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;You can add a new MVC controller class file in the Add New Item dialog as is shown in Figure 1.&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Figure 1&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;img border="0" src="http://aspalliance.com/ArticleFiles/1559/image001.jpg" width="662" height="407"&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;Listing 1 shows the default code for a controller class that I named &lt;span class="Italic"&gt;SampleController&lt;/span&gt;.&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 1&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web.Mvc; &amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt;&amp;nbsp;KBlog.Controllers { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt;&amp;nbsp;SampleController&amp;nbsp;:&amp;nbsp;Controller &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ControllerAction] &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Index() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Add&amp;nbsp;action&amp;nbsp;logic&amp;nbsp;here&lt;/span&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;} }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;As you see, there is a reference to &lt;span class="Italic"&gt;System.Web.Mvc&lt;/span&gt; namespace which comes to your machine after installing the &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 3.5 extensions and the class is also derived from the &lt;span class="Italic"&gt;Controller&lt;/span&gt; base class.&lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page4" class="pageTitle"&gt;Action Methods&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;The main part of a controller class is its action methods. Action methods are just some public methods that do not return anything and are marked with a &lt;span class="Italic"&gt;ControllerAction&lt;/span&gt; attribute which makes a method an action method.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;But what is the responsibility of an action method? Well, an action method receives a request and triggers appropriate logic to fetch data from the data model and passes this data to views in order to show the appropriate result to end users. So action methods are like the heart of the controller class.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;But how do action methods work? Action methods work based on the parameters that are passed to them. Obviously, URL&amp;#39;s represent the content that a user is looking for and routing mechanism routes each request to the appropriate controller class. But here, parameters specify the action that should take place.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;For instance, when the user is viewing a page like &lt;span class="Italic"&gt;/Post?ID=5&lt;/span&gt; then the request should be routed to &lt;span class="Italic"&gt;PostController&lt;/span&gt; class where Post action method handles the request in some ways.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Listing 2 adds an action method to Listing 1.&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 2&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web.Mvc; &amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt;&amp;nbsp;KBlog.Controllers { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt;&amp;nbsp;SampleController&amp;nbsp;:&amp;nbsp;Controller &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ControllerAction] &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Index() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Add&amp;nbsp;action&amp;nbsp;logic&amp;nbsp;here&lt;/span&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;} }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;By default, there is a &lt;span class="Italic"&gt;HomeController&lt;/span&gt; class in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC projects that handles requests to default home pages.&lt;/p&gt; &lt;p class="MsoNormal"&gt;In the next section I will discuss more about the parameters in action methods.&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page5" class="pageTitle"&gt;Parameters in Action Methods&lt;/a&gt;&lt;/span&gt;&lt;br&gt;  &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Parameters are the key part of the controller class and specify the user&amp;#39;s choice to actions methods. Parameters come directly from the URL and its query parameters and you need to decide how to use them with your own logic.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;There are some different ways to handle parameters in action methods and it is left to you to decide how to do this.&lt;/p&gt; &lt;p class="MsoNormal"&gt;The first approach is to use query parameters and fetch them in the action method from the URL. Obviously, this approach does not need any parameter for the action method. Listing 3 shows such an action method that retrieves the ID parameter from query string.&lt;/p&gt;  &lt;p class="CodeListingHeading"&gt;Listing 3&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL:&amp;nbsp;/Page/Article?ID=5&lt;/span&gt; [ControllerAction] &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Article() { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;&amp;nbsp;id&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Convert.ToInt32(Request[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;]); }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;The first approach was something that you could do in all &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; web applications as well. In the second approach you pass the URL parameter to the action method as its parameter by defining the type.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Listing 4 shows an example of this approach. You can simply use the id parameter in your action method to write your logic.&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 4:&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL:&amp;nbsp;/Page/Article?ID=5&lt;/span&gt; [ControllerAction] &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Article(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;&amp;nbsp;id) { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Implement&amp;nbsp;the&amp;nbsp;logic&amp;nbsp;to&amp;nbsp;handle&amp;nbsp;the&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;request&amp;nbsp;based&amp;nbsp;on&amp;nbsp;the&amp;nbsp;id&amp;nbsp;parameter&lt;/span&gt; }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;The last way is similar to the previous one. You handle parameters via action method parameters, but parameters also come from sub-paths. So if you have a URL like /Page/Article/5, then 5 can be considered as the ID parameter to be passed to the controller.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Listing 5 shows this in action.&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 5:&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL:&amp;nbsp;/Page/Article/5&lt;/span&gt; [ControllerAction] &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Article(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;&amp;nbsp;id) { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Implement&amp;nbsp;the&amp;nbsp;logic&amp;nbsp;to&amp;nbsp;handle&amp;nbsp;the&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;request&amp;nbsp;based&amp;nbsp;on&amp;nbsp;the&amp;nbsp;id&amp;nbsp;parameter&lt;/span&gt; }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;You can use nullable type arguments in order to pass optional parameters to an action method. For instance, suppose that you have an article that consists of several sections. In one case the user can request the whole article and in an optional case he can also pass a Section parameter to get a specific section based on its unique string title.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;In listing 6 you see how this can be implemented.&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 6:&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL&amp;nbsp;1:&amp;nbsp;/Page/Article/5&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL&amp;nbsp;2: /Page/Article/5?section=introduction&lt;/span&gt; [ControllerAction] &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Article(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;&amp;nbsp;id,&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;?&amp;nbsp;section) { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Implement&amp;nbsp;the&amp;nbsp;logic&amp;nbsp;to&amp;nbsp;handle&amp;nbsp;the&amp;nbsp;request&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;based&amp;nbsp;on&amp;nbsp;the&amp;nbsp;id&amp;nbsp;and/or&amp;nbsp;section&amp;nbsp;parameters&lt;/span&gt; }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page6" class="pageTitle"&gt;Implementing the Controllers for KBlog&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Now that we have gotten familiar with the principles of controller classes, action methods and action parameters, we can apply them in KBlog to update our code.&lt;/p&gt; &lt;p class="MsoNormal"&gt;For KBlog we need three controllers (regarding that here we just want to build a very simple blogging engine to show some concepts):&lt;/p&gt; &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Controller for homepage which is our index: We load data for recent N posts and the list of all categories.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Controller for individual posts: We load data for a specific post based on its ID.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Controller for individual categories: We load all posts that are in a specified category based on its unique name.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Listing 7 is the code for the homepage in &lt;span class="Italic"&gt;HomeController&lt;/span&gt; where we do not need to pass any parameter. Later I will update this controller to load recent posts and all categories and pass them to the appropriate view. For now, just focus on the controller part of the code.&lt;/p&gt;  &lt;p class="CodeListingHeading"&gt;Listing 7:&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web.Mvc; &amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt;&amp;nbsp;KBlog.Controllers { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt;&amp;nbsp;HomeController&amp;nbsp;:&amp;nbsp;Controller &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL:&amp;nbsp;/Default.aspx&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ControllerAction] &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Index() &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;The other controller is &lt;span class="Italic"&gt;PostsController&lt;/span&gt; where we handle requests for individual posts based on the unique ID (Listing 8). Note that later we need to modify the default routing definitions in order to route request to this controller.&lt;/p&gt;  &lt;p class="CodeListingHeading"&gt;Listing 8:&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web.Mvc; &amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt;&amp;nbsp;KBlog.Controllers { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt;&amp;nbsp;PostsController&amp;nbsp;:&amp;nbsp;Controller &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL:&amp;nbsp;/Post/25&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ControllerAction] &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Post(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt;&amp;nbsp;id) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;And the last controller is &lt;span class="Italic"&gt;CategoriesController&lt;/span&gt; where we handle requests for a specific category based on its unique string name and load all posts in that category (Listing 9). Like &lt;span class="Italic"&gt;PostsController&lt;/span&gt; we need to modify default routing definition in order to route requests to this controller.&lt;/p&gt;  &lt;p class="CodeListingHeading"&gt;Listing 9:&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt;&amp;nbsp;System.Web.Mvc; &amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt;&amp;nbsp;KBlog.Controllers { &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt;&amp;nbsp;CategoriesController&amp;nbsp;: Controller &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//&amp;nbsp;Sample&amp;nbsp;URL:&amp;nbsp;/Category/DotNet&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ControllerAction] &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Category(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;nbsp;name) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page7" class="pageTitle"&gt;Summary&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;In the second part of my articles about &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 3.5 MVC framework I discussed controller as one of the main parts of the MVC pattern.&lt;/p&gt; &lt;p class="MsoNormal"&gt;First, I introduced controllers then talked about the anatomy of controller classes in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC. Then I talked about action methods and their parameters. Finally, I applied these theories in KBlog to move forward in the development of the simple sample blogging engine that I am going to write in this article series.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;In the future parts I will talk about data model, views, unit testing of MVC applications, URL routing and other related ideas.&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-5578240895281282805?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/5578240895281282805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=5578240895281282805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/5578240895281282805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/5578240895281282805'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/building-simple-blog-engine-with-aspnet_14.html' title='Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 2'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-3609637350381348255</id><published>2008-03-13T09:41:00.001+07:00</published><updated>2008-03-13T09:41:21.027+07:00</updated><title type='text'>Working with Callback and Control Rendering</title><content type='html'>&lt;span id="intellitTxt"&gt;Introduction&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;In my previous article, I wrote about Callback and JSON based JavaScript serialization which you can find &lt;a href="http://aspalliance.com/1537_ICallback__JSON_Based_JavaScript_Serialization" target="_blank"&gt;here&lt;/a&gt;. Callback doesn&amp;#39;t cause postback and page rendering, neither full nor even partial. With it we can communicate with the server (IIS) and our server side code runs there successfully and could rebind our controls like DropDownList, GridView, ListView, DataList, Repeater, or any server side control to which you assign data. The problem is when the page won&amp;#39;t render, its controls won&amp;#39;t render, and if controls won&amp;#39;t render then changes won&amp;#39;t reflect. When changes don&amp;#39;t reflect there won&amp;#39;t be anything at the front end to show on the webpage.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;This article is mainly about callback and rendering controls but through this tutorial you can also learn many other things; how postbacks work, how rendering works, how to dynamically create server-side controls, how to create DataTables dynamically in memory to bind with, how to get server-side controls during client-side execution and set their properties, and how to register client-side events of server side control from the server-side code.&lt;/p&gt; &lt;/div&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page2" class="pageTitle"&gt;Important Terms&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;First of all, I would like to briefly describe some terms of which I believe every web developer should be aware. &lt;/p&gt; &lt;p class="SectionHeading"&gt;Postback&lt;/p&gt; &lt;p class="MsoNormal"&gt;A postback is a mechanism of communication between client-side (browser) and server-side (IIS). Through a postback all contents of page/form(s) are sent to the server from client for processing. After following the page life cycle, all server-side contents get render into client-side code and the client (browser) displays the content. Callback is another form of communication between server and client. Callback doesn't follow the page life cycle which is followed by standard postback, and it doesn&amp;#39;t even cause rendering.&lt;/p&gt;  &lt;p class="SectionHeading"&gt;Rendering&lt;/p&gt; &lt;p class="MsoNormal"&gt;Rendering is the process of converting server-side code/content into client-side code/content so the client (browser) can understand the code and could display the output. Browsers can understand, or you may say decode, code of client-side languages and scripts like HTML, DHTML, XHTML, JavaScript, VbScript, etc. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;If rendering doesn&amp;#39;t happen then changes won't be reflected at client-side. Ajax leverages partial page postbacks automatically whereas callback doesn&amp;#39;t, so programmer needs to perform that task manually. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;The &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; team has created a RenderControl method which is applied to the base control. By using that method we can render our controls very easily.&lt;/p&gt; &lt;p class="SectionHeading"&gt;Callback&lt;/p&gt; &lt;p class="MsoNormal"&gt;Callback is a lightweight process. It uses the well known XMLHTTP object internally to call server side methods. It doesn&amp;#39;t cause page postback so doesn't cause page rendering, so if we want to show output at client side, we need to make output html ourselves and render controls manually.&lt;/p&gt;  &lt;p class="SectionHeading"&gt;ICallbackEventHandler&lt;/p&gt; &lt;p class="MsoNormal"&gt;ICallback is implemented in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; by using the ICallbackEventHandler interface, which has two methods, one of them used to be called from JavaScript (client-side code) and the other one returned results asynchronously back to the JavaScript function.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;We just need to perform some action through server-side code at server-side and need to return results, but the results could be an instance or object of a class which might not be easy for JavaScript code to handle, so here we prefer JSON which stands for JavaScript Object Notation.&lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;Real Time Scenario with implementation &lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Suppose we have categories, subcategories, products data, and we need to populate categories and subcategories which depend upon categories, and the data would be populated in two different DropDownLists. For products data which contains multiple columns so we need to show that data in tabular format so I would prefer GridView control. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;So the situation would be load/populate categories on Page_Load and load/populate subcategories on the basis of selected category using callback and finally load products into Gridview on the basis of selected subcategory. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;Before starting coding, I would like to write the Pseudo code for better understanding. &lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page4" class="pageTitle"&gt;Steps&lt;/a&gt;&lt;/span&gt;&lt;br&gt;  &lt;div class="KonaBody"&gt; &lt;p class="MsoListNumber"&gt;1.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Create Server side controls e.g. DropDownLists and GridView&lt;/p&gt; &lt;p class="MsoListNumber"&gt;2.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Load Categories on Page load &lt;/p&gt; &lt;p class="MsoListNumber"&gt;3.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Implement ICallbackEventHandler interface&lt;/p&gt; &lt;p class="MsoListNumber"&gt;4.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Create subcategories data in server memory to bind to Subcategory DropDownLists.&lt;/p&gt;  &lt;p class="MsoListNumber"&gt;5.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Render control (subcategory DropDownLists) and show output.&lt;/p&gt; &lt;p class="MsoListNumber"&gt;6.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Create products data in server memory to bind to Products GridView.&lt;/p&gt;  &lt;p class="MsoListNumber"&gt;7.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Render Control (products GridView) and return rendered contents to client side to show&lt;/p&gt;  &lt;p class="MsoListNumber"&gt;8.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Set innerHTML of each control by rendered contents&lt;/p&gt; &lt;p class="SectionHeading"&gt;Create DropDownLists and GridView Controls&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 1&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;b&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;Categories:&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;b&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;br&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;asp:DropDownList&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;ID&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;quot;ddlCategories&amp;quot;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;runat&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;Width&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;quot;100&amp;quot;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;onchange&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;quot;CallSrv(this);&amp;quot;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;asp:DropDownList&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;br&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;b&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;Subcategories&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;b&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;: &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;div&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;id&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;quot;ddlSubcategories&amp;quot;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;div&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;b&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;Products:&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;b&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;div&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;id&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;quot;grvProducts&amp;quot;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;div&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt; &lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;Callback Server side code&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Let&amp;#39;s implement the ICallbackEventHandler to call server side methods asynchronously step by step&lt;/p&gt; &lt;p class="MsoNormal"&gt;Implement Server Side (C#) Page/Control class by System.Web.UI.ICallbackEventHandler &lt;/p&gt; &lt;p class="MsoNormal"&gt;Following are definition of two methods which needs to implement:&lt;/p&gt; &lt;p class="MsoNormal"&gt;RaiseCallbackEvent method invoke by JavaScript function&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 2&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;RaiseCallbackEvent(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; eventArgument) { &amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]commands&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; eventArgument.Split(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&amp;nbsp;.ToCharArray()); &amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (commands[0].Equals(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;LoadSubCategory&amp;quot;&lt;/span&gt;)) &amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DropDownList&amp;nbsp;ddlSubcategories&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; DropDownList(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;switch&lt;/span&gt;&amp;nbsp;(commands[1]) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Autos&amp;quot;&lt;/span&gt;: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ddlSubcategories.Items.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Cars&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ddlSubcategories.Items.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Bikes&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Electronics&amp;quot;&lt;/span&gt;: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ddlSubcategories.Items.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Computers&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ddlSubcategories.Items.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;TV&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp; ddlSubcategories.Attributes.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;onchange&amp;quot;&lt;/span&gt;,&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;CallSrv(this);&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.Text.StringBuilder&amp;nbsp;sb&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; System.Text.StringBuilder(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.IO.StringWriter&amp;nbsp;sw&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; System.IO.StringWriter(sb); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HtmlTextWriter&amp;nbsp;htw&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt;&amp;nbsp;HtmlTextWriter(sw); &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ddlSubcategories.RenderControl(htw); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.RenderedOutput&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;LoadSubCategory,&amp;quot;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;&amp;nbsp;sb.ToString(); &amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (commands[0].Equals(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;LoadProducts&amp;quot;&lt;/span&gt;)) &amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DataTable&amp;nbsp;dtProducts&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt;&amp;nbsp;DataTable(); &amp;nbsp;&amp;nbsp;&amp;nbsp; dtProducts.Columns.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp; dtProducts.Columns.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Columns.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DataRow&amp;nbsp;drProduct; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;switch&lt;/span&gt;&amp;nbsp;(commands[1]) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Cars&amp;quot;&lt;/span&gt;: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Honda&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;2000&amp;nbsp;CC&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$1000&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Toyota&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;1800&amp;nbsp;CC&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$800&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Bikes&amp;quot;&lt;/span&gt;: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Pak&amp;nbsp;Hero&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;125&amp;nbsp;CC&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$100&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Honda&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;250&amp;nbsp;CC&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$150&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Computers&amp;quot;&lt;/span&gt;: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Dell&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;P4&amp;nbsp;Centrino&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$400&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;IBM&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;P4&amp;nbsp;Think&amp;nbsp;PAD&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$350&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;case&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;TV&amp;quot;&lt;/span&gt;: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Sony&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Plasma&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$600&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts.NewRow(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Philips&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductDescription&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Projection&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drProduct[&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ProductPrice&amp;quot;&lt;/span&gt;]&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;$550&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dtProducts.Rows.Add(drProduct); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;break&lt;/span&gt;; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GridView&amp;nbsp;grvProducts&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt;&amp;nbsp;GridView(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grvProducts.DataSource&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;dtProducts; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grvProducts.DataBind(); &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.Text.StringBuilder&amp;nbsp;sb&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; System.Text.StringBuilder(); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.IO.StringWriter&amp;nbsp;sw&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; System.IO.StringWriter(sb); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HtmlTextWriter&amp;nbsp;htw&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt;&amp;nbsp;HtmlTextWriter(sw); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grvProducts.RenderControl(htw); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.RenderedOutput&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;LoadProducts,&amp;quot;&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;&amp;nbsp;sb.ToString(); &amp;nbsp;&amp;nbsp;} } &amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;nbsp;GetCallbackResult() { &amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt;&amp;nbsp;RenderedOutput; }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p class="MsoNormal"&gt;In the Page_Load or Page_Init events &lt;/p&gt; &lt;p class="MsoNormal"&gt;Following statements are used to register client side methods. &lt;/p&gt; &lt;p class="MsoNormal"&gt;CallServer(arg, context) as name implies would use to call/raise server side method which was RaiseCallbackEvent string eventArgument)&lt;/p&gt; &lt;p class="MsoNormal"&gt;ReceiveServerData(arg, context) would use to get result through arg parameter by GetCallbackResult()&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Listing 3&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Register&amp;nbsp;Client&amp;nbsp;Script&amp;nbsp;for&amp;nbsp;Callback&amp;nbsp;and populate&amp;nbsp;categories&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt;&amp;nbsp;Page_Load(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt;&amp;nbsp;sender, EventArgs&amp;nbsp;e) { &amp;nbsp;&amp;nbsp;ClientScriptManager&amp;nbsp;scriptMgr&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Page.ClientScript; &amp;nbsp;&amp;nbsp;String&amp;nbsp;cbReference&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; scriptMgr.GetCallbackEventReference(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;,&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;arg&amp;quot;&lt;/span&gt;, &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;ReceiveServerData&amp;quot;&lt;/span&gt;, &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;String&amp;nbsp;callbackScript&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;function CallServer(arg,&amp;nbsp;context)&amp;nbsp;{&amp;quot;&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;&amp;nbsp;cbReference&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;;&amp;nbsp;}&amp;quot;&lt;/span&gt;; &amp;nbsp;&amp;nbsp;cm.RegisterClientScriptBlock(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.GetType(), &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;CallServer&amp;quot;&lt;/span&gt;,&amp;nbsp;callbackScript, &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;); &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt;&amp;nbsp;(!Page.IsPostBack) &amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//Load&amp;nbsp;Products&amp;nbsp;Data&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.ddlCategories.Items.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Select&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.ddlCategories.Items.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Autos&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.ddlCategories.Items.Add(&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: rgb(102,102,102); FONT-FAMILY: Courier New; BACKGROUND-COLOR: rgb(228,228,228)"&gt;&amp;quot;Electronics&amp;quot;&lt;/span&gt;); &amp;nbsp;&amp;nbsp;} }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page6" class="pageTitle"&gt;Callback client side code&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="CodeListingHeading"&gt;Listing 4&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;pre&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;script&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;language&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;nbsp;&amp;quot;JavaScript&amp;quot;&lt;/span&gt; &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;type&lt;/span&gt;&amp;nbsp;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&amp;nbsp;&amp;quot;text/JavaScript&amp;quot;&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt; function&amp;nbsp;ReceiveServerData(arg,&amp;nbsp;context) { &amp;nbsp;&amp;nbsp;var&amp;nbsp;cmd_content&amp;nbsp;=&amp;nbsp;arg.split(&amp;#39;,&amp;#39;); &amp;nbsp;&amp;nbsp;if&amp;nbsp;(cmd_content[0]&amp;nbsp;==&amp;nbsp;&amp;#39;LoadSubCategory&amp;#39;) &amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(&amp;#39;ddlSubcategories&amp;#39;).innerHTML&amp;nbsp;=&amp;nbsp;cmd_content[1]; &amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;else &amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById(&amp;#39;grvProducts&amp;#39;).innerHTML&amp;nbsp;=&amp;nbsp;cmd_content[1]; &amp;nbsp;&amp;nbsp;} } function&amp;nbsp;CallSrv(ddl) { &amp;nbsp; &amp;nbsp;&amp;nbsp;if&amp;nbsp;(&lt;a href="http://ddl.id"&gt;ddl.id&lt;/a&gt;&amp;nbsp;==&amp;nbsp;&amp;#39;ddlCategories&amp;#39;) &amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(ddl.value&amp;nbsp;!=&amp;nbsp;&amp;#39;Select&amp;#39;) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CallServer(&amp;#39;LoadSubCategory&amp;#39;&amp;nbsp;+&amp;nbsp;&amp;#39;,&amp;#39;&amp;nbsp;+ ddl.value,&amp;nbsp;&amp;#39;&amp;#39;); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;else &amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CallServer(&amp;#39;LoadProducts&amp;#39;&amp;nbsp;+&amp;nbsp;&amp;#39;,&amp;#39;&amp;nbsp;+ ddl.value,&amp;nbsp;&amp;#39;&amp;#39;); &amp;nbsp;&amp;nbsp;} } &lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;script&lt;/span&gt;&lt;span style="FONT-WEIGHT: normal; FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt; &lt;/div&gt; &lt;p class="MsoNormal"&gt;That&amp;#39;s it. These are the steps which you need to use to call and get result from server side code using ICallback.&lt;/p&gt; &lt;p class="MsoNormal"&gt;Asynchronously output would be within a millisecond and without Postback&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Figure 1&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;img border="0" src="http://aspalliance.com/ArticleFiles/1573/image001.jpg" width="320" height="178"&gt;&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page7" class="pageTitle"&gt;Downloads&lt;/a&gt;&lt;/span&gt;&lt;br&gt;  &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;[&lt;a href="http://authors.aspalliance.com/madnan/Callback_Rendering_Controls.rar" target="_blank"&gt;Download Sample&lt;/a&gt;]&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a id="#Page8" class="pageTitle"&gt;Conclusion&lt;/a&gt;&lt;/span&gt;&lt;br&gt;  &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Callback is a lightweight technique used to call server side methods asynchronously from JavaScript without any postback and reloading/rendering of unnecessary parts of a page and unnecessary code.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;So we can use that when we need to perform any operations at the backend on the server like updating records in database. You don&amp;#39;t need to send all your contents of page in a request and make that object heavyweight which could cause slow performance. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;Source: &lt;a href="http://aspalliance.com/1573_Working_with_Callback_and_Control_Rendering.all"&gt;http://aspalliance.com/1573_Working_with_Callback_and_Control_Rendering.all&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="2"&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-3609637350381348255?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/3609637350381348255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=3609637350381348255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/3609637350381348255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/3609637350381348255'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/working-with-callback-and-control.html' title='Working with Callback and Control Rendering'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-8286888859760739221</id><published>2008-03-12T09:32:00.000+07:00</published><updated>2008-03-12T09:33:26.950+07:00</updated><title type='text'>Accessing data using Language Integrated Query (LINQ) in ASP.NET WebPages – Part 1</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;This article comprises of two parts; Part 1 deals with the introduction to LINQ and LinqDataSource control in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; and describes how to define and retrieve an in-memory data collection and display data in a web page. Part 2 explains how to create entity classes to represent SQL Server database and tables using Object Relational Designer and display data in a web page using LinqDataSource control.&lt;/span&gt;&lt;/p&gt; &lt;table&gt;&lt;td class="NonPrintable" width="50%"&gt;    &lt;/td&gt;&lt;tr&gt;&lt;td colspan="2"&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleSubtitle"&gt;&lt;span lang="EN-IN"&gt;Introduction to LINQ&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Language Integrated Query (LINQ) is a query syntax that defines a set of query operators that allow traversal, filter, and projection operations to be expressed in a declarative way in any .NET-based programming language. It provides a unified programming model for querying and updating data from different types of data sources and extends data capabilities directly into the C# and Visual Basic languages. LINQ simplifies the interaction between object-oriented programming and relational data by applying the principles of object-oriented programming to relational data.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="MARGIN-BOTTOM: 3.75pt; TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;With the advent of LINQ, a ground-breaking, new concept of a &lt;i&gt;query&lt;/i&gt; has been introduced as a first-class language construct in C# and Visual Basic. &amp;nbsp;LINQ simplifies the way you work with data queries. LINQ offers you a unified, declarative syntax model to query any data source including an XML document, SQL database, an &lt;a href="http://ADO.NET"&gt;ADO.NET&lt;/a&gt; Dataset, an in-memory collection, or any other remote or local data source that chooses to support LINQ&amp;nbsp; Language Integrated Queries&amp;nbsp; are strongly typed and designer tools can be used to create object-relational mappings. It is easier now for developers to catch many errors during compile-time; also supports Intellisense and debugging.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleSubtitle"&gt;&lt;span lang="EN-IN"&gt;Sample Query&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;A query is an expression that retrieves data from a data source. All LINQ query operations consist of three essential actions: Obtain the data source,Create the query and Execute the query.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;In LINQ, the execution of the query is isolated from the query itself and hence data cannot be retrieved just by creating a query;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;In the following sample, a query retrieves even numbers from an array of integers.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;//&amp;nbsp; Data source.&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;int[] numbers = new int[10] { 0, 1, 2, 3, 4, 5, 6 ,8,9,10};&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;//&amp;nbsp; Query creation.&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;IEnumerable&amp;lt;int&amp;gt; numQuery =&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; from num in numbers&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;where (num % 2) == 0&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; select num;&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;//&amp;nbsp; Query execution. &lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;foreach (int j in numQuery)&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Write(&amp;quot;{0,1} &amp;quot;, j);&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span class="CodeTitleChar"&gt;&lt;span style="FONT-SIZE: 9pt" lang="EN-IN"&gt;Output will be:&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;0,2,4,6,8,10&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleSubtitle"&gt;&lt;span lang="EN-IN"&gt;LinqDataSource Control in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;As many of you familiar with various DataSource controls in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 2.0, the 2008 version of &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; includes a new DataSource control called LinqDataSource control. The LinqDataSource control enables us to retrieve, update data using Language Integrated Queries (LINQ) from an in-memory collection of data or SQL Server database tables. It automatically generates data commands for select, update, delete and insert operations and you need not have to create them manually.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;This control has two main properties:&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ListParagraphCxSpFirst"&gt;&lt;span lang="EN-IN"&gt;1.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;ContextTypeName property that represents the name of the type object that contains data collection&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpLast"&gt;&lt;span lang="EN-IN"&gt;2.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;TableName property that represents the name of the public field or property that returns data collection, or table name in case of database access.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span class="ArticleSubtitle"&gt;&lt;span style="FONT-SIZE: 9pt" lang="EN-IN"&gt;Walkthrough 1:&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt; Connecting in-memory data collection using LinqDataSource control and perform queries&amp;nbsp; to display dat in a ASP.Net page&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Open Visual Studio 2008 and create a New WebSite Project. &lt;/span&gt;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;Add a new class file to the App_Code folder of the project. Define classes that supplies data to the control and write LINQ Queries to retrieve data from them.&lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;public class &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string First { get; set; }&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Last { get; set; }&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int ID { get; set; }&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; Scores;&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;public class &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;gt; students = new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Svetlana&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Omelchenko&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID=111, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {97, 92, 81, 60}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Claire&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;O'Donnell&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID&lt;/span&gt;&lt;span lang="EN-IN"&gt;=112, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {75, 84, 91, 39}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Sven&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Mortensen&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID=113, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {88, 94, 65, 91}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Cesar&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;Garcia&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID&lt;/span&gt;&lt;span lang="EN-IN"&gt;=114, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {97, 89, 85, 82}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Debra&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;Garcia&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID&lt;/span&gt;&lt;span lang="EN-IN"&gt;=115, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {35, 72, 91, 70}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Fadi&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Fakhouri&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID=116, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {99, 86, 90, 94}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Hanying&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Feng&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID=117, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {93, 92, 80, 87}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Hugo&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;Garcia&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID&lt;/span&gt;&lt;span lang="EN-IN"&gt;=118, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {92, 90, 83, 78}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Lance&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Tucker&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID=119, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {68, 79, 88, 92}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Terry&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;Adams&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID&lt;/span&gt;&lt;span lang="EN-IN"&gt;=120, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {99, 82, 81, 79}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Eugene&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Zabokritski&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID=121, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {96, 85, 91, 60}},&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Student&lt;/span&gt;&lt;span lang="EN-IN"&gt; {First=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Michael&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, Last=&lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;Tucker&amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt;, ID=122, Scores= new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;List&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; {94, 92, 91, 91} }&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/span&gt;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;You have just added a Student Class and an initialized list of students in the class file. The data source for the queries is a simple list of Student objects. Each Student record has a first name, last name, and an array of integers that represents their test scores in the class. &lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleSubtitle"&gt;&lt;span lang="EN-IN"&gt;Creating Queries&lt;/span&gt;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;You can create number of queries to retrieve data from the datasource and in this article, I have create few queries for demonstration purposes. Each query is assigned to a public property or field so that it would be used in the LinqDataSource Controls in the WebPage.&lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="ListParagraphCxSpFirst" align="left"&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;1.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang="EN-IN"&gt;Queries of IEnumerable&amp;lt;StudentAverage&amp;gt; type&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="ListParagraphCxSpLast" align="left"&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue" lang="EN-IN"&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;public class &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentAverage&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int ID;&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string First;&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Last;&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public double ScoreAverage;&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;IEnumerable&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentAverage&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;gt; studentAverageMarks = from student in &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt;.students&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where student.Scores[0] &amp;gt; 90 &lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&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 new &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentAverage&lt;/span&gt;&lt;span lang="EN-IN"&gt; { ID=student.ID, First=student.First, Last=student.Last, ScoreAverage = student.Scores.Average()};&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Declared a new type StudentAverage that consists of ID,First, Last, ScoreAverage fields. This query returns the list of students with average marks.&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="ListParagraphCxSpFirst" align="left"&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;2.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span lang="EN-IN"&gt;Queries of IEnumerable&amp;lt;int&amp;gt; type&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="ListParagraphCxSpLast" align="left"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;public static int studentID;&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;public &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;IEnumerable&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;int&amp;gt; GetStudentTotal = from student in &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt;.students where student.ID == &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt;.studentID select student.Scores.Sum();&lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;Declared another public property that returns a int type of collection that holds the result from the query. This query retrieves sum total of all marks for a particular student and it uses a condition in the where clause. User will supply data to the parameter studentID during runtime.&lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;public&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;IEnumerable&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;int&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;gt; GetStudentList = &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;from&lt;/span&gt;&lt;span lang="EN-IN"&gt; student &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;in&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt;.students &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;select&lt;/span&gt;&lt;span lang="EN-IN"&gt; student.ID;&lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;GetStudentList is another property added to the class that stores the result of a query. This query returns a collection of Student.ID.&lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="ListParagraph" align="left"&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;3.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;Queries of Implicit Type(Anonymos Type)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;public&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;IEnumerable&lt;/span&gt;&lt;span lang="EN-IN"&gt; GetData&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;get&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;var&lt;/span&gt;&lt;span lang="EN-IN"&gt; studentMarks = &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;from&lt;/span&gt;&lt;span lang="EN-IN"&gt; student &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;in&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt;.students &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;where&lt;/span&gt;&lt;span lang="EN-IN"&gt; student.ID &amp;gt; 110 &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;select&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;new&lt;/span&gt;&lt;span lang="EN-IN"&gt; { ID = student.ID, First = student.First, Last = student.Last, ScoreTotal = student.Scores.Sum() };&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;foreach&lt;/span&gt;&lt;span lang="EN-IN"&gt; (&lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;var&lt;/span&gt;&lt;span lang="EN-IN"&gt; s &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;in&lt;/span&gt;&lt;span lang="EN-IN"&gt; studentMarks)&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&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; &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;yield&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;return&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;a href="http://s.ID"&gt;s.ID&lt;/a&gt; + &lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt; + s.Last + &lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt; + s.First + &lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)" lang="EN-IN"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span lang="EN-IN"&gt; + s.ScoreTotal;&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span style="FONT-SIZE: 10pt" lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;Now you have just added a public property that returns a query result as collection of Student's marks data. Note that the query involves an anonymous type that contains fields such as ID, First, Last and ScoreTotal. The query returns implicit type var and it uses Iterators to return the elements in the collection.&lt;/span&gt;&lt;/p&gt;  &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue" lang="EN-IN"&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;By this time, you have your data sources and queries ready for access by the data-bound controls of a web page.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="NonPrintable" colspan="2"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="2"&gt; &lt;p class="ArticleSubtitle"&gt;&lt;span lang="EN-IN"&gt;Designing the Webpage to view data&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;To demonstrate the usage of Linq data sources and to view data on a web page, the layout of the page has been designed in three sections.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span class="ArticleSubtitle"&gt;&lt;span style="FONT-SIZE: 9pt" lang="EN-IN"&gt;Section 1:&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt; View Student Details such as Student ID, First Name, Last Name and Average Score. This view executes the Query No. 1 studentAverageMarks defined earlier in this article.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Drag a LinqDataSource control(ID=LinqDataSource1) into the page from the data tab in the toolbox and configure it to access the data sources and queries you have just created in the project as below in the Configure Data Source Wizard.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ListParagraphCxSpFirst"&gt;&lt;span lang="EN-IN"&gt;1.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Choose "StudentData" as a Context object. (Pic1)&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;&lt;img id="Picture 3" alt="linqdatapic1.jpg" src="http://www.codedigest.com/Articles/ArticleFiles/IMG/38/image001.jpg" width="407" height="301"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;2.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Choose "studentAverageMarks" as Table in the Data Selection and Check all the fields appear in the Select list.(Pic2)&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;&lt;img id="Picture 5" alt="linqdatapic2.jpg" src="http://www.codedigest.com/Articles/ArticleFiles/IMG/38/image002.jpg" width="468" height="345"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;3.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Click the "Finish" button to complete the configuration of LinqDataSource control.&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="MARGIN-LEFT: 0in" class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;Drag a GridView control(ID=GridView1) into the page from the data tab in the tool box and set Data Source property to LinqDataSource1.&lt;/span&gt;&lt;/p&gt;  &lt;p style="MARGIN-LEFT: 0in" class="ListParagraphCxSpLast"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span class="ArticleSubtitle"&gt;&lt;span style="FONT-SIZE: 9pt" lang="EN-IN"&gt;Section 2:&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt; View Total Score for a selected student ID listed in the drop-down list. This section executes the Query No. 2 GetStudentTotal defined earlier in this article.&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraph"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Drag a LinqDataSource control(ID=LinqDataSource2) into the page from the data tab in the toolbox and configure it to access the data sources and queries you have just created in the project as below in the Configure Data Source Wizard.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ListParagraphCxSpFirst"&gt;&lt;span lang="EN-IN"&gt;1.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Choose "StudentData" as a Context object.&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;2.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Choose "GetStudentList" as Table in the Data Selection and Check the field appear in the Select list. (Pic3)&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;&lt;img id="Picture 6" alt="linqdatapic3.jpg" src="http://www.codedigest.com/Articles/ArticleFiles/IMG/38/image003.jpg" width="415" height="305"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;3.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Click the "Finish" button to complete the configuration of LinqDataSource control.&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpLast"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Drag a Drop-down list control (ID=DropDownList1) into the page and set the DataSource Property to LinqDataSource2. Remember to check the box that enables AutoPostBack behaviour to this control.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Place a TextBox and Label controls in the page and add the following code to SelectedIndexChanged Event handler of the DropDownList1.&lt;/span&gt;&lt;/p&gt; &lt;p style="TEXT-ALIGN: left" class="MsoNormal" align="left"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;protected&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;void&lt;/span&gt;&lt;span lang="EN-IN"&gt; DropDownList1_SelectedIndexChanged(&lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;object&lt;/span&gt;&lt;span lang="EN-IN"&gt; sender, &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;EventArgs&lt;/span&gt;&lt;span lang="EN-IN"&gt; e)&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;{&lt;/span&gt;&lt;/p&gt; &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt; sd = &lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;new&lt;/span&gt;&lt;span lang="EN-IN"&gt; &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt;();&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;StudentData&lt;/span&gt;&lt;span lang="EN-IN"&gt;.studentID = &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Convert&lt;/span&gt;&lt;span lang="EN-IN"&gt;.ToInt32(DropDownList1.SelectedItem.Text);&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TextBox2.Text = &lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)" lang="EN-IN"&gt;Convert&lt;/span&gt;&lt;span lang="EN-IN"&gt;.ToString(sd.GetStudentTotal.ToList&amp;lt;&lt;/span&gt;&lt;span style="COLOR: blue" lang="EN-IN"&gt;int&lt;/span&gt;&lt;span lang="EN-IN"&gt;&amp;gt;()[0]);&lt;/span&gt;&lt;/p&gt;  &lt;p class="ArticleCode"&gt;&lt;span lang="EN-IN"&gt;}&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span class="ArticleSubtitle"&gt;&lt;span style="FONT-SIZE: 9pt" lang="EN-IN"&gt;Section 3:&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt; View Student Details such as Student ID, First Name, Last Name and Total Score. This view executes the Query No. 3 studentMarks returned from the public property GetData defined earlier in this article.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Drag a LinqDataSource control(ID=LinqDataSource3) into the page from the data tab in the toolbox and configure it to access the data sources and queries you have just created in the project as below in the Configure Data Source Wizard.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="ListParagraphCxSpFirst"&gt;&lt;span lang="EN-IN"&gt;1.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Choose "StudentData" as a Context object. Refer Pic1.&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;2.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Choose "GetData" as Table in the Data Selection and Check all the fields appear in the Select list.&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;3.&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-IN"&gt;Click the "Finish" button to complete the configuration of LinqDataSource control.&lt;/span&gt;&lt;/p&gt;  &lt;p class="ListParagraphCxSpMiddle"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="MARGIN-LEFT: 0in" class="ListParagraphCxSpLast"&gt;&lt;span lang="EN-IN"&gt;Drag a ListBox control (ID=ListBox1) into the page from the data tab in the tool box and set Data Source property to LinqDataSource3.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;That's' it. Now run the webpage and see the output as displayed below. (pic4)&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;img id="Picture 0" alt="linqdatapic4.jpg" src="http://www.codedigest.com/Articles/ArticleFiles/IMG/38/image004.jpg" width="424" height="508"&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&amp;nbsp;&lt;/div&gt; &lt;div class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt; &lt;p class="ArticleSubtitle"&gt;&lt;span lang="EN-IN"&gt;Download Source&lt;/span&gt;&lt;/p&gt;&lt;a href="http://www.codedigest.com/Articles/ArticleFiles/ZIPS/38.zip"&gt;Download&lt;/a&gt;  &lt;p class="ArticleSubtitle"&gt;&lt;span lang="EN-IN"&gt;Summary&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span lang="EN-IN"&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;The Part-I of this article has demonstrated how to define and connect to in-memory data sources and explained various ways of defining and executing queries on that data collection. You are now invited to walk-through the Part-II of this article that defines entity classes to database objects and write and execute Linq queries on database table objects.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-IN"&gt;Source: &lt;a href="http://www.codedigest.com/Articles/ASPNET/38_Accessing_data_using_Language_Integrated_Query_(LINQ)_in_ASPNET_WebPages_%E2%80%93_Part_1.aspx"&gt;http://www.codedigest.com/Articles/ASPNET/38_Accessing_data_using_Language_Integrated_Query_(LINQ)_in_ASPNET_WebPages_%E2%80%93_Part_1.aspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; &lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-8286888859760739221?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/8286888859760739221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=8286888859760739221' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/8286888859760739221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/8286888859760739221'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/accessing-data-using-language.html' title='Accessing data using Language Integrated Query (LINQ) in ASP.NET WebPages – Part 1'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-6073388754512937818</id><published>2008-03-11T09:31:00.001+07:00</published><updated>2008-03-11T09:31:20.070+07:00</updated><title type='text'>File Denial</title><content type='html'>&lt;h2&gt;Let authorized users download files from your site - and keep unauthorized users out!&lt;/h2&gt; &lt;h3&gt;By &lt;a href="http://steveorr.net/about"&gt;&lt;font color="#0000ff"&gt;Steve C. Orr&lt;/font&gt;&lt;/a&gt; &lt;/h3&gt; &lt;h3&gt;Introduction&lt;/h3&gt; &lt;p class="BodyText"&gt;A common web site requirement is the ability to share certain files with specific users. For example, customers who have purchased software or other digital assets from a web site should ideally be able to return to that site and re-download the file(s) any time they want. However, that user (and other users) must be prevented from downloading packages that they have not purchased. &lt;/p&gt;  &lt;p class="BodyText"&gt;This article will not attempt to cover &lt;a href="http://www.sql-server-performance.com/jk_asp_secuirty_i.asp" target="_blank"&gt;ASP.NET user authentication&lt;/a&gt; &lt;a href="http://www.sql-server-performance.com/jk_asp_secuirty_i.asp" target="_blank"&gt;techniques&lt;/a&gt; since that topic is already thoroughly &lt;a href="http://steveorr.net/articles/SecureYourSite.aspx"&gt;covered elsewhere&lt;/a&gt;. Instead this article will focus on how (and how not) to provide access to a file once it has been determined the user is indeed authorized to download it. &lt;/p&gt;  &lt;h3&gt;How Not to Share Files &lt;/h3&gt; &lt;p class="BodyText"&gt;Many webmasters have a public folder underneath their web root somewhere that holds downloadable files. When appropriate, the user is provided with a hyperlink to a file within that folder which allows the user to download it. While this approach is common, it is also very insecure since anyone that knows that URL can download the file. The only security in place here is &amp;quot;security through obscurity&amp;quot;, since it relies completely on users not knowing information; users that have not been given the URL will not know that they can download it. However, a user could easily give the URL to other people or post it on the Internet, or a hacker could intercept it by probing network traffic, etc. Before you know it everybody has the URL and can download at will. &lt;/p&gt;  &lt;p class="BodyText"&gt;Because of this insecurity, valuable files should never be placed in a public folder, unless perhaps it is an Intranet application (not available over the Internet) and is secured by Windows Authentication with the appropriate &lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/03/SecurityBriefs/default.aspx" target="_blank"&gt;ACL&lt;/a&gt;s &lt;a href="http://msdn2.microsoft.com/en-us/library/ms229742.aspx" target="_blank"&gt;set&lt;/a&gt; on the files. &lt;/p&gt;  &lt;h3&gt;Private Parts&lt;/h3&gt; &lt;p class="BodyText"&gt;Instead, files should be stored in a secure location and managed via code to allow downloads only for select individuals. There are two main accepted techniques for storing files securely in an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; web site: &lt;/p&gt;  &lt;ol&gt; &lt;li&gt; &lt;p&gt;Store the files in a private folder that is directly inaccessible to web users.&lt;/p&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Store the files in a database (such as SQL Server).&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p class="BodyText"&gt;Both techniques have potential performance implications, depending primarily on the number and size of files. Other factors include the frequency of file updates &amp;amp; uploads, the number of concurrent users, hardware capacity, bandwidth, etc. So if top performance is a top priority then you should test both techniques to see which is better for your particular application. &lt;/p&gt;  &lt;h3&gt;Private Folders&lt;/h3&gt; &lt;p class="BodyText"&gt;When storing downloadable files on a server&amp;#39;s file system, instead of storing them in a public folder (such as &lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;,Courier,monospace"&gt;c:\inetpub\wwwroot\myapp\downloads&lt;/span&gt;) they should instead be stored in a folder outside the web application&amp;#39;s directory hierarchy (such as &lt;span style="FONT-FAMILY: &amp;#39;Courier New&amp;#39;,Courier,monospace"&gt;d:\downloads&lt;/span&gt;). &lt;/p&gt;  &lt;p class="BodyText"&gt;If it&amp;#39;s not possible to store the files outside the application&amp;#39;s folder hierarchy (as the case may be if you&amp;#39;re using a shared host) then the download folder should be secured so it cannot be directly accessed via the Internet. This can be done via IIS (by turning of all permissions off to that folder as shown in &lt;b&gt;Figure 1&lt;/b&gt;) or via Windows ACL settings (as shown in &lt;b&gt;Figure 2&lt;/b&gt;) by removing permissions. Alternately, many shared hosts have custom user interfaces that allow the configuration of such settings. &lt;/p&gt;  &lt;p class="BodyText"&gt;&lt;img style="POSITION: relative" border="0" src="http://steveorr.net/articles/images/FileDenial1.jpg"&gt;&lt;br&gt;&lt;span class="Captions"&gt;&lt;strong&gt;Figure 1:&lt;/strong&gt; &lt;em&gt;IIS can be configured to deny direct Internet access to specified folders.&lt;/em&gt;&lt;/span&gt; &lt;/p&gt;  &lt;p class="BodyText"&gt;&lt;img style="POSITION: relative" border="0" src="http://steveorr.net/articles/images/FileDenial2.jpg"&gt;&lt;br&gt;&lt;span class="Captions"&gt;&lt;strong&gt;Figure 2:&lt;/strong&gt; &lt;em&gt;The standard Windows security dialogs can be used to adjust ACLs and prevent access to unauthorized user accounts.&lt;/em&gt;&lt;/span&gt; &lt;/p&gt;  &lt;p class="BodyText"&gt;The &lt;b&gt;Response.WriteFile &lt;/b&gt;method can be used to send a file to the user dynamically from a private folder once it has been determined they are authorized to download it. Here&amp;#39;s an example: &lt;/p&gt;  &lt;div class="CodeFigure"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Response.Clear()&lt;/span&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Response.ContentType = &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;application/ms-excel&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Response.WriteFile(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;d:\downloads\Confidential.xls&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Response.AddHeader(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;Content-Disposition&amp;quot;&lt;/span&gt;, &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;inline;filename=Confidential.xls&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Response.End()&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="BodyText"&gt;Since this code is sending out a file instead of HTML, the first line clears the page&amp;#39;s Response object to get rid of any HTML that may already be buffered in the output stream. Then the content type is set on the second line to inform the browser that the output is (in this case) an Excel file. The Response.Writefile method is then invoked on the 3rd line to grab the file from the web server&amp;#39;s private folder and output its contents. On the fourth line of the above code sample, a header is added to the response object to let the browser know that it may open the Excel file embedded within the browser. (Replace &amp;quot;inline&amp;quot; with &amp;quot;attachment&amp;quot; to specify that it should be opened in an external Excel application window instead.) Finally, the Response is ended to ensure nothing else is written to the Response stream. &lt;/p&gt;  &lt;p class="BodyText"&gt;&lt;b&gt;Note:&lt;/b&gt; In some cases you may need to use impersonation or grant access to the ASPNET user account (aka NetworkService) in order for &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; to be able to access a private file share. &lt;/p&gt;  &lt;h3&gt;Database Storage&lt;/h3&gt; &lt;p class="BodyText"&gt;Applications that require large numbers of downloadable files - or allow users to upload files - may benefit from storing those files in a database instead of the web server&amp;#39;s file system. By leveraging SQL Server&amp;#39;s data management capabilities you can avoid writing reams of custom file management code that may otherwise be necessary. &lt;/p&gt;  &lt;p class="BodyText"&gt;SQL Server 2000 can store binary file data in a field of type image. SQL Server 2005 has improved binary storage capabilities in the form of the new varbinary data type. &lt;/p&gt; &lt;p class="BodyText"&gt;The following block shows &lt;a href="http://VB.NET"&gt;VB.NET&lt;/a&gt; code that retrieves binary data from a SQL Server query and sends the resulting file to the user: &lt;/p&gt; &lt;div class="CodeFigure"&gt; &lt;p class="MsoNormal"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;Dim&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; dr &lt;span style="COLOR: blue"&gt;As&lt;/span&gt; DataReader = GetFileCommand.ExecuteReader&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;If&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; dr.Read &lt;span style="COLOR: blue"&gt;Then&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;Response.Clear()&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;Response.ContentType = dr(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;ContentType&amp;quot;&lt;/span&gt;).ToString&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;Response.OutputStream.Write(&lt;span style="COLOR: blue"&gt;CType&lt;/span&gt;(dr(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;FileData&amp;quot;&lt;/span&gt;), &lt;span style="COLOR: blue"&gt;Byte&lt;/span&gt;()), 0, _&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;Convert.ToInt32(dr(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;FileSize&amp;quot;&lt;/span&gt;)))&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;Response.AddHeader(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;Content-Disposition&amp;quot;&lt;/span&gt;, &lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;attachment;filename=&amp;quot;&lt;/span&gt; + _&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;dr(&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;FileName&amp;quot;&lt;/span&gt;).ToString())&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;Response.End()&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt;End&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: &amp;#39;Courier New&amp;#39;"&gt; &lt;span style="COLOR: blue"&gt;If&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;&lt;/div&gt; &lt;p class="BodyText"&gt;Just as in the previous example, the Response object is first cleared of any buffered HTML since a file is being output instead. Next the content type that was stored along with the file is retrieved from the DataReader&amp;#39;s current row and assigned to the Response&amp;#39;s ContentType property. &lt;/p&gt;  &lt;p class="BodyText"&gt;The third line is the most important. The file data is written to the Response&amp;#39;s output stream after the binary data is converted into a byte array. The file size that was also stored along with the file data is cast into an integer and passed as a parameter to the write method. &lt;/p&gt;  &lt;p class="BodyText"&gt;Finally the file&amp;#39;s name is retrieved from the DataReader and provided to the browser via the Content-Disposition header, and the Response is ended to prevent anything else from slipping into the output. &lt;/p&gt;  &lt;h3&gt;Summary&lt;/h3&gt; &lt;p class="BodyText"&gt;You should now know how to provide &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; file download capabilities to authorized users without compromising the security of those files. By storing files in a private folder or database, they can be easily retrieved with a just few lines of code - after you&amp;#39;ve determined the user is authorized to access the file. &lt;/p&gt;  &lt;h3&gt;References&lt;/h3&gt; &lt;p class="BodyText"&gt;For further reading on this subject you may wish to review these articles: &lt;/p&gt; &lt;p class="BodyText"&gt;&lt;a href="http://steveorr.net/articles/EasyUploads.aspx"&gt;Easy Uploads&lt;/a&gt; &lt;/p&gt; &lt;div class="BodyText"&gt;&lt;a href="http://www.code-magazine.com/Article.aspx?quickid=0703031" target="_blank"&gt;Protect Your Downloadable Files Using HTTP Handlers&lt;/a&gt; &lt;/div&gt; &lt;div class="BodyText"&gt;&amp;nbsp;&lt;/div&gt; &lt;div class="BodyText"&gt;Source: &lt;a href="http://steveorr.net/articles/File-Denial.aspx"&gt;http://steveorr.net/articles/File-Denial.aspx&lt;/a&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-6073388754512937818?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/6073388754512937818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=6073388754512937818' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/6073388754512937818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/6073388754512937818'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/file-denial.html' title='File Denial'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-5250134562730105475</id><published>2008-03-10T00:57:00.001+07:00</published><updated>2008-03-10T00:57:23.167+07:00</updated><title type='text'>Adding Multiple Rows in the GridView Control</title><content type='html'>&lt;div&gt;By &lt;a href="mailto:azamsharp@gmail.com"&gt;AzamSharp &lt;/a&gt;&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;span id="ctl00_cphCell1_datalistArticles_ctl01_lblArticleDescription"&gt; &lt;p align="left"&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Introduction:&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;A while back an article was published on &lt;/font&gt;&lt;a href="http://www.gridviewguy.com/"&gt;&lt;font size="2" face="Verdana"&gt;www.gridviewguy.com&lt;/font&gt;&lt;/a&gt;&lt;font size="2" face="Verdana"&gt; which explained how to add a single row at the bottom of the GridView control. You can read the article using &lt;a href="http://www.gridviewguy.com/ArticleDetails.aspx?articleID=98_Adding_a_New_Row_in_GridView"&gt;this&lt;/a&gt; link. Many readers were interested in the idea of adding multiple rows to the GridView. This article explains how to add multiple rows to the GridView control. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Populating the GridView Control: &lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The first task is to populate the GridView control. We will be using the LINQ to SQL Classes to populate the GridView but you can use any data container that you like. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;private void BindData()&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; NorthwindDataContext northwind = new NorthwindDataContext();&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; gvReport.DataSource = GetProducts(); &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; gvReport.DataBind(); &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // since the product list is long I am only selecting three products&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private List&amp;lt;Product&amp;gt; GetProducts()&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; NorthwindDataContext northwind = new NorthwindDataContext();&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; return (from p in northwind.Products&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; select p).Take(3).ToList&amp;lt;Product&amp;gt;(); &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The database is the &lt;strong&gt;Northwind&lt;/strong&gt; database and we are using the &lt;strong&gt;Products&lt;/strong&gt; table of the database. The &lt;font face="Courier New"&gt;GetProducts&lt;/font&gt; method returns the top three products from the Products table (You can return all the rows it does not really matter). &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Here is the ASPX part of the code: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;lt;asp:GridView ID=&amp;quot;gvReport&amp;quot; runat=&amp;quot;server&amp;quot; AutoGenerateColumns=&amp;quot;false&amp;quot;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Columns&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TemplateField HeaderText=&amp;quot;ProductName&amp;quot;&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;%# Eval(&amp;quot;ProductName&amp;quot;) %&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TextBox ID=&amp;quot;txtProductName&amp;quot; runat=&amp;quot;server&amp;quot; Visible=&amp;#39;&amp;lt;%# DoesProductExists( (string) Eval(&amp;quot;ProductName&amp;quot;))&amp;nbsp; %&amp;gt;&amp;#39; /&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:TemplateField&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TemplateField HeaderText=&amp;quot;CategoryID&amp;quot;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;lt;asp:DropDownList ID=&amp;quot;ddlCategories&amp;quot; DataSource=&amp;lt;%# GetCategories() %&amp;gt; DataTextField=&amp;quot;CategoryName&amp;quot; DataValueField=&amp;quot;id&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:TemplateField&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Columns&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:GridView&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The first column displays the "&lt;strong&gt;ProductName&lt;/strong&gt;". If the ProductName is not available then a TextBox is created which is used to enter a new ProductName. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The &lt;font face="Courier New"&gt;GetCategories&lt;/font&gt; method is used to populate the DropDownList in the second column of the GridView control. Here is the implementation of the GetCategories method. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp; protected List&amp;lt;Category&amp;gt; GetCategories()&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; NorthwindDataContext northwind = new NorthwindDataContext();&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; return northwind.Categories.ToList&amp;lt;Category&amp;gt;();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;&lt;font size="2" face="Verdana"&gt;&lt;strong&gt;&lt;u&gt;Adding New Rows to the GridView Control:&lt;/u&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Now, let's see how to add new rows to the GridView control. The rows are added using the "&lt;strong&gt;Add&lt;/strong&gt;" Button control. Here is the implementation of the add button click. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;// adds the new row &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void Button1_Click(object sender, EventArgs e)&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; Count += 1; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var list = GetProducts();&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; // add empty elements at the end of the list &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; list.AddRange(new Product[Count]); &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; gvReport.DataSource = list;&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; gvReport.DataBind(); &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;Let's first talk about how we are going to add empty rows to the GridView control. Each time a button is clicked the postback is triggered. So, we need a way to know how many empty rows have to be created. We will use ViewState to store the number of rows that have to be created and then add the rows in the product list as empty products. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The &lt;strong&gt;Count&lt;/strong&gt; property in the button click code is used to store the number of empty rows to be created. Here is the implementation of the Count property. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&gt;public int Count&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&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; if (ViewState[&amp;quot;Count&amp;quot;] == 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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0; &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Courier New"&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; return (int) ViewState[&amp;quot;Count&amp;quot;];&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; set&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; &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; ViewState[&amp;quot;Count&amp;quot;] = value; &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;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The &lt;font face="Courier New"&gt;list.AddRange(new Product[Count]);&lt;/font&gt; line is used to append the rows to the product list. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;The effect is shown in the GIF Animation below: &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;&lt;img src="http://www.gridviewguy.com/ArticleImages/VideoAddingMultipleGridViewRows.gif"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;&lt;font size="2" face="Verdana"&gt;I have also used UpdatePanel to eliminate the server postback. &lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2" face="Verdana"&gt;I hope you liked the article, happy coding!&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Verdana"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font face="Verdana"&gt;Source: &lt;a href="http://www.gridviewguy.com/ArticleDetails.aspx?articleID=374_Adding_Multiple_Rows_in_the_GridView_Control"&gt;http://www.gridviewguy.com/ArticleDetails.aspx?articleID=374_Adding_Multiple_Rows_in_the_GridView_Control&lt;/a&gt;&lt;/font&gt;&lt;/p&gt; &lt;/span&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-5250134562730105475?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/5250134562730105475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=5250134562730105475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/5250134562730105475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/5250134562730105475'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/adding-multiple-rows-in-gridview.html' title='Adding Multiple Rows in the GridView Control'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-4570941388257566763</id><published>2008-03-10T00:56:00.001+07:00</published><updated>2008-03-10T00:56:21.216+07:00</updated><title type='text'>Handling the back button from server code</title><content type='html'>&lt;p&gt;By: &lt;span id="ctl00_ArticleInfo1_author"&gt;&lt;a href="http://dotnetslackers.com/community/members/Bleroy.aspx"&gt;Bertrand Le Roy&lt;/a&gt;&lt;/span&gt; &lt;span id="ctl00_ArticleInfo1_download"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span id="ctl00_ArticleInfo1_desc"&gt;One common drawback of Ajax applications is the loss of the browser&amp;#39;s back button. This article by Bertrand Le Roy shows how to restore it using &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 3.5 Extensions Preview and server code.&lt;/span&gt;&lt;/p&gt;  &lt;h3 class="KonaBody"&gt;A brief history of History &lt;/h3&gt; &lt;p class="KonaBody"&gt;&lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; has introduced a very powerful component model for the Web at a time when templating engines were limited to inserting code into markup placeholders. The new level of abstraction aims at reproducing the component and event-based model that was familiar to VB developers on the Web, along with the productivity boost it represented. At the time, Ajax was a concept that was almost limited to a few big applications such as Outlook Web Access and that didn&amp;#39;t even have a clearly defined name. Most of the interactivity was implemented on the server-side, which means that a round-trip to the server was necessary for each and every user interaction. This, in addition to the disconnected nature of HTTP and the scalability requirements of Web applications, set state management as one of the most important problems that a Web framework had to solve. It also meant that a lot of redundant data was travelling back and forth as the server had to reconstruct the application&amp;#39;s state on the one side, and the browser had to reconstruct the page UI on the other, every single time the user was doing anything. One advantage of this system is that every user interaction resulted in the browser creating a point in History and adding it to its back button&amp;#39;s stack of previous states, making it possible and relatively natural for the user to step back. If anything, there was an &lt;i&gt;excess &lt;/i&gt;of history points. &lt;/p&gt;  &lt;p class="KonaBody"&gt;It was only a matter of time before the industry moved to a more rational model where the client-server conversation becomes a lot less chatty and redundant. This is essentially what Ajax is all about, but switching to a model where the page gets its updates out of band instead of posting back and rebuilding itself from scratch means that the browser has no clue that anything significant happened and no history points get created. Essentially, we went from too many history points to none at all! &lt;/p&gt;  &lt;p class="KonaBody"&gt;In &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; Ajax, you can go all the way and implement a lot of logic on the client-side, which involves some investment in the understanding of client-side technologies, or you can continue to implement the logic in server-side code using &lt;code&gt;UpdatePanels&lt;/code&gt;, or even have a mix of &lt;code&gt;UpdatePanels&lt;/code&gt; and client-side code. In all three cases, &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; provides a simple and efficient way of restoring the back button. What&amp;#39;s interesting is that it is now up to the application developer to decide which user interactions represent a change that should be reflected by a point in browser history. In summary, we&amp;#39;re now moving from no history points to the exact right number of history points. &lt;/p&gt;  &lt;p class="KonaBody"&gt;An important side-effect of implementing browser history in an Ajax application is that each state of the application becomes bookmarkable. &lt;/p&gt; &lt;h3 class="KonaBody"&gt;How to prepare an application for history &lt;/h3&gt; &lt;p class="KonaBody"&gt;To make a page work well with the back button, you&amp;#39;ll need to determine the minimum set of variables that is necessary to represent its state. For a mapping application, this may be the current longitude and latitude and for a wizard it may be the current step index and maybe the contents of the different fields in each step. But one thing to keep in mind is that this set of variables needs to remain small because of the way history management systems have to be implemented. In effect the implementation is severely constrained by the fact that browsers don&amp;#39;t have built-in APIs to manage the history stack as we speak (the next generation of browsers will very likely change that, seeing how important this scenario has become). The only place where the framework can store state is in the so-called fragment part of the url (the part after '#&amp;#39;, which was originally designed to enable links within a single page). This is a very different process than the ViewState model where everything is automatically maintained (and as a consequence can become very large if one is not careful). &lt;/p&gt;  &lt;p class="KonaBody"&gt;It is actually a very useful and structured design phase to stop and think about what constitutes the state of the application. &lt;/p&gt; &lt;h3 class="KonaBody"&gt;A simple Ajax wizard &lt;/h3&gt; &lt;p class="KonaBody"&gt;Let&amp;#39;s start with a simple wizard inside of an &lt;code&gt;UpdatePanel&lt;/code&gt;: &lt;/p&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:ScriptManager&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;ScriptManager1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;EnableHistory&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;True&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;EnableStateHash&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;False&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;ContentTemplate&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:Wizard&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Wizard1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;WizardSteps&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:WizardStep&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;Title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Step&amp;nbsp;1&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:TextBox&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;TextBox1&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;asp:WizardStep&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:WizardStep&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;Title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Step&amp;nbsp;2&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:TextBox&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;TextBox2&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;asp:WizardStep&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:WizardStep&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;Title&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;Step&amp;nbsp;3&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;asp:TextBox&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;ID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;TextBox3&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;runat&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;asp:WizardStep&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&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;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;WizardSteps&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;asp:Wizard&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;ContentTemplate&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="KonaBody"&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t1"&gt;&amp;lt;asp:ScriptManager ID=&amp;quot;ScriptManager1&amp;quot; runat=&amp;quot;server&amp;quot;      EnableHistory=&amp;quot;True&amp;quot; EnableStateHash=&amp;quot;False&amp;quot;/&amp;gt; &amp;lt;asp:UpdatePanel ID=&amp;quot;UpdatePanel1&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;     &amp;lt;ContentTemplate&amp;gt;         &amp;lt;asp:Wizard ID=&amp;quot;Wizard1&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;             &amp;lt;WizardSteps&amp;gt;                 &amp;lt;asp:WizardStep runat=&amp;quot;server&amp;quot; Title=&amp;quot;Step 1&amp;quot;&amp;gt;                     &amp;lt;asp:TextBox ID=&amp;quot;TextBox1&amp;quot; runat=&amp;quot;server&amp;quot;/&amp;gt;                 &amp;lt;/asp:WizardStep&amp;gt;                 &amp;lt;asp:WizardStep runat=&amp;quot;server&amp;quot; Title=&amp;quot;Step 2&amp;quot;&amp;gt;                     &amp;lt;asp:TextBox ID=&amp;quot;TextBox2&amp;quot; runat=&amp;quot;server&amp;quot;/&amp;gt;                 &amp;lt;/asp:WizardStep&amp;gt;                 &amp;lt;asp:WizardStep runat=&amp;quot;server&amp;quot; Title=&amp;quot;Step 3&amp;quot;&amp;gt;                     &amp;lt;asp:TextBox ID=&amp;quot;TextBox3&amp;quot; runat=&amp;quot;server&amp;quot;/&amp;gt;                 &amp;lt;/asp:WizardStep&amp;gt;             &amp;lt;/WizardSteps&amp;gt;         &amp;lt;/asp:Wizard&amp;gt;     &amp;lt;/ContentTemplate&amp;gt; &amp;lt;/asp:UpdatePanel&amp;gt; &lt;/textarea&gt;&lt;/div&gt; &lt;p class="KonaBody"&gt;The minimum state that we want to maintain here is the wizard&amp;#39;s step index, and that&amp;#39;s what we&amp;#39;ll do here. Depending on what use we want to make of this page, we may also want to store the contents of each textbox, but these contents could potentially be quite large, so if it&amp;#39;s not strictly necessary, I&amp;#39;d keep them out. An alternative for such potentially large pieces of state is to use a more traditional state store such as ViewState or Session, but of course you won&amp;#39;t get history or bookmarkability on them. &lt;/p&gt;  &lt;h3 class="KonaBody"&gt;Handling state changes and navigation &lt;/h3&gt; &lt;p class="KonaBody"&gt;To handle history, once we&amp;#39;ve set &lt;code&gt;EnableHistory&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;, we only have two things left to do. The first one is to create history points every time state changes. In our case, this is done by handling the &lt;code&gt;ActiveStepChanged&lt;/code&gt; event of the wizard and creating a history point from there: &lt;/p&gt;  &lt;h4 class="KonaBody"&gt;Listing 1: C# code &lt;/h4&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;Wizard1_ActiveStepChanged(&lt;/span&gt;&lt;span class="keyword"&gt;object&lt;/span&gt;&lt;span&gt;&amp;nbsp;sender,&amp;nbsp;EventArgs&amp;nbsp;e)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(ScriptManager1.IsInAsyncPostBack&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;!ScriptManager1.IsNavigating)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager1.AddHistoryPoint(&lt;span class="string"&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;Wizard1.ActiveStepIndex.ToString(),&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&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;&lt;span class="string"&gt;&amp;quot;Wizard&amp;nbsp;step&amp;nbsp;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;Wizard1.ActiveStepIndex.ToString());&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="KonaBody"&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t2"&gt;protected void Wizard1_ActiveStepChanged(object sender, EventArgs e) {     if (ScriptManager1.IsInAsyncPostBack &amp;amp;&amp;amp; !ScriptManager1.IsNavigating) {         ScriptManager1.AddHistoryPoint(&amp;quot;index&amp;quot;, Wizard1.ActiveStepIndex.ToString(),             &amp;quot;Wizard step &amp;quot; + Wizard1.ActiveStepIndex.ToString());     } } &lt;/textarea&gt;&lt;/div&gt; &lt;h4 class="KonaBody"&gt;Listing 2: VB code &lt;/h4&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-vb"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;Protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Sub&lt;/span&gt;&lt;span&gt;&amp;nbsp;Wizard1_ActiveStepChanged(&lt;/span&gt;&lt;span class="keyword"&gt;ByVal&lt;/span&gt;&lt;span&gt;&amp;nbsp;sender&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;As&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Object&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;ByVal&lt;/span&gt;&lt;span&gt;&amp;nbsp;e&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;As&lt;/span&gt;&lt;span&gt;&amp;nbsp;System.EventArgs)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Handles&lt;/span&gt;&lt;span&gt;&amp;nbsp;Wizard1.ActiveStepChanged&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;If&lt;/span&gt;&lt;span&gt;&amp;nbsp;ScriptManager1.IsInAsyncPostBack&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;And&lt;/span&gt;&lt;span&gt;&amp;nbsp;_&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;Not&lt;/span&gt;&lt;span&gt;&amp;nbsp;ScriptManager1.IsNavigating&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Then&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptManager1.AddHistoryPoint(&lt;span class="string"&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span&gt;,&amp;nbsp;_&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&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;Wizard1.ActiveStepIndex,&amp;nbsp;_&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&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;&lt;span class="string"&gt;&amp;quot;Wizard&amp;nbsp;step&amp;nbsp;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;amp;&amp;nbsp;Wizard1.ActiveStepIndex)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;End&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;If&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;End&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Sub&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="KonaBody"&gt;&lt;textarea style="DISPLAY: none" class="vb" name="t3"&gt;Protected Sub Wizard1_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Wizard1.ActiveStepChanged     If ScriptManager1.IsInAsyncPostBack And _ 	Not ScriptManager1.IsNavigating Then         ScriptManager1.AddHistoryPoint(&amp;quot;index&amp;quot;, _             Wizard1.ActiveStepIndex, _             &amp;quot;Wizard step &amp;quot; &amp;amp; Wizard1.ActiveStepIndex)     End If End Sub &lt;/textarea&gt;&lt;/div&gt; &lt;p class="KonaBody"&gt;It is important to note that although we only have one piece of state in this sample (the wizard index), you can handle as many events as you want and independently create history points from there. Each part of the application can manage its own part of the state without having to know about the others. In other words, state is &lt;i&gt;added &lt;/i&gt;by &lt;code&gt;AddHistoryPoint&lt;/code&gt; more than it is &lt;i&gt;set&lt;/i&gt;, and setting a new entry doesn&amp;#39;t delete the previously added ones. &lt;/p&gt;  &lt;p class="KonaBody"&gt;The second thing we need to do is handle the &lt;code&gt;Navigate&lt;/code&gt; event on the &lt;code&gt;ScriptManager&lt;/code&gt;, which gets triggered every time the user clicked the back or forward button and restore the state from there: &lt;/p&gt;  &lt;h4 class="KonaBody"&gt;Listing 3: C# code &lt;/h4&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-c"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;ScriptManager1_Navigate(&lt;/span&gt;&lt;span class="keyword"&gt;object&lt;/span&gt;&lt;span&gt;&amp;nbsp;sender,&amp;nbsp;HistoryEventArgs&amp;nbsp;e)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;indexString&amp;nbsp;=&amp;nbsp;e.State[&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span&gt;];&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(String.IsNullOrEmpty(indexString))&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wizard1.ActiveStepIndex&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;index&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;.Parse(indexString);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wizard1.ActiveStepIndex&amp;nbsp;=&amp;nbsp;index;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Page.Title&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;&amp;quot;Wizard&amp;nbsp;step&amp;nbsp;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;indexString;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="KonaBody"&gt;&lt;textarea style="DISPLAY: none" class="c#" name="t4"&gt;protected void ScriptManager1_Navigate(object sender, HistoryEventArgs e) {     string indexString = e.State[&amp;quot;index&amp;quot;];     if (String.IsNullOrEmpty(indexString)) {         Wizard1.ActiveStepIndex = 0;     }     else {         int index = int.Parse(indexString);         Wizard1.ActiveStepIndex = index;     }     Page.Title = &amp;quot;Wizard step &amp;quot; + indexString; } &lt;/textarea&gt;&lt;/div&gt; &lt;h4 class="KonaBody"&gt;Listing 4: VB code &lt;/h4&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-vb"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span class="keyword"&gt;Protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Sub&lt;/span&gt;&lt;span&gt;&amp;nbsp;ScriptManager1_Navigate(&lt;/span&gt;&lt;span class="keyword"&gt;ByVal&lt;/span&gt;&lt;span&gt;&amp;nbsp;sender&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;As&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Object&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;ByVal&lt;/span&gt;&lt;span&gt;&amp;nbsp;e&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;As&lt;/span&gt;&lt;span&gt;&amp;nbsp;HistoryEventArgs)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Handles&lt;/span&gt;&lt;span&gt;&amp;nbsp;ScriptManager1.Navigate&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;Dim&lt;/span&gt;&lt;span&gt;&amp;nbsp;indexString&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;As&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;String&lt;/span&gt;&lt;span&gt;&amp;nbsp;=&amp;nbsp;e.State(&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;index&amp;quot;&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;If&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;String&lt;/span&gt;&lt;span&gt;.IsNullOrEmpty(indexString)&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Then&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wizard1.ActiveStepIndex&amp;nbsp;=&amp;nbsp;0&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;Else&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;Dim&lt;/span&gt;&lt;span&gt;&amp;nbsp;index&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;As&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Integer&lt;/span&gt;&lt;span&gt;&amp;nbsp;=&amp;nbsp;Convert.ToInt32(indexString)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wizard1.ActiveStepIndex&amp;nbsp;=&amp;nbsp;index&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;End&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;If&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class="alt1"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Page.Title&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;&amp;quot;Wizard&amp;nbsp;step&amp;nbsp;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;amp;&amp;nbsp;indexString&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;End&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;Sub&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="KonaBody"&gt;&lt;textarea style="DISPLAY: none" class="vb" name="t5"&gt;Protected Sub ScriptManager1_Navigate(ByVal sender As Object, ByVal e As HistoryEventArgs) Handles ScriptManager1.Navigate     Dim indexString As String = e.State(&amp;quot;index&amp;quot;)     If String.IsNullOrEmpty(indexString) Then         Wizard1.ActiveStepIndex = 0     Else         Dim index As Integer = Convert.ToInt32(indexString)         Wizard1.ActiveStepIndex = index     End If     Page.Title = &amp;quot;Wizard step &amp;quot; &amp;amp; indexString End Sub &lt;/textarea&gt;&lt;/div&gt; &lt;p class="KonaBody"&gt;You can think of these two things as analogous to &lt;code&gt;SaveViewState&lt;/code&gt; and &lt;code&gt;LoadViewState&lt;/code&gt; in the &lt;code&gt;ViewState&lt;/code&gt; model. &lt;/p&gt; &lt;p class="KonaBody"&gt;An important thing to note here is that when restoring the state, our code has to account for empty state and restore the default state of the page in that case. This is to handle the case of the user going back from a later state of the page to the initial request to the page, where no state existed yet. &lt;/p&gt;  &lt;p class="KonaBody"&gt;One could notice while running this application that the state on the URL looks very cryptic. Indeed, by default the server state is hashed using the same algorithm as &lt;code&gt;ViewState&lt;/code&gt;. This can be relaxed by setting &lt;code&gt;EnableStateHash&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; on the &lt;code&gt;ScriptManager&lt;/code&gt;. In that case, the state becomes readable (and modifiable) and looks very much like a regular query string: &lt;/p&gt;  &lt;h4 class="KonaBody"&gt;Listing 5: EnableStateHash = true &lt;/h4&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;Default.aspx#&amp;amp;&amp;amp;/&lt;/span&gt;&lt;span class="attribute"&gt;wEXAQUFaW5kZXgFATFywiqnhio4diSZ0PbZMAUM2NG7xg&lt;/span&gt;&lt;span&gt;==&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="KonaBody"&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t6"&gt;Default.aspx#&amp;amp;&amp;amp;/wEXAQUFaW5kZXgFATFywiqnhio4diSZ0PbZMAUM2NG7xg== &lt;/textarea&gt;&lt;/div&gt; &lt;h4 class="KonaBody"&gt;Listing 6: EnableStateHash = false &lt;/h4&gt; &lt;div class="dp-highlighter nogutter"&gt; &lt;div class="bar"&gt;&lt;/div&gt; &lt;ol class="dp-xml"&gt; &lt;li class="alt1"&gt;&lt;span&gt;&lt;span&gt;Default.aspx#&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="attribute"&gt;index&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;1&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="KonaBody"&gt;&lt;textarea style="DISPLAY: none" class="xml" name="t7"&gt;Default.aspx#&amp;amp;&amp;amp;index=1 &lt;/textarea&gt;&lt;/div&gt; &lt;p class="KonaBody"&gt;It&amp;#39;s also important to say a word about security here. Even if the state is hashed, the data that the application puts in there is essentially user data, and there is potential for injection attacks. It is thus very important to validate that data before using it, as with any piece of user data. &lt;/p&gt;  &lt;h3 class="KonaBody"&gt;Summary &lt;/h3&gt; &lt;p class="KonaBody"&gt;By writing two simple server-side event handlers, we&amp;#39;ve enabled meaningful state and history management on a sample application. Furthermore, we&amp;#39;ve done that without writing a single line of client-side JavaScript. This is made possible by all the work that has been put into the history feature of &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; Ajax, which abstracts away browser differences to a large extent (&lt;a href="http://weblogs.asp.net/bleroy/archive/2007/09/07/how-to-build-a-cross-browser-history-management-system.aspx" target="_blank"&gt;there are still some caveats on Safari 2 and Internet Explorer, and Opera versions before 9.5 are broken&lt;/a&gt;). This will enable productive development of user-friendly applications that behave in a natural way and don&amp;#39;t break Web users&amp;#39; expectations. &lt;/p&gt;  &lt;h3 class="KonaBody"&gt;References &lt;/h3&gt; &lt;div class="KonaBody"&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://dotnetslackers.com/articles/ajax/ClientHistoryPointsInASPNET35Extensions.aspx" target="_blank"&gt;Client History Points in ASP.NET 3.5 Extensions by Dino Esposito&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2008/01/04/screencast-how-to-enable-server-side-history-management-in-an-asp-net-ajax-application.aspx" target="_blank"&gt;Screencast: how to enable server-side history management in an ASP.NET Ajax application&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2007/09/07/how-to-build-a-cross-browser-history-management-system.aspx" target="_blank"&gt;How to build a cross-browser history management system&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p&gt;Source: &lt;a href="http://dotnetslackers.com/articles/ajax/HandlingTheBackButtonFromServerCode.aspx"&gt;http://dotnetslackers.com/articles/ajax/HandlingTheBackButtonFromServerCode.aspx&lt;/a&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-4570941388257566763?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/4570941388257566763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=4570941388257566763' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4570941388257566763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4570941388257566763'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/handling-back-button-from-server-code.html' title='Handling the back button from server code'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-4700986375284998439</id><published>2008-03-07T09:16:00.001+07:00</published><updated>2008-03-07T09:16:47.955+07:00</updated><title type='text'>Creating Derived Controls</title><content type='html'>&lt;h2&gt;Introduction&lt;/h2&gt; &lt;p&gt;In the &lt;a href="http://www.bipinjoshi.net/articles/31cf8d3d-7f71-46f4-b847-3eea47a7f2f5.aspx"&gt;previous lesson&lt;/a&gt; you developed a composite control by assembling existing server controls. There is one more technique to add to the functionality of the existing controls. You can extend existing controls and add/customize functionality as per your requirement. This way you avail the core functionality of the base control to create a tailor-made control meeting your requirement. The designer features of Visual Studio such as &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink1" class="kLink" href="http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;smart &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;tags&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; and dialogs that are available for the base control continue to remain available for the derived control also.&lt;/p&gt;  &lt;h2&gt;Example&lt;/h2&gt; &lt;p&gt;As an example I am going to take up a common scenario. You might be aware that features of the &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink2" class="kLink" href="http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;GridView&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; control such as paging and sorting work in code less fashion if you use data source controls (ODS or SDS). However, when you bind raw data in the form of say a DataSet to the GridView it forces you to write event handlers for Sorting and PageIndexChanging events. In most of the cases code within these event handlers look very similar. To reduce this repetition you can create your own &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink3" class="kLink" href="http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; BORDER-BOTTOM: blue 1px solid; FONT-FAMILY: Verdana; BACKGROUND-COLOR: transparent" class="kLink"&gt;grid &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; BORDER-BOTTOM: blue 1px solid; FONT-FAMILY: Verdana; BACKGROUND-COLOR: transparent" class="kLink"&gt;control&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; that inherits from GridView base class. You can then add the logic for sorting and paging inside this custom control.&lt;/p&gt;  &lt;p&gt;To clearly understand how this can be done, &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink4" class="kLink" href="http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;create &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;a &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;new &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;web &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;site&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; in Visual Studio. Add a class to it named MyGridView. The class definition should look as shown below:&lt;/p&gt; &lt;pre&gt;namespace BinaryIntellect {   public class MyGridView:GridView   {   } }&lt;/pre&gt; &lt;p&gt;Here, we created MyGridView class that inherits from GridView as its base class. This way all the functionality of GridView becomes available to our custom control class. &lt;/p&gt; &lt;p&gt;Then we need to create two helper methods viz. GetSortDirection() and BindGrid(). The GetSortDirection() method stores sort direction (ASC/DESC) in a ViewState variable. This is necessary because when you are not using any data source control for the purpose of data binding then GridView will not maintain the sorting direction by itself. The BindGrid() method bind the GridView with the required data. Internally it uses GetSortDirection() to sort the data on required column. These two functions are shown below:&lt;/p&gt; &lt;pre&gt;private SortDirection GetSortDirection() { SortDirection dir; if (ViewState[&amp;quot;_sortdirection&amp;quot;]==null) { ViewState[&amp;quot;_sortdirection&amp;quot;] = &amp;quot;ASC&amp;quot;; dir = SortDirection.Ascending; } else { dir = (ViewState[&amp;quot;_sortdirection&amp;quot;].ToString()  == &amp;quot;ASC&amp;quot; ? SortDirection.Ascending :  SortDirection.Descending); } ViewState[&amp;quot;_sortdirection&amp;quot;] = (ViewState[&amp;quot;_sortdirection&amp;quot;]. ToString() == &amp;quot;ASC&amp;quot; ? &amp;quot;DESC&amp;quot; : &amp;quot;ASC&amp;quot;); return dir; }  private void BindGrid(string sortExpression) { SqlDataAdapter da = new SqlDataAdapter(&amp;quot;select * from  employees&amp;quot;, @&amp;quot;data source=.\sqlexpress;initial  catalog=northwind;integrated security=true&amp;quot;); DataSet ds = new DataSet(); da.Fill(ds); DataView dv=ds.Tables[0].DefaultView; if (sortExpression != string.Empty) { ViewState[&amp;quot;_sortexpression&amp;quot;] = sortExpression; dv.Sort = sortExpression + &amp;quot; &amp;quot; + (GetSortDirection()  == SortDirection.Ascending ? &amp;quot;ASC&amp;quot; : &amp;quot;DESC&amp;quot;); } else { if (ViewState[&amp;quot;_sortexpression&amp;quot;] != null) { sortExpression = ViewState[&amp;quot;_sortexpression&amp;quot;].ToString(); dv.Sort = sortExpression + &amp;quot; &amp;quot; + (GetSortDirection()  == SortDirection.Ascending ? &amp;quot;ASC&amp;quot; : &amp;quot;DESC&amp;quot;); } } this.DataSource = dv; this.DataBind(); }&lt;/pre&gt; &lt;p&gt;The GetSortDirection() method returns the sort direction as SortDirection enumeration. The SortDirection enumeration is the same enumeration that GridView uses to represents its sorting direction. We persist the sort direction in a ViewState variable named _sortdirection. The possible values for this variable are ASC and DESC. Every time you cann GetSortDirection() method it returns existing direction to the caller and toggles the direction so that next time correct direction can be retirned. This is because if the grid is sorted in ascending order the first time then the next time we should sort it in descending order.&lt;/p&gt;  &lt;p&gt;The BindGrid() method accepts the sort expression (Column name) on which you want to sort the data. It then proceeds to create a DataView containing the required data. In above code we are fetching all the records from Employees table of Northwind &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink5" class="kLink" href="http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;database&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;. The DataView is then sorted using its Sort property and the return value of GetSortDirection() method. We also persist the sort expression in a ViewState variable so that sorting and paging can co-exist properly. The base GridView is then bound with the DataView.&lt;/p&gt;  &lt;p&gt;Next, we override some events of the base class viz. Load, Sorting, Sorted, PageIndexChanging and PageIndexChanged. Their event handlers are shown below:&lt;/p&gt;&lt;pre&gt;protected override void OnLoad(EventArgs e) { if (!this.Page.IsPostBack) { BindGrid(string.Empty); } }  protected override void OnSorting (GridViewSortEventArgs e) { BindGrid(e.SortExpression); } protected override void OnSorted(EventArgs e) { //nothing here } protected override void OnPageIndexChanging (GridViewPageEventArgs e) { this.PageIndex = e.NewPageIndex; BindGrid(string.Empty); } protected override void OnPageIndexChanged (EventArgs e) { //nothing here }&lt;/pre&gt; &lt;p&gt;The OnLoad() method simply binds the grid during first load (IsPostBack is false). The OnSorting() method calls the BindGrid() method by passing the appropriate sort expression. The OnPageIndexChanging method sets the current page index of the grid using the NewPageIndex property and rebinds the grid. In our example we have not provided any specific code inside OnSorted() and OnPageIndexChanged() methods but you can add it if you so wish.&lt;/p&gt;  &lt;p&gt;To use our MyGridView control on a web form, register it with the page using @Register directive.&lt;/p&gt;&lt;pre&gt;&amp;lt;%@ Register Namespace=&amp;quot;BinaryIntellect&amp;quot; TagPrefix=&amp;quot;cc1&amp;quot;  %&amp;gt;&lt;/pre&gt; &lt;p&gt;Also, create one instance of MyGridView in the form.&lt;/p&gt;&lt;pre&gt;&amp;lt;cc1:MyGridView ID=&amp;quot;GridView1&amp;quot; runat=&amp;quot;server&amp;quot; AllowPaging=&amp;quot;True&amp;quot;&amp;gt; &amp;lt;/cc1:MyGridView&amp;gt;&lt;/pre&gt; &lt;p&gt;Using &lt;a style="POSITION: static; TEXT-DECORATION: underline! important" id="KonaLink6" class="kLink" href="http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" color="blue"&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;Visual &lt;/span&gt;&lt;span style="FONT-WEIGHT: 400; FONT-SIZE: 13px; POSITION: static; COLOR: blue! important; FONT-FAMILY: Verdana" class="kLink"&gt;Studio&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; designer add two BoundFields to the MyGridView control. Bind the first BoundField with FirstName column and the second with LastName column. Make sure to set their SortExpression property to FirstName and LastName respectively. Set AllowPaging and AllowSorting properties of MyGridView to true.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.bipinjoshi.net/articles/content/Images/BK_Derived_Control_01.jpg"&gt; &lt;/p&gt; &lt;p&gt;If you run the web form now you should something as shown below:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.bipinjoshi.net/articles/content/Images/BK_Derived_Control_02.jpg"&gt;&lt;/p&gt; &lt;div&gt;Try playing with sorting and paging functionality.&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;a href="http://www.bipinjoshi.net/articles/displayarticlelink.aspx?linkid=9aa1e9c2-441e-4f3a-8288-6b8a59624db0"&gt;Download Source Code&lt;/a&gt;&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;Source: &lt;a href="http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx"&gt;http://www.bipinjoshi.net/articles/5d98c230-1143-4ff2-a473-96a2ca00a58d.aspx&lt;/a&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-4700986375284998439?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/4700986375284998439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=4700986375284998439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4700986375284998439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/4700986375284998439'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/creating-derived-controls.html' title='Creating Derived Controls'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-8402706025712537013</id><published>2008-03-06T09:39:00.001+07:00</published><updated>2008-03-06T09:39:46.187+07:00</updated><title type='text'>Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 1</title><content type='html'>&lt;div&gt;&lt;span id="abstractLabel"&gt;Microsoft released the first CTP of &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 3.5 Extensions and it includes &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework as one of the main extensions for &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 3.5. In the first part of this article series about building a simple blog engine with &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC and LINQ, Keyvan introduces the MVC pattern, &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework, and the fundamentals of a simple blogging engine.&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;span&gt;&lt;/span&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;span&gt;by &lt;span class="author" id="author"&gt;&lt;a href="http://aspalliance.com/author.aspx?uId=58927"&gt;Keyvan Nayyeri&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span class="author"&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;span&gt;&lt;span class="author"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page1"&gt;Introduction&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;A few weeks ago Microsoft released the first CTP of &lt;a href="http://asp.net/downloads/3.5-extensions/"&gt;ASP.NET 3.5 Extensions&lt;/a&gt; which includes the first public version of &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework. There have been many good resources about this MVC Framework on the web as tutorials, blog posts and web casts.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I want to write a set of articles about &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework to build a simple blogging engine based on MVC and LINQ in .NET 3.5 and show you all the steps in detail then extend the discussion to some more-in-depth topics. I have not written this application completely and will write it in parallel with these articles.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Such a sample application is provided by &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC toolkit, but there is not a description about it yet. But why I am doing this while there are some other tutorials with the same approach? In my opinion, the learning curve of this MVC Framework consists of a workflow progress of some steps that should be followed and the major thing is this, building this simple blogging engine and describing its process would be a very good example for &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;So here is the first part of this series (I want to finish them in a few weeks) and it is an introduction with some basic information.&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page2"&gt;What is MVC?&lt;/a&gt;&lt;/span&gt;&lt;br&gt;  &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Yes, what is that?! Others have described this better than me but I repeat it in my words.&lt;/p&gt; &lt;p class="MsoNormal"&gt;Model View Controller (MVC) is a methodology to build an application based on the idea of dividing the implementation into three roles: Model, View and Controller.&lt;/p&gt; &lt;p class="MsoNormal"&gt;Let us take a second look at the above sentence. From the above sentence we believe that MVC is a methodology not a technology, so it has been used before Microsoft adapts it to &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt;. I persisted on this because saw some guys who thought it was a technology that is designed for &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; specifically.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I also need to introduce the three roles in a nutshell:&lt;/p&gt; &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Model: This is the role to maintain the state. Usually these are classes that represent data in a database.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;View: The second role displays the data in the user interface to end users. This may be a set of user interface elements like TextBoxes, editors and buttons.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Controller: The last role is responsible to interact with user inputs and handling it. In fact, controller is where you implement the actual logic to handle what the user has asked for.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The MVC has become a very good methodology to design applications that rely on data interactions. The most important benefit of MVC is the ability to unit test the application easily because you can unit test an MVC application via its controllers and apply a TDD workflow (Red-Green-Refactor) easily.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Figure 1 shows the structure of MVC pattern where the model is independent from the controller and view so this enables the testability of the model independently from what controller and view are. On the other hand, there is a separation between model, view and controller that lets developers test their MVC applications easily. In fact, separation of view as the user interface element and controller and model is important because it simplifies the testing process.&lt;/p&gt;  &lt;p class="CodeListingHeading"&gt;Figure 1: MVC structure&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;img height="159" src="http://aspalliance.com/ArticleFiles/1538/image001.jpg" width="318" border="0"&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;I do not discuss more about the MVC and just refer you to &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;Scott Guthrie&amp;#39;s post&lt;/a&gt; about it and its description on &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;Wikipedia&lt;/a&gt; that would be sufficient to get you started.&lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page3"&gt;What is ASP.NET MVC Framework?&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;The &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework is the Microsoft&amp;#39;s adoption of MVC for its &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; technology for version 3.5 where it provides features required to build a web application based on MVC.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Framework is currently under construction and only one public release is available for download as a part of &lt;a href="http://asp.net/downloads/3.5-extensions/"&gt;ASP.NET 3.5 Extensions CTP&lt;/a&gt;.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Once you download and install this package, you can get the benefit of different pieces of &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 3.5 Extensions and it automatically installs some project templates for you on Visual Studio 2008.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Along this download package, there is an &lt;a href="http://asp.net/downloads/3.5-extensions/MVCToolkit.zip"&gt;MVC toolkit package&lt;/a&gt; available for download that provides some helpful tools for your MVC development. I may use them in my posts as well. &lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page4"&gt;Basics of KBlog&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;For this article series, I am going to build a simple sample blogging tool that I call KBlog. This blogging engine will be built on top of some considerations that will be described here.&lt;/p&gt; &lt;p class="MsoNormal"&gt;This blogging engine supports blog posts, comments and categories. A blog post can have only one category and as many comments as possible. This blog engine is for single users only and has some URL patterns for public and private pages. Everything will be referred by its ID and KBlog does not support post names as a part of URL just to make the application simpler.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I will use SQL Express for my database and for the first steps. I fill this database manually and after finishing my discussion with public pages, I will jump into details of administration pages where the user can enter data.&lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page5"&gt;Create the Project&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Obviously, the first step is to create a project in Visual Studio. Under Web category, you can choose &amp;quot;&lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Web Application&amp;quot; project item which should be available after installing &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; 3.5 Extensions CTP. I name my project KBlog (Figure 2).&lt;/p&gt;  &lt;p class="CodeListingHeading"&gt;Figure 2: Create a new &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC Web Application project&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;img height="470" src="http://aspalliance.com/ArticleFiles/1538/image002.jpg" width="652" border="0"&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;After this, Visual Studio generates a project for you with the pre-defined template and structure.&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page6"&gt;Getting Started&lt;/a&gt;&lt;/span&gt;&lt;br&gt;  &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;At first glance, Visual Studio generates an &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; web application project for you with a simple structure.&lt;/p&gt; &lt;p class="CodeListingHeading"&gt;Figure 3: &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC solution structure&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;img height="488" src="http://aspalliance.com/ArticleFiles/1538/image003.jpg" width="295" border="0"&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;Taking a look at this project, you believe that there are some references for the project and one important reference is to System.Web.Extensions assembly. There are also four folders available including Content, Controllers, Models and Views.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Content folder is just for a default CSS stylesheet file for default look and feel of the site.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Controllers folder is responsible to hold controller classes.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Models folder is responsible to hold model classes.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Views folder is responsible for holding view files and contains some folders that include ASPX and master files.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;As you see, Controllers, Models and Views are more important for us here. While they are generated to hold controllers, models and views, this is not a rule and you can replace them with your own structure.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Beside these folders, there are some well-known &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; files that of course have some extra definitions that I will describe later.&lt;/p&gt; &lt;p class="MsoNormal"&gt;There is a point to mention here about Default.aspx file and as mentioned in the content of this file, you should not remove the file to let IIS activate MVC for the application when the user navigates to this page.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;That is enough for now. Step-by-step, I am going to add my implementation to this project in the upcoming posts.&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page7"&gt;Further Reading&lt;/a&gt;&lt;/span&gt;&lt;br&gt;  &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;Here is a list of some good blogs that you can use for further reading about &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC framework and they already contain excellent information about &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC. This technology is completely new in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; so there is a hope to see many more resources in the future, but fortunately MVC has become popular among developers and we saw great reactions against it in these a few weeks.&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt;&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt;&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;a href="http://haacked.com/"&gt;Phil Haack&lt;/a&gt;&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;a href="http://blog.wekeroad.com/"&gt;Rob Conery&lt;/a&gt;&lt;/p&gt;  &lt;p class="MsoListBullet"&gt;&lt;span style="FONT-FAMILY: Symbol"&gt;·&lt;span style="FONT: 7pt &amp;#39;Times New Roman&amp;#39;; font-size-adjust: none; font-stretch: normal; -x-system-font: none"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;a href="http://blogs.msdn.com/brada/"&gt;Brad Abrams&lt;/a&gt;&lt;/p&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="subtitle" colspan="2"&gt;&lt;span id="intellitTxt"&gt;&lt;a class="pageTitle" id="#Page8"&gt;Summary&lt;/a&gt;&lt;/span&gt;&lt;br&gt; &lt;div class="KonaBody"&gt; &lt;p class="MsoNormal"&gt;In the first part of my article series about new &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC framework, I introduced you to the MVC pattern, fundamentals of Model View Controller and &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC framework as well as basic information about the simple blogging engines that I am going to write in this series. I also covered the structure of MVC solutions in &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;In the future parts, I will build this blogging engine step-by-step and will show you some principles and techniques about the &lt;a href="http://ASP.NET"&gt;ASP.NET&lt;/a&gt; MVC framework.&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/263307687327671735-8402706025712537013?l=asp-net-news.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://asp-net-news.blogspot.com/feeds/8402706025712537013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=263307687327671735&amp;postID=8402706025712537013' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/8402706025712537013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/263307687327671735/posts/default/8402706025712537013'/><link rel='alternate' type='text/html' href='http://asp-net-news.blogspot.com/2008/03/building-simple-blog-engine-with-aspnet.html' title='Building a Simple Blog Engine with ASP.NET MVC and LINQ - Part 1'/><author><name>Newbie</name><uri>http://www.blogger.com/profile/15218799722148729737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-263307687327671735.post-6266545895338403800</id><published>2008-03-05T09:33:00.000+07:00</published><updated>2008-03-05T09:40:10.038+07:00</updated><title type='text'>Introduction To LINQ</title><content type='html'>&lt;span&gt;Posted by &lt;a class="Article_AuthorLink" href="http://odetocode.com/articles/Users_ShowProfile.aspx?user=scott"&gt;scott&lt;/a&gt; on &lt;span class="dateCreated"&gt;Sunday, December 23, 2007&lt;/span&gt; &lt;br&gt;&lt;br&gt;&lt;span class="Article_BriefDescription"&gt;This article is an introduction to LINQ and provides examples of using LINQ to query objects, XML, and relational data. &lt;/span&gt;&lt;table&gt; &lt;tr&gt;&lt;td class="Article_BodyCell"&gt;&lt;span class="Article_FullDescription"&gt; &lt;p&gt;Language Integrated Query (LINQ) gives .NET developers the ability to query and transform data using their .NET language of choice. The data can live inside XML documents, inside &lt;a class="kLink" id="KonaLink0" style="POSITION: static; TEXT-DECORATION: underline! important" href="http://odetocode.com/articles/737.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static" color="blue"&gt;&lt;span class="kLink" style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static"&gt;relational &lt;/span&gt;&lt;span class="kLink" style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static"&gt;database&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; tables, or inside collections of objects. What truly distinguishes LINQ from other data access APIs in .NET however, is LINQ&amp;#39;s deep integration into the .NET languages like C# and VB. In this article, we will explore the basic features of LINQ and demonstrate this beautiful integration. &lt;/p&gt;  &lt;h1&gt;Manipulating Data &lt;/h1&gt; &lt;p&gt;Traditionally, your &lt;a class="kLink" id="KonaLink1" style="POSITION: static; TEXT-DECORATION: underline! important" href="http://odetocode.com/articles/737.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static" color="blue"&gt;&lt;span class="kLink" style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static"&gt;data &lt;/span&gt;&lt;span class="kLink" style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static"&gt;source&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; determines your selection of a low-level data access API. To fetch relational data from a table, you can use components based on &lt;a href="http://ADO.NET"&gt;ADO.NET&lt;/a&gt;. To parse XML data, you might use some combination of XPath and XML DOM APIs. Each data access API requires its own specialized syntax (SQL queries, as an example), and typically forces a &lt;a class="kLink" id="KonaLink2" style="POSITION: static; TEXT-DECORATION: underline! important" href="http://odetocode.com/articles/737.aspx#" target="_top"&gt;&lt;font style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static" color="blue"&gt;&lt;span class="kLink" style="FONT-WEIGHT: 400; FONT-SIZE: 16px; COLOR: blue! important; BORDER-BOTTOM: blue 1px solid; FONT-FAMILY: Times New Roman,Arial,helvetica,sans-serif; POSITION: static; BACKGROUND-COLOR: transparent"&gt;developer&lt;/span&gt;&lt;/font&gt;&lt;/a&gt; to shuffle data between their business objects and the data access API. Sophisticated frameworks like object-relational mappers (OR/M) can take much of the grunge work out of data shuffling, but these frameworks still impose their own APIs on a developer. &lt;/p&gt;  &lt;p&gt;All of the diverse data access strategies and APIs means there is a tremendous amount of mental energy expended to build the basic data features needed in every business application. LINQ is poised to eliminate this mental overhead. &lt;/p&gt;  &lt;h2&gt;Designing LINQ &lt;/h2&gt; &lt;p&gt;Microsoft designed LINQ to provide general-purpose query facilities to the .NET platform. More specifically, LINQ defines a set of &lt;strong&gt;standard query operators&lt;/strong&gt; in the System.Linq namespace to select, filter, aggregate, and partition data from any type that implements the IEnumerable or &lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/a&gt; interfaces. The standard query operators are compliant with the Common Language Specification (CLS) and work inside any .NET language that supports generics. &lt;/p&gt;  &lt;p&gt;In the following C# code, we&amp;#39;re using LINQ to query a collection of strings. &lt;/p&gt; &lt;div style="BORDER-RIGHT: black 1pt solid; BORDER-TOP: black 1pt solid; FONT-SIZE: 8pt; BORDER-LEFT: black 1pt solid; BORDER-BOTTOM: black 1pt solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: rgb(211,211,189)"&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="COLOR: black"&gt;[] instructors = { &lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;Aaron&amp;quot;&lt;/span&gt;&lt;span style="COLOR: black"&gt;, &lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;Fritz&amp;quot;&lt;/span&gt;&lt;span style="COLOR: black"&gt;, &lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;Keith&amp;quot;&lt;/span&gt;&lt;span style="COLOR: black"&gt;, &lt;/span&gt;&lt;span style="COLOR: rgb(163,21,21)"&gt;&amp;quot;Scott&amp;quot;&lt;/span&gt;&lt;span style="COLOR: black"&gt; };&lt;br&gt; &lt;br&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/span&gt;&lt;span style="COLOR: black"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="COLOR: black"&gt;&amp;gt; query =&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;from&lt;/span&gt;&lt;span style="COLOR: black"&gt; n &lt;/span&gt;&lt;span style="COLOR: blue"&gt;in&lt;/span&gt;&lt;span style="COLOR: black"&gt; instructors&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;where&lt;/span&gt;&lt;span style="COLOR: black"&gt; n.Length == 5&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;orderby&lt;/span&gt;&lt;span style="COLOR: black"&
