﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-玄铁剑-文章分类-AJAX</title><link>http://www.cnitblog.com/MartinYao/category/4797.html</link><description>欢迎您的到来...</description><language>zh-cn</language><lastBuildDate>Thu, 03 Jan 2008 14:36:14 GMT</lastBuildDate><pubDate>Thu, 03 Jan 2008 14:36:14 GMT</pubDate><ttl>60</ttl><item><title>Building a ToJSON() Extension Method using .NET 3.5</title><link>http://www.cnitblog.com/MartinYao/articles/38305.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Sun, 30 Dec 2007 09:45:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/38305.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/38305.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/38305.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/38305.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/38305.html</trackback:ping><description><![CDATA[<p>Extension methods allow developers to add new methods to the public contract of an existing CLR&nbsp;type, without having to sub-class it or recompile the original type.&nbsp;&nbsp;In doing so they enable a variety of useful scenarios (including LINQ).&nbsp; They also provide a really convenient way to add a dash of "syntactic sugar" into your code.
<p>Over the last few months I've been making a list of cool extension methods that I plan to sit down and implement when I get some free time (not sure when that is... but at least I can still have fun coming up with the ideas!)&nbsp; Two of the&nbsp;scenarios I added to my extension method list were easy methods to automate generating&nbsp;<a href="http://www.json.org/" target=_blank><u><font color=#0000ff>JSON (JavaScript Object Notation)</font></u></a> or XML serialization strings for any .NET object.&nbsp; </p>
<h3><u>Simple Scenario: The ToJSON() extension method</u></h3>
<p>Assume I had a Person object defined like below (note: I'm using the new&nbsp;<a href="http://weblogs.asp.net/scottgu/archive/2007/03/08/new-c-orcas-language-features-automatic-properties-object-initializers-and-collection-initializers.aspx" target=_blank><u><font color=#0000ff>automatic properties</font></u></a> feature to implement it):</p>
<p><img src="http://www.scottgu.com/blogposts/tojson/step1.jpg"> </p>
<p>I'd like to then be able to initialize a collection of Person objects and programmatically retrieve a JSON string representation of them by just calling a ToJSON() extension method on it like below:</p>
<p><img src="http://www.scottgu.com/blogposts/tojson/step2.jpg"> </p>
<p>This would work just&nbsp;like the built-in ToString() method on the Object class in .NET today - except that it would generate a JSON-format representation of the collection that I could use for AJAX scenarios on the client:</p>
<p><img src="http://www.scottgu.com/blogposts/tojson/step3.jpg"> </p>
<p>Note: Clicking on the hour-glass in the debugger above allows us to bring up the Text Visualizer in VS to see a clean version of the JSON serialization:</p>
<p><img src="http://www.scottgu.com/blogposts/tojson/step4.jpg"> </p>
<p>This string format could then be used within JavaScript on the client to instantiate an appropriate JavaScript object that represents my collection (note: ASP.NET AJAX has a built-in JavaScript library to support this).</p>
<h3><u>Implementing the ToJSON Extension Method</u></h3>
<p>Implementing a basic ToJSON() extension method is pretty simple.&nbsp; All I needed to-do was use the JavaScriptSerializer class in the System.Web.Script.Serialization namespace, and define two extension methods like below. One of the methods serializes an object graph any levels deep, the other is an overloaded version that allows you to optionally constrain how deep it recurses (for example: ToJSON(2) would serialize only 2 levels deep in the object graph).</p>
<p><img src="http://www.scottgu.com/blogposts/tojson/step5.jpg"> </p>
<p>Note that the ToJSON() extension methods above&nbsp;are defined for type "Object" - which means they can be used with all objects in .NET (not just collections).&nbsp; This means that in addition to calling .ToJSON() on collections like I did above, I could also have called ToJSON() on individual Person objects, as well as any other .NET datatype.</p>
<p>To use the extension method, all I need to-do is add a using statement at the top of my program&nbsp;that references the namespace it was defined within:</p>
<p><img src="http://www.scottgu.com/blogposts/tojson/step6.jpg"> </p>
<p>VS 2008 then takes care of providing intellisense and compile time support for it to all objects:</p>
<p><img src="http://www.scottgu.com/blogposts/tojson/step7.jpg"> </p>
<p><em>Note: In addition to the JavaScriptSerializer class, .NET 3.5 also now includes a </em><a href="http://blogs.msdn.com/kaevans/archive/2007/09/04/use-linq-and-net-3-5-to-convert-rss-to-json.aspx" target=_blank><em><u><font color=#0000ff>new System.Runtime.Serialization.DataContractJsonSerializer class</font></u></em></a><em> that you can use for JSON serialization/deserialization.</em></p>
<h3><u>Summary</u></h3>
<p>Hopefully the above sample provides a simple example of how you can easily encapsulate useful functionality into extension methods.&nbsp; Overtime I expect that we'll start to see some nice utility libraries come out that provide helpful extension methods like above.&nbsp; </p>
<p>I'd be curious to see suggestions for other common scenarios you think should be packaged up into re-usable extension methods (feel free to use the comments of this post to suggest them).&nbsp; We can then figure out how to get a&nbsp;good CodePlex project created that bundles up some of them together into one library to easily use.</p>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/38305.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2007-12-30 17:45 <a href="http://www.cnitblog.com/MartinYao/articles/38305.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AJAX in Action</title><link>http://www.cnitblog.com/MartinYao/articles/22640.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Sat, 03 Feb 2007 15:26:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/22640.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/22640.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/22640.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/22640.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/22640.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr valign="top">
								<td width="100%">
										<table width="100%">
												<tbody>
														<tr valign="top">
																<td class="SmallText" nowrap="">
																</td>
																<td nowrap="" align="right">
																		<a name="__top">
																		</a>
																		<table>
																				<tbody>
																						<tr>
																								<td class="smallText" align="right">7 votes for this article.</td>
																								<td>
																										<table cellspacing="0" cellpadding="0" border="2">
																												<tbody>
																														<tr>
																																<td>
																																		<img height="5" src="http://www.codeproject.com/script/images/red.gif" width="20" border="0" />
																																</td>
																																<td>
																																		<img height="5" src="http://www.codeproject.com/script/images/red.gif" width="20" border="0" />
																																</td>
																																<td>
																																		<img height="5" src="http://www.codeproject.com/script/images/red.gif" width="20" border="0" />
																																</td>
																																<td>
																																		<img height="5" src="http://www.codeproject.com/script/images/red.gif" width="6" border="0" />
																																		<img height="5" src="http://www.codeproject.com/script/images/white.gif" width="14" border="0" />
																																</td>
																																<td>
																																		<img height="5" src="http://www.codeproject.com/script/images/white.gif" width="20" border="0" />
																																</td>
																														</tr>
																												</tbody>
																										</table>
																								</td>
																						</tr>
																						<tr>
																								<td class="smallText" align="right" colspan="2">
																										<a title="Calculated as rating x Log10(# votes)" href="http://www.codeproject.com/script/articles/top_articles.asp?st=2">Popularity: 2.78</a>. Rating: <b>3.29</b> out of 5.</td>
																						</tr>
																				</tbody>
																		</table>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
						<tr>
								<td class="ArticlePane">
										<span id="intelliTXT">
												<div id="contentdiv">
														<!-- Article Starts -->
														<ul class="download">
																<li>
																		<a href="http://www.codeproject.com/Ajax/AJAX/AjaxInAction.zip">Download source - 10.2 Kb</a>
																</li>
														</ul>
														<h2>Introduction</h2>
														<p nd="1">I love AJAX, it really cleans my dishes. Unfortunately, in this article we will not be talking about washing detergent. If you like you can visit <a href="http://www.rateitall.com/i-26387-ajax-detergent-dish-liquid-antibacterial.aspx" target="_blank">Clean My Dishes</a> for more details. In this article we will be talking about AJAX (Asynchronous JavaScript and XML). All you need to know right now is that AJAX allows you to make server side calls without doing a postback.</p>
														<h2>Downloading the AJAX.NET Library</h2>
														<ul>
																<li nd="2">
																		<a href="http://ajax.schwarz-interactive.de/csharpsample/default.aspx" target="_blank">Download link</a>. </li>
														</ul>
														<p nd="3">First of all, you need to download the AJAX.NET library created by Michael Schwarz. Now that you have downloaded the library and made the reference to the DLL in your project, we can start some dirty stuff.</p>
														<h2>What are we going to do?</h2>
														<p nd="4">Okay, here is what we are going to do. We are going to make a dropdown list using <code lang="html" nd="5">&lt;select&gt;</code> HTML tags. We will populate the dropdown list from the database. Now when we select any item from the dropdown list, it will fetch the result from the database and display it on the screen in a <code nd="6">DataGrid</code>. All of this will happen with <b>no pstback</b>.</p>
														<p nd="7">I highly recommend that you first read the basic instructions of using the AJAX.NET Library which are given at the above URL, so that you will have the basic idea.</p>
														<h2>AJAX in Action</h2>
														<p nd="8">Our first task is that when the page is loaded the dropdown list is populated with data from the database. But before that let's initialize our AJAX library by making a call in the <code nd="9">page_load</code> event.</p>
														<pre lang="cs" nd="12">
																<span class="cs-keyword" nd="10">private</span>
																<span class="cs-keyword" nd="11">void</span> Page_Load(<span class="cs-keyword" nd="13">object</span> sender, System.EventArgs e)
{
  Ajax.Utility.RegisterTypeForAjax(<span class="cs-keyword" nd="14">typeof</span>(UsingAjax));
}</pre>
														<p nd="15">In this article we will be using the Northwind database. First of all you need to make a server method so that you can get a <code nd="16">DataSet</code> and bind it to the dropdown list. Let's make that method:</p>
														<pre lang="cs" nd="17">[Ajax.AjaxMethod]
<span class="cs-keyword" nd="18">public</span> DataSet GetDropDownListData()
{
  <span class="cs-keyword" nd="19">string</span> query = <span class="cpp-string" nd="20">"SELECT CategoryID,CategoryName FROM Categories "</span>;
  SqlConnection myConnection = <span class="cs-keyword" nd="21">new</span> SqlConnection(GetConnectionString());
  SqlDataAdapter ad = <span class="cs-keyword" nd="22">new</span> SqlDataAdapter(query,myConnection);
  DataSet ds = <span class="cs-keyword" nd="23">new</span> DataSet();
  ad.Fill(ds,<span class="cpp-string" nd="24">"Categories"</span>);
  <span class="cs-keyword" nd="25">return</span> ds;
}</pre>
														<p nd="26">As you might have already noticed, this method is marked with the <code nd="27">Ajax.AjaxMethod</code> attribute. This means that this method is going to be called from the client side. Now let's see how we can access this method from the client side.</p>
														<div class="precollapse" id="premain2" style="WIDTH: 100%">
																<img id="preimg2" style="CURSOR: hand" height="9" src="http://www.codeproject.com/images/minus.gif" width="9" preid="2" />
																<span id="precollapse2" style="MARGIN-BOTTOM: 0px; CURSOR: hand" nd="28" preid="2">Collapse</span>
														</div>
														<pre lang="jscript" id="pre2" style="MARGIN-TOP: 0px" nd="29">
																<span class="cpp-keyword">function</span> FillDropDownList()
{
  UsingAjax.GetDropDownListData(FillDropDownList_CallBack);
}

<span class="cpp-keyword">function</span> FillDropDownList_CallBack(response)
{
  <span class="cpp-keyword">var</span> ds = response.value;
  <span class="cpp-keyword">var</span> html = <span class="cpp-keyword">new</span> Array();

  <span class="cpp-keyword">if</span>(ds!= <span class="cpp-keyword">null</span> &amp;&amp; typeof(ds) == <span class="cpp-string" nd="30">"object"</span> &amp;&amp; ds.Tables!= <span class="cpp-keyword">null</span>)
  {
    <span class="cpp-keyword">for</span>(<span class="cpp-keyword">var</span> i=<span class="cpp-literal">0</span>;i&lt;ds.Tables[<span class="cpp-literal">0</span>].Rows.length;i++)
    {
      html[html.length] = <span class="cpp-string" nd="31">"&lt;option value="</span> + 
                          ds.Tables[<span class="cpp-literal">0</span>].Rows[i].CategoryID + <span class="cpp-string" nd="32">"&gt;"</span> 
                          + ds.Tables[<span class="cpp-literal">0</span>].Rows[i].CategoryName + 
                          <span class="cpp-string" nd="33">"&lt;/option&gt;"</span>;
    }
    document.getElementById(<span class="cpp-string" nd="34">"Display"</span>).innerHTML = 
        <span class="cpp-string" nd="35">"&lt;select id=\"</span>sel\<span class="cpp-string" nd="36">" onchange=\"</span> ChangeListValue<span class="cpp-string" nd="37">" + 
        "</span>(<span class="cpp-keyword">this</span>.options[<span class="cpp-keyword">this</span>.selectedIndex].value); \<span class="cpp-string" nd="38">"&gt;"</span> + 
        html.join(<span class="cpp-string" nd="39">""</span>) + <span class="cpp-string" nd="40">"&lt;/select&gt;"</span>;
  }
}</pre>
														<p nd="41">Let me first explain the <code nd="42">FillDropDownList()</code> method. <code nd="43">UsingAjax</code> is the name of the class which contains the <code nd="44">GetDropDownListData</code> method which we implemented a few moments ago. We call <code nd="45">FillDropDownList_CallBack()</code> which contains the actual code to populate the dropdown list.</p>
														<p nd="46">Take a look at the line below:</p>
														<pre lang="jscript" nd="47">document.getElementById(<span class="cpp-string" nd="48">"Display"</span>).innerHTML = 
                       <span class="cpp-string" nd="49">"&lt;select id=\"</span>sel\<span class="cpp-string" nd="50">" onchange=\"</span></pre>
														<p nd="51">You must be wondering what "<code nd="52">Display</code>" is. <code nd="53">Display</code> is no more than a <code lang="html" nd="54">SPAN</code> tag. I have implemented it below:</p>
														<pre lang="html" nd="55">&lt;span id="Display"&gt;&lt;/span&gt;</pre>
														<p nd="56">Now let's go and see how the <code nd="57">ChangeListValue</code> method is implemented since it is called when the selection in the dropdown changes.</p>
														<pre lang="jscript" nd="58">
																<span class="cpp-keyword">function</span> ChangeListValue(index)
{
  GetResult(index);
}</pre>
														<p nd="60">
																<code nd="59">ChangeListValue()</code> calls <code nd="61">GetResult(index)</code>. Now let's go to <code nd="62">GetResult(index)</code>.</p>
														<div class="precollapse" id="premain6" style="WIDTH: 100%">
																<img id="preimg6" style="CURSOR: hand" height="9" src="http://www.codeproject.com/images/minus.gif" width="9" preid="6" />
																<span id="precollapse6" style="MARGIN-BOTTOM: 0px; CURSOR: hand" nd="63" preid="6">Collapse</span>
														</div>
														<pre lang="jscript" id="pre6" style="MARGIN-TOP: 0px" nd="64">
																<span class="cpp-keyword">function</span> GetResult(categoryID)
{
  UsingAjax.GetProductsByID(categoryID,GetResult_CallBack);
}

<span class="cpp-keyword">function</span> GetResult_CallBack(response)
{
  <span class="cpp-keyword">var</span> ds = response.value;
  <span class="cpp-keyword">if</span>(ds!=<span class="cpp-keyword">null</span> &amp;&amp; typeof(ds) == <span class="cpp-string" nd="65">"object"</span> &amp;&amp; ds.Tables!=<span class="cpp-keyword">null</span>)
  {
    <span class="cpp-keyword">var</span> s = <span class="cpp-keyword">new</span> Array();
    s[s.length] = <span class="cpp-string" nd="66">"&lt;table border = 1&gt;"</span>;

    <span class="cpp-keyword">for</span>(<span class="cpp-keyword">var</span> i=<span class="cpp-literal">0</span>;i&lt;ds.Tables[<span class="cpp-literal">0</span>].Rows.length;i++)
    {
        s[s.length] = <span class="cpp-string" nd="67">"&lt;tr&gt;"</span>;
        s[s.length] = <span class="cpp-string" nd="68">"&lt;td&gt;"</span> + ds.Tables[<span class="cpp-literal">0</span>].Rows[i].ProductID + <span class="cpp-string" nd="69">"&lt;/td&gt;"</span>;
        s[s.length] = <span class="cpp-string" nd="70">"&lt;td&gt;"</span> + ds.Tables[<span class="cpp-literal">0</span>].Rows[i].ProductName + <span class="cpp-string" nd="71">"&lt;/td&gt;"</span>;
        s[s.length] = <span class="cpp-string" nd="72">"&lt;td&gt;"</span> + ds.Tables[<span class="cpp-literal">0</span>].Rows[i].QuantityPerUnit + <span class="cpp-string" nd="73">"&lt;/td&gt;"</span>;
        s[s.length] = <span class="cpp-string" nd="74">"&lt;/tr&gt;"</span>;
    }
    s[s.length] = <span class="cpp-string" nd="75">"&lt;/table&gt;"</span>;

    document.getElementById(<span class="cpp-string" nd="76">"Display1"</span>).innerHTML = s.join(<span class="cpp-string" nd="77">""</span>);
  }
}</pre>
														<p nd="79">
																<code nd="78">GetResults()</code> method calls the server side method "<code nd="80">GetProductsByID</code>".</p>
														<pre lang="cs" nd="81">[Ajax.AjaxMethod]
<span class="cs-keyword" nd="82">public</span> DataSet GetProductsByID(<span class="cs-keyword" nd="83">int</span> categoryID)
{
  <span class="cs-keyword" nd="84">string</span> query = <span class="cpp-string" nd="85">"SELECT * FROM Products WHERE CategoryID = @CategoryID "</span>;
  SqlConnection myConnection = <span class="cs-keyword" nd="86">new</span> SqlConnection(GetConnectionString());
  SqlCommand myCommand = <span class="cs-keyword" nd="87">new</span> SqlCommand(query,myConnection);

  myCommand.Parameters.Add(<span class="cpp-string" nd="88">"@CategoryID"</span>,categoryID);
  SqlDataAdapter ad = <span class="cs-keyword" nd="89">new</span> SqlDataAdapter(myCommand);
  DataSet ds = <span class="cs-keyword" nd="90">new</span> DataSet();

  ad.Fill(ds);
  <span class="cs-keyword" nd="91">return</span> ds;
}</pre>
														<p nd="92">So, there you go now. When you select an item from the dropdown, your <code nd="93">DataGrid</code> will pull up new results without having to refresh the page. In other words, there will be no postback.</p>
														<p nd="94">You should also make a <code nd="95">BindControls()</code> method that will populate the controls when the page loads. Here is my implementation of the <code nd="96">BindControls()</code> method. Keep in mind that we have already implemented the <code nd="97">FillDropDownList()</code> method above.</p>
														<pre lang="jscript" nd="98">
																<span class="cpp-keyword">function</span> BindControls()
{
  FillDropDownList();
}</pre>
														<p nd="99">After making the <code nd="100">BindControls</code> method you just need to call it when the page loads.</p>
														<pre lang="html" nd="101">&lt;body onload="BindControls();"&gt;</pre>
														<p nd="102">You also need to add these settings in the <i>web.config</i> file:</p>
														<pre lang="xml" nd="103">&lt;configuration&gt;
  &lt;system.web&gt;
    &lt;httpHandlers&gt;
      &lt;add verb="POST,GET " path="ajax /*.ashx"
           type="Ajax.PageHandlerFactory, Ajax" /&gt; 
    &lt;/httpHandlers&gt;  
    ...
  &lt;system.web&gt;
&lt;/configuration&gt;</pre>
														<p nd="104">For your convenience I have attached the zip file which contains all the files you need for this project. I hope you like the article, happy coding!</p>
														<!-- Article Ends -->
												</div>
										</span>
										<script src="/script/togglePre.js" type="text/javascript">
										</script>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/22640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2007-02-03 23:26 <a href="http://www.cnitblog.com/MartinYao/articles/22640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>