<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Andrew Corkery &#187; json</title>
	<atom:link href="http://www.andrewcorkery.com/tag/json/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.andrewcorkery.com</link>
	<description>Software Developer etc.</description>
	<lastBuildDate>Wed, 06 Jan 2010 09:59:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Talking to the server with JSON-RPC &amp; Jayrock</title>
		<link>http://www.andrewcorkery.com/2010/01/06/talking-with-jayrock/</link>
		<comments>http://www.andrewcorkery.com/2010/01/06/talking-with-jayrock/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 09:58:02 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[jayrock]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>

		<guid isPermaLink="false">http://www.andrewcorkery.com/?p=100</guid>
		<description><![CDATA[A shiny old toy
I recently came across a .NET utility called Jayrock, an open source implementation of JSON-RPC. The project was apparently started a few years ago by Atif Aziz, a guy whose work is definitely worth checking out if you&#8217;re a .NET web developer. Jayrock essentially makes it really easy to interoperate between client-side [...]]]></description>
			<content:encoded><![CDATA[<h2>A shiny old toy</h2>
<p>I recently came across a .NET utility called <a href="http://jayrock.berlios.de/" target="_blank">Jayrock</a>, an open source implementation of JSON-RPC. The project was apparently started a few years ago by <a href="http://www.raboof.com/">Atif Aziz</a>, a guy whose work is definitely worth checking out if you&#8217;re a .NET web developer. Jayrock essentially makes it <strong>really</strong> easy to interoperate between client-side Javascript code and server-side ASP.NET code, without the need to construct bloated XML requests like traditional AJAX &#8211; it uses JSON notation. The thing I love about it is that it abstracts away the mapping between server-side business objects and javascript objects, as well as exposing business logic to the client in a way that is completely controlled by the developer.</p>
<h2>An Example</h2>
<p>I can think of a few areas of web development where Jayrock would come in handy &#8211; validation, partial page updates, dynamic form elements, capturing user interaction for stats &#8211; to name a few. I decided to make a demo of an accordian control to test it out. It&#8217;s a list of Frequently Asked Questions (FAQs) that loads answers on demand. When a user clicks on a question, the answer for that question only is fetched using JSON-RPC.</p>
<p>Though this is a trivial example, and in this case it would be more efficient to load all answers at once, it demonstrates how useful it would be if the content being loaded on demand was perhaps a video or large images.</p>
<p><a href="http://demo.andrewcorkery.com/jayrock" target="_blank"><img src="http://www.andrewcorkery.com/wp-content/uploads/2010/01/accordian.gif" width="619" height="222" /></a></p>
<p><a href="http://demo.andrewcorkery.com/jayrock" target="_blank">Click here to try out the the accordian</a></p>
<h2>The Code</h2>
<p>The solution requires a <a href="http://jquery.com/" target="_blank">jQuery</a> &lt;script&gt; reference to be included. It also requires the Jayrock JSON-RPC utility to be included in the project. This requires a few additions to the Web.config, a DLL in the Bin folder and a &lt;script&gt; reference. <a href="http://jayrock.berlios.de/#setup" target="_blank">Specifics here</a>.</p>
<h3>Javascript Includes in the web page</h3>
<p>The first 2 references are to the jQuery library and the JSON utility library (distributed with Jayrock) that converts JavaScript values to JSON and vice versa. The 3rd script reference points to the JavaScript proxy that will be dynamically generated by Jayrock from the server so that we can call our service methods. The final script reference is to our custom JavaScript that will perform the client side interactions and invoke calls to our server-side code.</p>
<pre class="brush: xml;">

&lt;script src=&quot;js/jquery-1.3.2.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/json.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;jsonaccordianfunctions.ashx?proxy&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/accordian.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</pre>
<h3>ASP.NET ListView control to display the accordian</h3>
<p>The only thing to note here is that we are assigning the ID of the FAQ to the &#8220;id&#8221; attribute of the &lt;dt&gt; tag that is generated (line 8). The assigned &#8220;id&#8221; will enable us to fetch the corresponding answer using our client-side code.</p>
<pre class="brush: xml;">&lt;asp:ListView ID=&quot;lvAccordian&quot; runat=&quot;server&quot;&gt;
    &lt;LayoutTemplate&gt;
    &lt;dl class=&quot;accordian&quot;&gt;
        &lt;asp:PlaceHolder ID=&quot;itemPlaceholder&quot; runat=&quot;server&quot; /&gt;
    &lt;/dl&gt;
    &lt;/LayoutTemplate&gt;
    &lt;ItemTemplate&gt;
        &lt;dt id=&quot;item&lt;%# Eval(&quot;ID&quot;) %&gt;&quot;&gt;&lt;%# Eval(&quot;Question&quot;) %&gt;&lt;/dt&gt;
        &lt;dd&gt; &lt;/dd&gt;
    &lt;/ItemTemplate&gt;
&lt;/asp:ListView&gt;</pre>
<h3>Binding the data on Page Load</h3>
<p>For simplicity, I&#8217;m using Linq-to-XML to fetch all FAQs from an XML file stored in App_Data. These are data-bound to the ListView in the previous snippet.</p>
<pre class="brush: csharp;">protected void Page_Load(object sender, EventArgs e) {
        //open Faqs.xml
        XDocument doc = XDocument.Load(Server.MapPath(&quot;~/App_Data/Faqs.xml&quot;));

        //bind the questions to the accordian
        lvAccordian.DataSource = from faq in doc.Descendants(&quot;faq&quot;)
                                 select new Faq
                                 {
                                     Id = Convert.ToInt32(faq.Attribute(&quot;id&quot;).Value),
                                     Question = faq.Element(&quot;question&quot;).Value
                                 };
        lvAccordian.DataBind();
}</pre>
<h3>Define service methods in our Json RPC Handler</h3>
<p>This is where it gets interesting. We create an ASP.NET web handler that inherits from <strong>JsonRpcHandler</strong> (a Jayrock library class). In this handler we can declare service methods that may be called directly from our javascript code. We have one method, <strong>GetFaqById</strong> which fetches an <strong>Faq</strong> object based on it&#8217;s ID. The attribute <strong>JsonRpcMethod</strong> specifies the name of the method that can be accessed by JavaScript. This may be different to the C# method name.</p>
<p>The really useful thing about Jayrock is that it handles converting the custom complex type (<strong>Faq</strong>) to a JSON string that can be operated upon by JavaScript code.</p>
<p>Jayrock generates a simple JavaScript proxy using the &lt;script&gt; reference above (<strong>jsonaccordianfunctions.ashx?proxy</strong>) and this is how our JS code &#8220;talks&#8221; to our server side code.</p>
<pre class="brush: csharp;">
&lt;%@ WebHandler Language=&quot;C#&quot; Class=&quot;JsonAccordianFunctions&quot; %&gt;

using System;
using System.Web;
using System.Linq;
using System.Xml.Linq;
using System.Data.Linq;
using Jayrock.Json;
using Jayrock.JsonRpc;
using Jayrock.JsonRpc.Web;

public class JsonAccordianFunctions : JsonRpcHandler {

    [JsonRpcMethod(&quot;getFaqById&quot;)]
    public Faq GetFaqById(int id) {
        //open Faqs.xml
        XDocument doc = XDocument.Load(Server.MapPath(&quot;~/App_Data/Faqs.xml&quot;));

        //fetch Faqs that match the provided ID
        var faqs = from faq in doc.Descendants(&quot;faq&quot;)
                   where faq.Attribute(&quot;id&quot;).Value == id.ToString()
                   select new Faq
                   {
                       Question = faq.Element(&quot;question&quot;).Value,
                       Answer = faq.Element(&quot;answer&quot;).Value
                   };

        //return the first if found
        return faqs.FirstOrDefault();
    }
}
</pre>
<h3>The Javascript</h3>
<p>The code below may look a little convoluted (indeed it is, in parts). However most of it is there to provide the visual effects (toggling visibility, expand/collapse buttons, changing backgrounds etc).</p>
<p>The lines to look at are 22-36. Inside the <span>click</span> event handler, we fetch the desired FAQ from our service and display the answer to the user by calling <span>faq.answer</span> &#8211; properties of our C# class are auto-mapped to fields in a Javascript object! Nice.</p>
<pre class="brush: jscript;">
$(document).ready(function () {
    //create a reference to the JavaScript proxy that interfaces with our handler
    var jf = new JsonAccordianFunctions();

    $(&quot;.accordian dd&quot;).hide();

    $(&quot;.accordian dt&quot;).hover(
            function () {
                var tip = &quot;&lt;span&gt;expand&lt;/span&gt;&quot;;
                if ($(this).next().is(&quot;:visible&quot;)) {
                    tip = &quot;&lt;span&gt;collapse&lt;/span&gt;&quot;;
                }
                $(this).prepend(tip);
            },
            function () {
                $(this).find(&quot;span:first&quot;).remove();
            }
        );

    $(&quot;.accordian dt&quot;).click(function () {
        if (!$(this).next().is(&quot;:visible&quot;)) {
            //get the ID of the &lt;dt&gt; the user has clicked
            var htmlId = $(this).attr(&quot;id&quot;);

            //extract the ID of the target FAQ from the HTML ID
            var id = htmlId.substring(4)

            //make a call to the service using the JavaScript proxy, generated by Jayrock
            //here we are fetching an FAQ by it's ID
            var faq = jf.getFaqById(id);            

            $(&quot;.accordian dd&quot;).hide();
            $(&quot;.accordian dt&quot;).css(&quot;background-image&quot;, &quot;url('../img/backgrounds/grey-gradient.gif')&quot;);

            //populate the next html element (&lt;dd&gt;) with the answer of the FAQ
            $(this).next().html(faq.answer);

            $(this).next().show(&quot;fast&quot;);

            $(this).find(&quot;span:first&quot;).text(&quot;collapse&quot;);
            $(this).css(&quot;background-image&quot;, &quot;url('../img/backgrounds/green-gradient.gif')&quot;);
        } else {
            $(&quot;.accordian dd&quot;).hide(&quot;fast&quot;);

            $(this).find(&quot;span:first&quot;).text(&quot;expand&quot;);
            $(this).css(&quot;background-image&quot;, &quot;url('../img/backgrounds/grey-gradient.gif')&quot;);
        }
    });
});
</pre>
<p>Download the full source code <a href="http://demo.andrewcorkery.com/jayrock/accordian.zip">here</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.andrewcorkery.com/2010/01/06/talking-with-jayrock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
