<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Blogs at Near Infinity</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/" />
    <link rel="self" type="application/atom+xml" href="http://www.nearinfinity.com/blogs/atom.xml" />
    <id>tag:www.nearinfinity.com,2007-12-20:/blogs/7</id>
    <updated>2010-07-23T02:45:15Z</updated>
    <subtitle>Employee Blogs</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.31-en</generator>

<entry>
    <title>Death to the DAO and How to Test LINQ</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/death_to_the_dao_and_how_to_te.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1753</id>

    <published>2010-07-23T02:42:43Z</published>
    <updated>2010-07-23T02:45:15Z</updated>

    <summary>Occasionally I hear complaints that LINQ is hard to unit test. These complaints aren&apos;t about LINQ to objects, mind you, they&apos;re specific to the complexities of the flavors of LINQ...</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term=".NET" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="architecture" label="architecture" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="linq" label="LINQ" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="testing" label="testing" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>Occasionally I hear complaints that LINQ is hard to unit test.  These complaints aren't about LINQ to objects, mind you, they're specific to the complexities of the flavors of LINQ that turn C# code into something else like SQL or CAML using <a href="http://rapidapplicationdevelopment.blogspot.com/2008/03/expression-trees-why-linq-to-sql-is.html">expression trees</a>.  The most common technologies are LINQ to SQL, the Entity Framework, or in my case at the moment LINQ to SharePoint.  In this post I'm going to propose a technique that makes testing LINQ not just easy, but downright elegant - assuming you're ok with extension methods - lots of extension methods.  And assuming you're ready to kill your Data Access Objects (DAO) tier.</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2010/07/death-to-dao-and-how-to-test-linq.html';

        /* Digg */
        var diggIframe = document.createElement('iframe');
        diggIframe.setAttribute('src', 'http://digg.com/tools/diggthis.php?u=' + currentPageUrl);
        diggIframe.setAttribute('height', '80');
        diggIframe.setAttribute('width', '52');
        diggIframe.setAttribute('frameborder', '0');
        diggIframe.setAttribute('scrolling', 'no');
        diggIframe.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');

        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);

        var div = document.createElement('div');
        div.appendChild(dotnetkicksLink);
        div.appendChild(document.createElement('br'));
        div.appendChild(diggIframe);

        document.write(div.innerHTML);
    </script>
</div>


<p><b>The Unit Testing Problem</b></p><p>Any architecture needs a place to put code that finds entities.  For instance FindBySocialSecurityNumber().  In a traditional architecture we might put a method like this is in a DAO layer.  If so our method will look something like this:</p><p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">public</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"> <span style="color:blue">class</span> <span style="color:#2B91AF"> EmployeesDao</span> {<br /> <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span> <span style="color:#2B91AF">Employee</span> FindBySSN(<span   style="color:#2B91AF">Context</span> ctx, <span style="color:blue">string</span>  ssn) {<br /> <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">return</span>  ctx.Employees.SingleOrDefault(e =&gt; e.Ssn == ssn);<br /> <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>}<br /> }</span></p><p>So how would we go about unit testing this?</p><p>One fairly typical solution would be to use an in-memory database.  That approach works if our data store is a database, but it certainly doesn't work if the data store is something less traditional like SharePoint.  But even if our store is a database, we'll still have the hassle of setting up the in-memory database.</p><p>Another solution might be to use a mock Context that returns an IQueryable<Employee>.  But wouldn't it be wonderful if we could avoid mocking all together?</p><p><b>Killing the DAO</b></p><p>The first question is why we even have a DAO tier to begin with.  The original idea was that we wanted a place to put code specific to a particular data store.  In other words we wanted to isolate the code that will need to be changed should the data store switch from SQL Server to Oracle.  But isn't that exactly what LINQ does?  I'd be pretty surprised if there wasn't a decent LINQ provider for just about any data store at this point that required more than minimal code changes.  So why not embrace LINQ and reconsider alternatives to a DAO tier?</p><p>One alternative that I've been using for over a month now is to switch to extension methods.  To give credit where it's due the idea originated with a conversation with fellow <a href="http://www.nearinfinity.com">Near Infinity</a> employee <a href="http://www.nearinfinity.com/blogs/joe_ferner/">Joe Ferner</a>.  And I'm sure the idea isn't particularly original (please post in the comments if you know others that use this approach).</p><p>Using this technique our code changes from something like this:</p><p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">var</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:R-SA"> employeeDao = <span style="color:blue">new</span> <span style="color:#2B91AF">EmployeesDao</span>(); <span style="color:green">//  or use IOC of course<br /> </span>employeeDao.FindBySSN(ctx, <span style="color:#A31515">&quot;111-11-1111&quot;</span>);</span></p><p>To something like this:</p><p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">ctx.Employees.FindBySSN(<span style="color:#A31515">&quot;111-11-1111&quot;</span>);</span></p><p>Among other things I find this far more aesthetically pleasing because each of the three elements to the statement represent a subsequent filtering of data.  It's a more functional way of looking at things.</p><p>We could implement this off of the Employees property of the context if we have control over that (which I don't with spmetal). But if we implement this as an extension method like this:</p><p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">public</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"> <span style="color:blue">static</span> <span style="color:blue">class</span> <span style="color:#2B91AF">EmployeeExtensions</span> {<br /> <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span> <span style="color:blue">static</span> <span style="color:#2B91AF">Employee</span>  FindBySSN(<span style="color:blue">this</span> <span style="color:#2B91AF"> IQueryable</span>&lt;<span style="color:#2B91AF">Employee</span>&gt; employees, <span style="color:blue">string</span> ssn) {<br /> <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">return</span>  employees.SingleOrDefault(e =&gt; e.Ssn == ssn);<br /> <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>}<br /> }</span></p><p>We now have something that's considerable easier to unit test.</p><p><b>Testing It</b></p><p>Once we've refactored our function as an extension method that filters down the corpus of entities, we can test the code using in-memory objects with a call to .AsQueryable().  For instance:</p><p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">public</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:R-SA"> <span style="color:blue">void</span>  FindBySSN_OneSsnExists_EmployeeReturned() {<br /> <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span>  employees = <span style="color:blue">new</span> [] { <span style="color:blue"> new</span> <span style="color:#2B91AF">Employee</span> { Ssn = <span style="color:#A31515">&quot;111-11-1111&quot;</span> } };<br /> <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span>  actual = employees.AsQueryable().FindBySSN(<span style="color:#A31515">&quot;111-11-1111&quot;</span>);<br /> <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">Assert</span>.IsNotNull(actual); <br /> }</span></p><p>Notice we didn't have to mock anything.</p><p><b>Testability, but at What Cost?</b></p><p>This technique works great for the example above, but how does it scale to harder problems and what other downsides are there?</p><p>As far as scalability I've found this technique works great for every scenario I've run across in the month I've been doing it.  It works for joins, aggregations, and even for inserts, update, and deletes.</p><p>As far as downsides the astute reader may be wondering about mockability.  For instance what if we want to mock the call to FindBySSN and give it the exact Employee that will be returned.  This scenario is admittedly harder.  But what I've found is that far more often than not I don't really need to mock the types of things that used to live in the DAO tier.  Instead I just mock the Employee object off of context to return in-memory objects and make my tests slightly larger in scope.  Most of the time I find the larger scope increases the usefulness of the test.  In the occasional case where I do really want to mock the "DAO" tier I use a technique described in <a href=" http://www.clariusconsulting.net/blogs/kzu/archive/2009/02/19/Makingextensionmethodsamenabletomocking.aspx">this post</a> by Daniel Cazzulino.</p><p><b>Conclusion</b></p><p>Obviously there is more to this architecture, for instance how do you handle insert and update operations?  The short answer is it's easy, but I'll save that topic for a future post.  For now why not give this approach a try?  You weren't really happy with that useless old DAO tier anyway, were you?  I say we eradicate it and never look back.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Display a custom UIView like a UIActionSheet</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/andrew_homeyer/display_a_custom_uiview_like_a.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1744</id>

    <published>2010-06-14T04:05:49Z</published>
    <updated>2010-06-14T18:51:47Z</updated>

    <summary>Have you ever tried to use a UIActionSheet to display more than just buttons? It doesn&apos;t work, as you have probably figured out. The common solution is to create a...</summary>
    <author>
        <name>Andrew Homeyer</name>
        <uri>http://www.nearinfinity.com/blogs/andrew_homeyer</uri>
    </author>
    
        <category term="iPhone" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<div>Have you ever tried to use a UIActionSheet to display more than just buttons? It doesn't work, as you have probably figured out. The common solution is to create a custom UIViewController and display it using UIViewController's <a href="http://developer.apple.com/iphone/library/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW29">presentModalViewController</a>, which can give you a nice slide up transition, much like how a UIActionSheet appears.</div><div><br /></div><div>But that solution is missing something. A UIActionSheet slides up, but not all the way, leaving a semi-transparent covering over the parent view. Let's try to display a custom view with this same effect.</div><div><br /></div><div>Full sample code can be found on <a href="http://github.com/homeyer/CustomUIActionSheet">github</a>.</div><div><br /></div><div>Let's start fresh by creating a new project in Xcode and choosing "Navigation-based Application." This gives us a RootViewController and an AppDelegate.</div><div><br /></div><div><font class="Apple-style-span" style="font-size: 1.25em; ">1. Create our custom action sheet</font></div><div><br /></div><div>Create a new UIViewController subclass with XIB (right click on Classes -&gt; Add -&gt; New File). I'm naming it CustomUIActionSheetViewController.</div><div>Add an outlet in the parent view controller (RootViewController) for our action sheet and synthesize it.</div><div><br /></div><div>

<pre class="prettyprint">@property(nonatomic, retain) IBOutlet
CustomUIActionSheetViewController *customUIActionSheetViewController;</pre><div><br />

</div></div><div>Open the RootViewController.xib in Interface Builder, drag a View Controller onto the document window. Tell it to be the CustomUIActionSheetViewController we just created by changing the Class property in the Identity Inspector, and the NIB Name in the Attributes Inspector.&nbsp;</div><div><br /></div><div>Connect the outlet we created from the File's Owner to the controller.</div><div><br /></div><div>At this point we've created our action sheet view controller and given the RootViewController a reference to it. You won't see anything different from a new project when you build and run.</div><div><br /></div>

<div><font class="Apple-style-span" style="font-size: 1.25em; ">2. Show our custom action sheet</font></div><div><br /></div><div>In the parent view controller (RootViewController), create a method to show the custom view.</div><div><br /></div>


<div><div>

<pre class="prettyprint">- (void)showCustomView {   
    [self.navigationController.view
        addSubview:self.customUIActionSheetViewController.view];

    [self.customUIActionSheetViewController viewWillAppear:NO];
}
</pre>

</div></div><div><br /></div>


<div>We're simply adding the view as a subview, we'll do the work to slide up the content in our custom view controller. Note that we need to <a href="http://stackoverflow.com/questions/131062/iphone-viewwillappear-not-firing">call viewWillAppear ourselves</a>, it's called for you when using presentModalViewController.</div><div><br /></div><div>Add a button when the RootViewController first loads to show our custom action sheet.</div><div><br /></div>

<pre class="prettyprint">- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] 
        initWithBarButtonSystemItem:UIBarButtonSystemItemAction 
        target:self 
        action:@selector(showCustomView)] autorelease];
}

</pre>

<div>
At this point, when you click the button in the navigation bar, you should see the custom view immediately appear without any transition.</div><div><br /></div><div><font class="Apple-style-span" style="font-size: 1.25em; ">3. Make background semi-transparent</font></div><div><br /></div><div>When the custom view loads, we want the parent view to be covered by a semi-transparent view.</div><div><br /></div><div>Open our custom action sheet NIB (CustomUIActionSheetViewController.xib) in Interface Builder.&nbsp;</div><div>In the Attributes Inspector for the UIView (there should only be one right now), click the background field. Change it's color to black (or the darkTextColor property), and change the Opacity to 50%.</div><div><br /></div><div><img alt="view_background_properties.png" src="http://www.nearinfinity.com/blogs/assets/view_background_properties.png" width="228" height="383" class="mt-image-none" style="" /></div><div><br /></div><div>When you build and run and click the right navigation button you should now see the semi-transparent view cover the parent view.</div><div><br /></div><div><font class="Apple-style-span" style="font-size: 1.25em; ">4. Add a view to hold our custom fields</font></div><div><br /></div><div>Drag a new UIView onto the NIB and attach it to a new outlet in View Controller. I'm calling it the actionSheetView.</div><div><br /></div>

<pre class="prettyprint">@property(nonatomic, retain) IBOutlet UIView *actionSheetView;
</pre>


<div>Adjust the height of the view to be less than 480, but keep the width at 320. This will determine how far up we'll slide the view.</div><div><br /></div><div>Next, let's add a navigation bar and a 'done' button that will dismiss the dialog.</div><div><br /></div><div>Drag a Navigation Bar onto the view, and then a Navigation Item onto the Navigation Bar. Change the Navigation Item's title to 'Done' and&nbsp;change the Navigation Bar's title to whatever you want.</div><div><br /></div><div>Let's go ahead and add a stub in the the CustomUIActionSheetViewController's header for 'slideOut', make it a UIAction, and connect the done button to it in IB.</div><div><br /></div>

<pre class="prettyprint">- (IBAction) slideOut;
</pre>

<div><br /></div><div>At this point, when you click the right nav button, you won't see the view we just created because we haven't added it as a subview yet.</div><div><br /></div><div><font class="Apple-style-span" style="font-size: 1.25em; ">5. Add the slide up transition</font></div><div><br /></div><div>Create a new method to slide up the actionSheetView, and call it from the viewWillAppear method.</div><div><br /></div>

<pre class="prettyprint">- (void)viewWillAppear:(BOOL)animated {
    [self slideIn];	
}

- (void)slideIn {
    //set initial location at bottom of view
    CGRect frame = self.actionSheetView.frame;
    frame.origin = CGPointMake(0.0, self.view.bounds.size.height);
    self.actionSheetView.frame = frame;
    [self.view addSubview:self.actionSheetView];
	
    //animate to new location, determined by height of the view in the NIB
    [UIView beginAnimations:@"presentWithSuperview" context:nil];
    frame.origin = CGPointMake(0.0, 
        self.view.bounds.size.height - self.actionSheetView.bounds.size.height);
	
    self.actionSheetView.frame = frame;
    [UIView commitAnimations];
}
</pre>


<div>To do this, we change the frame of the actionSheetView so that its top is at the bottom of the screen, and then start an animation block. In the animation we change the frame again, this time setting it's top to be the height of the actionSheetView. When we commit the animation, the view will transition from it's current position (at the bottom) to the position defined in the animation block.</div><div><br /></div><div>When you build and run you should see the actionSheetView slide up when you click the right nav button.</div><div><br /></div><div><font class="Apple-style-span" style="font-size: 1.25em; ">6. Add the slide out transition</font></div><div><br /></div><div>To slide out the custom view when 'done' is clicked we need to implement the stub we created earlier.</div><div><br /></div>

<pre class="prettyprint">- (void) slideOut {
    [UIView beginAnimations:@"removeFromSuperviewWithAnimation" context:nil];
	
    // Set delegate and selector to remove from superview when animation completes
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
	
    // Move this view to bottom of superview
    CGRect frame = self.actionSheetView.frame;
    frame.origin = CGPointMake(0.0, self.view.bounds.size.height);
    self.actionSheetView.frame = frame;
	
    [UIView commitAnimations]; 
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    if ([animationID isEqualToString:@"removeFromSuperviewWithAnimation"]) {
        [self.view removeFromSuperview];
    }
}
</pre>

<div><br /></div><div>Like before, we're going to change the origin of the frame wrapped in an animation block to slide out the view. We're doing a little extra work with setAnimationDidStopSelector. When the animation finishes, we want to remove our entire view (including the semi-transparent view), to go back to the state we were in before it was slid in. In the callback selector we simply use removeFromSuperview to do this.</div><div><br /></div><div>That's it! The actionSheetView should slide in when you click the right navigation button, and the done button should slide it out.</div><div><br /></div><div>Thanks to <a href="http://stackoverflow.com/questions/587681/how-to-use-presentmodalviewcontroller-to-create-a-transparent-view">this answer on Stack Overflow</a> for getting me started.</div><div><br /></div><div>Download or fork the sample code from&nbsp;<a href="http://github.com/homeyer/CustomUIActionSheet" style="text-decoration: underline; ">github</a>.</div><div><br /></div> ]]>
        
    </content>
</entry>

<entry>
    <title>Launching Mini Confluence Enterprise Edition at the Atlassian Summit</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/caroline_wizeman/launching_mini_confluence_ente.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1740</id>

    <published>2010-06-10T22:24:31Z</published>
    <updated>2010-06-10T22:27:40Z</updated>

    <summary>We&apos;re in San Francisco this week at the Atlassian Summit lunching Mini Confluence Enterprise Edition -- a way to access Confluence on your iPhone, Blackberry, Palm or Android. At last...</summary>
    <author>
        <name>Caroline Wizeman</name>
        
    </author>
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="iPhone" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="miniconfluence" label="Mini Confluence" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[We're in San Francisco this week at the Atlassian Summit lunching Mini 
Confluence Enterprise Edition -- a way to access Confluence on your 
iPhone, Blackberry, Palm or Android. <br />
<br />At last year's summit, we released Mini Confluence Personal Edition,
 an iPhone app that individual users can purchase from the app store and
 run based on Confluence's XML-RPC. <br /><br />The new version is a custom 
plugin installed on the server. For people using an iPhone, they still 
download an app from the app store, but with the Enterprise Edition, 
it's free. For people with other mobile devices, they get to Mini 
Confluence through a web client. <br />
<br />This year's version is two times as fast as the original (!), and 
has some cool new features like filtering on the dashboard based on your
 favorites, status updates, landscape mode, and multiple user accounts. 
Find out more about Mini Confluence at <a href="http://www.miniconfluence.com/">www.miniconfluence.com</a>.<br /><u></u>
<br />We've been talking to lots of the conference attendees the past 
couple 
of days. Some of them have already been using the personal edition, and 
have given us feedback on that. Other people have ideas for MCEE, like 
an iPad version, support for Confluence instances protected by VPN, and 
even "make Mini Jira!"<br /><br />I'm surprised by how many people here are 
on Android. It's still mostly 
iPhones, but a lot less Blackberry users than last year. <br />
<br />
A lot 
of people have been signing up for the<a href="http://www.miniconfluence.com/get-it#beta"> beta program </a>-- we're sending out
 copies of the plugin for free to anyone who's interested and letting 
them try it out for three months. I'm anxious to hear the feedback so we
 can improve it before people start paying for it. <br />
<br />If you try it out, let us know what you think!<br /><br />And now... I 
think it's time for some Ghirardelli Chocolate :-) ]]>
        
    </content>
</entry>

<entry>
    <title>Missing the each_line method in FakeFS version 0.2.1? Add it!</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/scott_leberknight/missing_the_each_line_method_i.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1733</id>

    <published>2010-05-07T02:22:38Z</published>
    <updated>2010-05-07T03:21:24Z</updated>

    <summary>Recently we have been using the excellent FakeFS (fake filesystem) gem in some specs to test code that reads and writes files on the filesystem. We are using the latest...</summary>
    <author>
        <name>Scott Leberknight</name>
        
    </author>
    
        <category term="Ruby" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="fakefs" label="FakeFS" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rspec" label="RSpec" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>Recently we have been using the excellent <a href="http://github.com/defunkt/fakefs">FakeFS</a> (fake filesystem) gem in some specs to test code that reads and writes files on the filesystem. We are using the latest <em>release</em> version of this gem which is 0.2.1 as I am writing this. Some of the code under test uses the <code>IO</code> <code>each_line</code> method to iterate lines in relatively largish files. But we found out quickly that is a problem, since in version 0.2.1 the <code>FakeFS::File</code> class does not extend <code>StringIO</code> and so you don't get all its methods such as <code>each_line</code>. (The <a href="http://github.com/defunkt/fakefs/blob/master/lib/fakefs/file.rb">version on master in GitHub</a> as I write this does extend <code>StringIO</code>, but it is not yet released as a formal version.)

As an example suppose we have the following code that prints out the size of each line in a file as stars (asterisks):

<pre class="prettyprint">
def lines_to_stars(file_path)
  File.open(file_path, 'r').each_line { |line| puts '*' * line.size }
end
</pre>

<p>Let's say we use FakeFS to create a fake file like this:</p>

<pre class="prettyprint">
require 'fakefs/safe'
require 'stringio'

FakeFS.activate!

File.open('/tmp/foo.txt', 'w') do |f|
  f.write "The quick brown fox jumped over the lazy dog\n"
  f.write "The quick red fox jumped over the sleepy cat\n"
  f.write "Jack be nimble, Jack be quick, Jack jumped over the candle stick\n"
  f.write "Twinkle, twinkle little star, how I wonder what you are\n"
  f.write "The End."
end
</pre>

<p>So far, so good. But now if we call <code>lines_to_stars</code> we get an error:</p>

<pre class="prettyprint">
NoMethodError: undefined method `each_line' for #&lt;FakeFS::File:0x000001012c22b8&gt;
</pre>

<p>Oops. No <code>each_line</code>. If you don't want to use an unreleased version of the gem, you can add <code>each_line</code> onto FakeFS::File using the following code:</p>

<pre class="prettyprint">
module FakeFS
  class File
    def each_line
      File.readlines(self.path).each { |line| yield line }
    end
  end
end
</pre>

<p>Basically all it does is define <code>each_line</code> so that it reads all the lines from a (fake) file on the (fake) filesystem and then yields them up one by one, so you can have code under test that iterates a file and work as expected. So now calling <code>lines_to_stars</code> gives a nice pretty bar chart containing the line sizes represented by stars:</p>

<pre class="prettyprint">
********************************************
********************************************
***************************************************************
*******************************************************
********
</pre>

<p>Since we're using RSpec, to make this work nicely we added the above code that defines <code>each_line</code> into a file named <code>fakefs.rb</code> in the <code>spec/support</code> directory, since <code>spec_helper</code> requires supporting files in the <code>spec/support</code> directory and its subdirectories. So now all our specs automatically get the <code>each_line</code> behavior when using FakeFS.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Selenium Mojo : Protoype Bindings in Selenium</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_protoype_binding.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1726</id>

    <published>2010-04-24T18:00:36Z</published>
    <updated>2010-04-27T13:33:02Z</updated>

    <summary>IntroductionOn my current project we have been involved in converting some of the hundreds of manual tests that are run by our Test Team every release into a suite of...</summary>
    <author>
        <name>Stephen Mouring Jr.</name>
        
    </author>
    
        <category term="Groovy" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Web Development" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<font style="font-size: 1.25em;"><b>Introduction</b></font><br /><br />On my current project we have been involved in converting some of the hundreds of manual tests that are run by our Test Team every release into a suite of automated Selenium RC tests.<br /><br />During the course of this adventure my crew found several instances where XPath and native JavaScript were not sufficiently expressive to find elements in some of our more complicated interfaces. <br /><br />Since our web app uses the Prototype/Scriptaculous JavaScript framework we wanted to find a way to make the locating power of Prototype available within Selenium RC.<br /><br />We developed approaches for both Selenium 0.9.2 and Selenium 1.0.3 (which had better programmatic support for adding JavaScript user extensions to Selenium).<br /><br /><br /><font style="font-size: 1.25em;"><b>Selenium 0.9.2</b></font><br /><br />Selenium RC provides the capability to add "user extensions" to augment its JavaScript core. <br /><br />See <a href="http://seleniumhq.org/docs/08_user_extensions.html">http://seleniumhq.org/docs/08_user_extensions.html</a> for detailed information on how to set this up. <br /><br />We wrote the following user-extension.js file:<br /><br /><pre class="prettyprint">Selenium.prototype.setupProtoypeJS = function() {<br />&nbsp;&nbsp;&nbsp; id = selenium.browserbot.getCurrentWindow().$;<br />&nbsp;&nbsp;&nbsp; css = selenium.browserbot.getCurrentWindow().$$;<br />}</pre><br />In our code we have a base class for all our test cases. To this we added our own waitForPage() method:<br /><br /><pre class="prettyprint">public void waitForPage() {<br />&nbsp;&nbsp;&nbsp; selenium.waitForPage('60000')<br />&nbsp;&nbsp;&nbsp; proc.doCommand('setupPrototypeJS', [])<br />}</pre><br />Thus every time the page reloads (which clears the JavaScript context) we call waitForPage() and this command is re-executed. It creates two global variables (id and css) and binds them to Prototype's $ and $$ functions respectively.<br /><br /><i>Note: The reason we choose id and css instead of $ and $$ was that Groovy considers $ in Strings to be a special character and we would have had to escape it each time it was used</i>.<br /><br />The Prototype selectors can now be used in Selenium RC like this:<br /><br /><pre class="prettyprint">selenium.click("dom=id('foo')")<br />selenium.click("dom=css('.bar')")<br />selenium.click("dom=css('span.foo a.baz')")</pre><br /><i>Note: You still have to specify the dom locator type so Selenium RC will know to execute your locator string as JavaScript.&nbsp; <br /></i><br /><br /><font style="font-size: 1.25em;"><b>Selenium 1.0.3</b></font><br /><br />In more recent version of Selenium RC the project added the setExtensionJs() method. This allows you to set extension JavaScript programmatically prior to starting the selenium client:<br /><br /><pre class="prettyprint">selenium = new DefaultSelenium(...)<br />selenium.setExtensionJs('...')<br />selenium.start()</pre><br />This made it much easier to implement our Prototype bindings. The only trick was that the JavaScript seems to be executed prior to having access to a page context and is also only executed once. This required us to take a different approach.<br /><br />We created id and css as global functions instead of variables. This allowed us to defer accessing the current window until the functions were actually invoked. &nbsp; <br /><br /><pre class="prettyprint">selenium.setExtensionJs('''<br />        id = function(value) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    return selenium.browserbot.getCurrentWindow().$(value);<br /><div id=":w0" class="ii gt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; css = function(value) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return selenium.browserbot.<wbr>getCurrentWindow().$$(value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />''');</div></pre> <br /><i>Note: The above code snippet is written in Groovy which allows multiline Strings.<br /></i><br />The Prototype selectors are used in Selenium RC like before:<br /><br /><pre class="prettyprint">selenium.click("dom=id('foo')")<br />selenium.click("dom=css('.bar')")<br />selenium.click("dom=css('span.foo a.baz')")</pre><br /><br /><br />I would be interested in hearing feedback from anyone who has a chance to use this technique!<br />]]>
        
    </content>
</entry>

<entry>
    <title>ASP.AJAX 4 Templates Part 4 - jQuery, and Manual JSON Object Manipulation</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/aspajax_4_templates_part_4_-_j.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1724</id>

    <published>2010-04-10T18:03:06Z</published>
    <updated>2010-04-10T19:02:58Z</updated>

    <summary>This is part 4 of a multi-part series exploring building client side AJAX applications with ASP.Net AJAX 4 Templating and the WCF Data Services (aka ADO.Net Data Services, aka oData,...</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term=".NET" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="ajax" label="AJAX" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint" label="SharePoint" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint2010" label="SharePoint 2010" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>This is part 4 of a multi-part series exploring building client side AJAX applications with ASP.Net AJAX 4 Templating and the WCF Data Services (aka ADO.Net Data Services, aka oData, aka Astoria) in SharePoint 2010.</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2010/04/aspajax-4-templates-part-4-jquery-and.html';
 
        /* Digg */
        var diggIframe = document.createElement('iframe');
        diggIframe.setAttribute('src', 'http://digg.com/tools/diggthis.php?u=' + currentPageUrl);
        diggIframe.setAttribute('height', '80');
        diggIframe.setAttribute('width', '52');
        diggIframe.setAttribute('frameborder', '0');
        diggIframe.setAttribute('scrolling', 'no');
        diggIframe.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
 
        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);
 
        var div = document.createElement('div');
        div.appendChild(dotnetkicksLink);
        div.appendChild(document.createElement('br'));
        div.appendChild(diggIframe);
 
        document.write(div.innerHTML);
    </script>
</div>

<p>
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications.html">Part 1 - Exploring WCF Data Services in SharePoint 2010</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html">Part 2 - Creating a read-only page with ASP.Net AJAX 4.0 Templates</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html">Part 3 - Writing data back to SharePoint with ASP.Net AJAX 4.0 Templates</a><br/>
<a href="http://www.nearinfinity.com/blogs/lee_richardson/aspajax_4_templates_part_4_-_j.html">Part 4 - jQuery and Manual JSON Object Manipulation</a>
</p>

<p>In the previous posts in this series I've shown how you can access SharePoint data using WCF Data Services, how you can display that data using ASP.Net AJAX 4.0 Templates, and how you can write data back to SharePoint.</p>

<p>In this post I'll take writing data back to SharePoint a step further by showing how you can modify non-visible fields by modifying JSON objects directly.  More specifically I'll enable dragging user story index cards on a virtual bulletin board using a jQuery plugin, save the X and Y coordinates back to JSON objects, and then save the updated records back to SharePoint. </p>

<p><b>Cards on a Corkboard</b></p>

<p>The first thing I'll do is style the cards and display them with absolute position.  While I'm at it I'll also reference the <a href=" http://jqueryui.com/demos/droppable/ ">draggable</a> jQuery UI plugin.  If you're following along at home just built a custom .js download from the jQuery UI site, drop it in your layouts directory and add a reference.  So my PageHead content control now looks like this:</p>

<p class="MsoNormal"><span style="font-size:9.5pt;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;color:blue">&lt;</span><span style="font-size:9.5pt;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;color:maroon">asp</span><span style="font-size:9.5pt;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;color:blue">:</span><span style="font-size:9.5pt;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;color:maroon">content</span><span    style="font-size:9.5pt;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas">  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">id</span><span style="color:blue">=&quot;PageHead&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">contentplaceholderid</span><span style="color:blue">=&quot;PlaceHolderAdditionalPageHead&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;&gt;<br />  <br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjax.js&quot;&gt;&lt;/</span><span    style="color:maroon">script</span><span style="color:blue">&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjaxDataContext.js&quot;&gt;&lt;/</span><span    style="color:maroon">script</span><span style="color:blue">&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjaxTemplates.js&quot;&gt;&lt;/</span><span    style="color:maroon">script</span><span style="color:blue">&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjaxAdoNet.js&quot;&gt;&lt;/</span><span    style="color:maroon">script</span><span style="color:blue">&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">src</span><span style="color:blue">=&quot;../jquery-ui-1.8.custom/js/jquery-1.4.2.min.js&quot;&gt;&lt;/</span><span    style="color:maroon">script</span><span style="color:blue">&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:red">src</span><span style="color:blue">=&quot;../jquery-ui-1.8.custom/js/jquery-ui-1.8.custom.min.js&quot;&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;/</span><span style="color:maroon">script</span><span    style="color:blue">&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  <span style="color:blue">&lt;</span><span style="color:maroon">style</span>  <span style="color:red">type</span><span style="color:blue">=&quot;text/css&quot;&gt;<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:maroon">.sys-template<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>{<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">display</span>: <span style="color:blue">none</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  }<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:maroon">.userstorycard<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>{<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">border</span>: <span style="color:blue">1px</span>  <span style="color:blue">solid</span> <span style="color:blue">#777777</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">width</span>: <span style="color:blue">200px</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">position</span>: <span style="color:blue">  absolute</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">cursor</span>: <span style="color:blue">move</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  }<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:maroon">.carddescription<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>{<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">font-size</span>: <span style="color:blue">13px</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">background-image</span>: <span style="color:blue">  url(&#39;card_bg.jpg&#39;)</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">padding</span>: <span style="color:blue">0px</span>  <span style="color:blue">5px</span> <span style="color:blue">5px</span>  <span style="color:blue">5px</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  }<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  <span style="color:maroon">.cardtitle<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>{<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">font-size</span>: <span style="color:blue">15px</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">font-weight</span>: <span style="color:blue">bold</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">padding</span>: <span style="color:blue">0px</span>  <span style="color:blue">0px</span> <span style="color:blue">0px</span>  <span style="color:blue">0px</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">border-bottom</span>: <span style="color:blue">  1px</span> <span style="color:blue">solid</span> <span style="color:blue">red</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">background-color</span>: <span style="color:blue">  White</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color:red">padding</span>: <span style="color:blue">0px</span>  <span style="color:blue">5px</span> <span style="color:blue">0px</span>  <span style="color:blue">5px</span>;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>  }<br style="mso-special-character:line-break" />  <![if !supportLineBreakNewLine]>  <br style="mso-special-character:line-break" />  <![endif]><o:p></o:p></span> </p> <span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"><span style="mso-spacerun:yes"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...</span>

<p>The next thing to do is add X and Y fields to the user story list in SharePoint.  And finally display the cards with absolute positioning:</p>

<span style="font-size:10.0pt;line-height:115%;font-family:&quot;Courier New&quot;;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">&lt;</span><span style="font-size:10.0pt;line-height:115%;font-family:&quot;Courier New&quot;;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:#A31515;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">div</span><span style="font-size:10.0pt;line-height:115%;font-family:&quot;Courier New&quot;;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes"> <span style="color:#A31515">xmlns</span><span     style="color:blue">:</span><span style="color:red">sys</span><span     style="color:blue">=&quot;javascript:Sys&quot;</span> <span style="color:red">class</span><span     style="color:blue">=&quot;background&quot;&gt;<br />   </span><span style="mso-spacerun:yes">&nbsp; </span><span style="color:blue">&lt;</span><span     style="color:#A31515">div</span> <span style="color:red">id</span><span     style="color:blue">=&quot;userStories&quot;</span> <span style="color:red">class</span><span     style="color:blue">=&quot;sys-template&quot;&gt;<br />   </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span     style="color:#A31515">div</span> <span style="color:red">class</span><span     style="color:blue">=&quot;userStoryCard&quot;</span>   <br />   <span style="mso-spacerun:yes">&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</span><b     style="mso-bidi-font-weight:normal"><span style="color:#A31515">sys</span><span     style="color:blue">:</span><span style="color:red">style</span><span     style="color:blue">=&quot;</span>{{ &#39;<span style="color:red">left</span>:   <span style="color:blue">&#39; + X + &#39;px</span>; <span style="color:red">top</span>:   <span style="color:blue">&#39; + Y + &#39;px</span>;&#39;}}<span style="color:blue">&quot;&gt;<br />   <br />   </span></b><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">   &lt;</span><span style="color:#A31515">div</span> <span style="color:red">class</span><span     style="color:blue">=&quot;userStoryTitle&quot;&gt;</span>{{ Title }}<span     style="color:blue">&lt;/</span><span style="color:#A31515">div</span><span     style="color:blue">&gt;<br />   </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span><span style="color:blue">&lt;</span><span     style="color:#A31515">div</span> <span style="color:red">class</span><span     style="color:blue">=&quot;userStoryBody&quot;&gt;&lt;</span><span style="color:#A31515">div</span><span     style="color:blue">&gt;</span>{{ Description }}<span style="color:blue">&lt;/</span><span     style="color:#A31515">div</span><span style="color:blue">&gt;<br />   </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span     style="color:#A31515">div</span><span style="color:blue">&gt;<br />   </span><span style="mso-spacerun:yes">&nbsp; </span><span style="color:blue">&lt;/</span><span     style="color:#A31515">div</span><span style="color:blue">&gt;<br />   &lt;/</span><span style="color:#A31515">div</span><span style="color:blue">&gt;</span></span></p>

<p>Notice the sys:style attribute.  The sys: part is the namespace you need to add for attributes when using templating that I mentioned in <a href=" http://rapidapplicationdevelopment.blogspot.com/2010/03/client-side-ajax-applications-in_3617.html">part three</a>.  Also notice the JavaScript string concatenation inside the binding.  You can put in any JavaScript in there that you like.  So now if you manually set X and Y values in SharePoint for a card the card shows in the right place.  But we're still missing the ability to drag cards.</p>

<p><b>Making Cards Draggable with jQuery</b></p>

<p>In order to enable dragging support you're supposed to call the draggable() function on the DOM elements you want to make draggable.  Simple right?  You just call $(".userstorycard").draggable() which should find every element with a class of userstorycard and call draggable() on it.</p>

<p>But if you do this onLoad() then ASP.Net AJAX Templating engine hasn't had a chance to render the new DOM elements yet.  Fortunately the DataView has the JavaScript equivalent of an OnRendered event that you can tie into:</p>

<p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">function</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"> onLoad() {<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>dataContext = $create(<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Sys.Data.AdoNetDataContext,  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{ serviceUri:  <span style="color:maroon">&quot;/demoprep/_vti_bin/ListData.svc&quot;</span> }<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>);<br />  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>dataView = $create(<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Sys.UI.DataView,<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>autoFetch:  <span style="color:blue">true</span>,<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dataProvider: dataContext,<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fetchOperation:  <span style="color:maroon">&quot;UserStories&quot;</span>,<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fetchParameters: { $top: 20 }<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>},<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</span>rendered: onRendered<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>},<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;</span><span style="color:blue">null</span>,<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>$get(<span style="color:maroon">&#39;userStories&#39;</span>)<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>);<br />  }<br />  <br />  <span style="color:blue">function</span> onRendered() {<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:darkgreen">// from   http://jqueryui.com/demos/draggable/<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>$(<span style="color:maroon">&quot;.userstorycard&quot;</span>).draggable();<br />  }</span></p>

<p>And that's it for enabling dragging.  Pretty simple.  The result looks like this:</p>

<p><a href="http://1.bp.blogspot.com/_gez10dNhuPk/S8C5Crk0xAI/AAAAAAAABss/y3vsN5TbKQA/s1600/part4-1-screenshot.jpg"><img style="cursor:pointer; cursor:hand;width: 400px; height: 334px;" src="http://1.bp.blogspot.com/_gez10dNhuPk/S8C5Crk0xAI/AAAAAAAABss/y3vsN5TbKQA/s400/part4-1-screenshot.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5458566204081095682" /></a></p>

<p>Ok, well you can't see the dragging support, but it's there, trust me.  And it's pretty cool except for one thing.</p>

<p><b>Saving Non-Visible Properties</b></p>

<p>The problem is that every time you refresh the page the nice layout you've done disappears and everything goes back to being stacked one on top of the other in the upper left.  My first thought was to create input type=hidden form elements on the page.  This approach causes a lot more plumbing code than is necessary.  The better way is that you can access the underlying in-memory JSON objects.  Step one is to register an "event" for when the user stops dragging a card.</p>

<p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">function</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"> onRendered() {<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:darkgreen">// from   http://jqueryui.com/demos/draggable/<br />  </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>$(<span style="color:maroon">&quot;.userstorycard&quot;</span>).draggable({<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</span>stop: onDragStop<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>});<br />  }</span></p>

<p>Once you wire that up the onDragStop() function is where all the interesting stuff happens:</p>

<p><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">function</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:Consolas;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"> onDragStop(event, ui) {<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span>   userStoryCard = ui.helper[0];<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span>   selectedUserStoryJsonObject =  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</span>dataView.findContext(userStoryCard).dataItem;<br />  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span>   newX = ui.position.left;<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span>   newY = ui.position.top;<br />  <br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  Sys.Observer.setValue(selectedUserStoryJsonObject, <span style="color:maroon">  &quot;X&quot;</span>, newX);<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>  Sys.Observer.setValue(selectedUserStoryJsonObject, <span style="color:maroon">  &quot;Y&quot;</span>, newY);<br />  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>dataContext.saveChanges();<br />  }</span></p>

<p>The first line gets the DOM element that just the user just completed dragging.  The second line retrieves the in memory JSON object represented by that DOM element.  The next couple of lines get the X and Y that the user story card was dragged to relative to their parent DOM element.  And then something odd happens.</p>

<p>Sys.Observer.setValue looks so complicated.  Why couldn't we just call selectedUserStoryJsonObject.X = newX?</p>

<p>Well, if we'd done that the DataView wouldn't know about the change we just made.  If we then tried to call dataContext.saveChanges() nothing would get sent back to the server.  <a href=" http://msdn.microsoft.com/en-us/library/dd393596%28VS.100%29.aspx">Sys.Observer.setValue</a> notifies any interested parties, in this case the DataView, that a value has been changed.  And this enables the functionality we saw in <a href="">part two</a> where the DataView only sends the relevant records back to SharePoint instead of the entire set of JSON objects.</p>

<p>And so, with this code in place, we can now move user story cards around on the page and when we refresh the page or come back days later our layout has persisted back into SharePoint.</p>

<p><b>Conclusion</b></p>

<p>In this post you've seen how to directly modify the in-memory JSON objects and send them back to SharePoint.  Our application is finally getting interesting and I find it quite remarkable how little code it's taken.  In the next post I'll show how to do master-detail scenario's for editing user story cards.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Taking Polyglot Programming Further</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/jason_harwig/taking_polyglot_programming_fu.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.775</id>

    <published>2010-04-01T04:00:00Z</published>
    <updated>2010-03-29T18:55:11Z</updated>

    <summary><![CDATA[I consider polyglot programming to be using the best tool for the problem. Some languages are&nbsp;inherently&nbsp;better at solving certain types of problems. We should embrace these advantages and switch freely...]]></summary>
    <author>
        <name>Jason Harwig</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>I consider polyglot programming to be using the best tool for the problem. Some languages are&nbsp;inherently&nbsp;better at solving certain types of problems. We should embrace these advantages and switch freely between languages.

<p>Today, we are introducing Hydra, the meta-language that runs on the JVM. Hydra supports (and encourages!) any JVM-based language at any time in the file.

<p>Example: Person.hyrdra

<pre class="prettyprint">:groovy
class Person {

  :ruby
  # define properties
  attr_accessor :first_name, :last_name

  :python
  """ 
    Get the full name by concatenating first, last
  """
  def full_name (self):
    print "%s %s" % (self.first_name, self.last_name)

  :java
  /**
   * Set the firstName attribute to name. (Useless javadoc)
   *
   * @param name the new first name value
   */
  public void setFirstName(String name) {
      String prefix = "Setting first name to ";

      :clojure
      (print prefix)
      (defn printChar [c] (print c))

      :javascript
      name.forEach(printChar);<br />
      :java
      this.firstName = name;      
  }

  // Switch to python so ending '}' isn't needed ;)
  :python</pre>

<p>Sent from my iPad]]>
        
    </content>
</entry>

<entry>
    <title>Client Side AJAX Applications in SharePoint 2010 - Part 3</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1717</id>

    <published>2010-03-22T02:17:25Z</published>
    <updated>2010-04-10T19:06:05Z</updated>

    <summary> Note: This is one of a multi-part series exploring building client side AJAX applications with ASP.Net AJAX 4 Templating and the WCF Data Services (aka ADO.Net Data Services, aka...</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term=".NET" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="adonetdataservices" label="ADO.Net Data Services" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint" label="SharePoint" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint2010" label="SharePoint 2010" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[ <p>Note: This is one of a multi-part series exploring building client side AJAX applications with ASP.Net AJAX 4 Templating and the WCF Data Services (aka ADO.Net Data Services, aka oData, aka Astoria) in SharePoint 2010.</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2010/03/client-side-ajax-applications-in_3617.html';

        /* Digg */
        var diggIframe = document.createElement('iframe');
        diggIframe.setAttribute('src', 'http://digg.com/tools/diggthis.php?u=' + currentPageUrl);
        diggIframe.setAttribute('height', '80');
        diggIframe.setAttribute('width', '52');
        diggIframe.setAttribute('frameborder', '0');
        diggIframe.setAttribute('scrolling', 'no');
        diggIframe.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');

        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);

        var div = document.createElement('div');
        div.appendChild(dotnetkicksLink);
        div.appendChild(document.createElement('br'));
        div.appendChild(diggIframe);

        document.write(div.innerHTML);
    </script>
</div>

<p>
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications.html">Part 1 - Exploring WCF Data Services in SharePoint 2010</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html">Part 2 - Creating a read-only page with ASP.Net AJAX 4.0 Templates</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html">Part 3 - Writing data back to SharePoint with ASP.Net AJAX 4.0 Templates</a><br/>
<a href="http://www.nearinfinity.com/blogs/lee_richardson/aspajax_4_templates_part_4_-_j.html">Part 4 - jQuery and Manual JSON Object Manipulation</a>
</p>

<p>In the previous two posts in this series I've shown how you can access SharePoint data using WCF Data Services and consume that data using ASP.Net AJAX 4 templates.  In this post I'll update the previous example in order to show how to write data back to SharePoint.</p>
<p><b>Templates and Linking</b></p>
<p>Before we go into writing data back let's modify our example to link each item back to the SharePoint DispForm.aspx page.  A naïve approach would look like this:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:maroon;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">ul</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA"> <span style="color:red">id</span><span style="color:blue">=&quot;userStoriesList&quot;</span>
 <span style="color:red">class</span><span style="color:blue">=&quot;sys-template&quot;&gt;<br />
 </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">li</span><span style="color:blue">&gt;&lt;</span><span 
  style="color:maroon">a</span> <span style="color:red">href</span><span 
  style="color:blue">=&quot;../../Lists/User%20Stories/DispForm.aspx?ID={{ID}}&quot;&gt;</span>{{ 
 Title }}<span style="color:blue">&lt;/</span><span style="color:maroon">a</span><span 
  style="color:blue">&gt;&lt;/</span><span style="color:maroon">li</span><span 
  style="color:blue">&gt;<br />
 &lt;/</span><span style="color:maroon">ul</span><span style="color:blue">&gt;</span></span></p>

<p>It turns out this approach doesn't work because the DataView won't look for the data binding syntax inside of attributes.  The next approach that might make sense would now be to set href to a data binding syntax and inside there do some string concatenation like so:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:maroon;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">li</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&gt;&lt;</span><span style="font-size:9.5pt;
line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;color:maroon;mso-ansi-language:EN-US;
mso-fareast-language:EN-US;mso-bidi-language:AR-SA">a</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA"> <span style="color:red">href</span><span 
  style="color:blue">=&quot;{{ &#39;../../Lists/User%20Stories/DispForm.aspx?ID=&#39; + ID 
 }}&quot;&gt;</span>{{ Title }}<span style="color:blue">&lt;/</span><span 
  style="color:maroon">a</span><span style="color:blue">&gt;&lt;/</span><span 
  style="color:maroon">li</span><span style="color:blue">&gt;</span></span></p>

<p>It turns out this doesn't work either, but for a different reason.  Apparently the DataView can't natively convert some HTML attributes like href and src for reasons <a href=" http://weblogs.asp.net/bleroy/archive/2008/07/30/using-client-templates-part-1.aspx">Bertrand La Roy</a> describes.  The solution is to prefix the attribute with the ASP.Net AJAX system namespace.  Typically you would define the system namespace on the HTML body element.  But with SharePoint you don't have access to this element.  Fortunately you can declare this namespace on any element so the following code works:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:maroon;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">div</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA"> <span style="color:red">xmlns</span><span style="color:blue">:</span><span 
  style="color:red">sys</span><span style="color:blue">=&quot;javascript:Sys&quot;&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="color:maroon">ul</span>
 <span style="color:red">id</span><span style="color:blue">=&quot;userStoriesList&quot;</span>
 <span style="color:red">class</span><span style="color:blue">=&quot;sys-template&quot;&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">li</span><span style="color:blue">&gt;&lt;</span><span 
  style="color:maroon">a</span> <span style="color:red">sys</span><span 
  style="color:blue">:</span><span style="color:red">href</span><span 
  style="color:blue">=&quot;{{ &#39;../../Lists/User%20Stories/DispForm.aspx?ID=&#39; + ID 
 }}&quot;&gt;</span>{{ Title }}<span style="color:blue">&lt;/</span><span 
  style="color:maroon">a</span><span style="color:blue">&gt;&lt;/</span><span 
  style="color:maroon">li</span><span style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span style="color:maroon">ul</span><span 
  style="color:blue">&gt;<br />
 &lt;/</span><span style="color:maroon">div</span><span style="color:blue">&gt;</span></span></p>

<p>Great.  Let's move on to updating data.</p>

<p><b>Live Binding Syntax</b></p>
<p>The {{ }} template syntax we've seen so far is what's known as one time binding.  When you use this syntax the expression is evaluated only once when the template is rendered.  What we want is one way live binding and/or two way live binding.</p>

<p>In order to understand the live bindings you need to understand that behind the scenes the DataView keeps an in memory copy of all of the JSON objects it downloads.  It's possible for the data in these objects to change.  And that's where one way live bindings come in.  When you use the syntax { binding [FieldName] }, the DataView will automatically update the binding when the underlying JSON object changes.</p>

<p>Two way live binding happens automatically when you use the one way live binding syntax on HTML INPUT elements.  For these scenarios the DataView automatically updates the in memory JSON objects.  Then the DataView updates any one way live binding's.</p>

<p>So let's throw two DataViews onto the page, one with one way live bound hyperlinks, one with two way bound HTML INPUT textbox elements and see what happens:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:maroon;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">script</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA"> <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">
 function</span> pageInit() {<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span> 
 dataContext = $create(Sys.Data.AdoNetDataContext, { serviceUri:
 <span style="color:maroon">&quot;/demoprep/_vti_bin/ListData.svc&quot;</span> });<br />
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>$create(Sys.UI.DataView,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>{<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>autoFetch:
 <span style="color:blue">true</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>dataProvider: 
 dataContext,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>fetchOperation:
 <span style="color:maroon">&quot;UserStories&quot;</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>fetchParameters: { 
 $top: 20 }<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>},<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:blue">null</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:blue">null</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>$get(<span 
  style="color:maroon">&quot;userStoriesList&quot;</span>)<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>);<br />
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>$create(Sys.UI.DataView,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>{<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>autoFetch:
 <span style="color:blue">true</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>dataProvider: 
 dataContext,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>fetchOperation:
 <span style="color:maroon">&quot;UserStories&quot;</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>fetchParameters: { 
 $top: 20 }<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>},<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:blue">null</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:blue">null</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>$get(<span 
  style="color:maroon">&quot;userStoriesTable&quot;</span>)<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>);<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>}<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>Sys.Application.add_init(pageInit);<br />
 <span style="color:blue">&lt;/</span><span style="color:maroon">script</span><span 
  style="color:blue">&gt;</span><br />
 <br />
 <span style="color:blue">&lt;</span><span style="color:maroon">div</span>
 <span style="color:red">xmlns</span><span style="color:blue">:</span><span 
  style="color:red">sys</span><span style="color:blue">=&quot;javascript:Sys&quot;&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">ul</span> <span style="color:red">id</span><span 
  style="color:blue">=&quot;userStoriesList&quot;</span> <span style="color:red">class</span><span 
  style="color:blue">=&quot;sys-template&quot;&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">li</span><span style="color:blue">&gt;&lt;</span><span 
  style="color:maroon">a</span> <span style="color:red">sys</span><span 
  style="color:blue">:</span><span style="color:red">href</span><span 
  style="color:blue">=&quot;{{ &#39;../../Lists/User%20Stories/DispForm.aspx?ID=&#39; + ID 
 }}&quot;&gt;</span>{ binding Title }<span style="color:blue">&lt;/</span><span 
  style="color:maroon">a</span><span style="color:blue">&gt;&lt;/</span><span 
  style="color:maroon">li</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp; &nbsp;&nbsp;</span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">ul</span><span style="color:blue">&gt;</span><br />
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">table</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">thead</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">tr</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">td</span><span style="color:blue">&gt;</span>Title<span 
  style="color:blue">&lt;/</span><span style="color:maroon">td</span><span 
  style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">tr</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">thead</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">tbody</span> <span style="color:red">id</span><span 
  style="color:blue">=&quot;userStoriesTable&quot;</span> <span style="color:
red">class</span><span style="color:blue">=&quot;sys-template&quot;&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">tr</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">td</span><span style="color:blue">&gt;&lt;</span><span 
  style="color:maroon">input</span> <span style="color:red">type</span><span 
  style="color:blue">=&quot;text&quot;</span> <span style="color:red">sys</span><span 
  style="color:blue">:</span><span style="color:red">value</span><span 
  style="color:blue">=&quot;{binding Title}&quot;</span> <span style="color:blue">/&gt;&lt;/</span><span 
  style="color:maroon">td</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">tr</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">tbody</span><span style="color:blue">&gt;</span><br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">table</span><span style="color:blue">&gt;</span><br />
 <span style="color:blue">&lt;/</span><span style="color:maroon">div</span><span 
  style="color:blue">&gt;</span></span></p>

<p>Notice the input element with the sys:value bound to title and the new binding syntax in the text of the a href.  The result looks like this:</p>

<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gez10dNhuPk/S6bMoFgda1I/AAAAAAAABsk/LwN6UrGi--g/s1600-h/part3-1-endresult.gif"><img style="cursor:pointer; cursor:hand;width: 269px; height: 400px;" src="http://2.bp.blogspot.com/_gez10dNhuPk/S6bMoFgda1I/AAAAAAAABsk/LwN6UrGi--g/s400/part3-1-endresult.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5451269388023720786" /></a></p>

<p>It may not be all that pretty yet, but if you change the text in any of the text boxes the result is immediately updated in the hyperlinks on mouse out.  But if you hop back to SharePoint or refresh the page you'll see that our data hasn't been updated.</p>
<p><b>Updating SharePoint, For Real This Time</b></p>
<p>Just because the DataView updated the in memory JSON objects it's bound to doesn't mean it sent a POST request back to ListData.svc.  To accomplish that we need to call dataContext.saveChanges().  If you toss in a button below the table like this:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:maroon;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">button</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA"> <span style="color:red">onclick</span><span style="color:blue">=&quot;dataContext.saveChanges()&quot;&gt;</span>Save 
 Changes<span style="color:blue">&lt;/</span><span style="color:maroon">button</span><span 
  style="color:blue">&gt;</span></span></p>

<p>And move the dataContext variable to a higher scope like this:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">var</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA"> dataContext;<br />
 <br />
 <span style="color:blue">function</span> onLoad() {<br />
 <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dataContext = 
 $create(Sys.Data.AdoNetDataContext, { serviceUri: <span style="color:maroon">
 &quot;/demoprep/_vti_bin/ListData.svc&quot;</span> });</span></p>

<p>Then when you click the button the AdoNetDataContext figures out which JSON objects changed and sends just those objects back to ListData.svc.  How do you know it only sends the rows that changed?  If you look at Fiddler there will be a POST to ListData.svc/$batch with something like the following:</p>

<p><span class="style1" 
  style="font-size: 11.0pt; line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: &quot;Times New Roman&quot;; mso-bidi-theme-font: minor-bidi; mso-themecolor: background1; mso-style-textfill-fill-color: white; mso-style-textfill-fill-themecolor: background1; mso-style-textfill-fill-alpha: 100.0%; mso-style-textfill-fill-colortransforms: lumm=50000; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">
 --batch_d425-6668-6b05<br />
 Content-Type: multipart/mixed;boundary=changeset_8a05-bdcd-0b3e<br />
 --changeset_8a05-bdcd-0b3e<br />
 Content-Type: application/http<br />
 Content-Transfer-Encoding: binary<br />
 MERGE http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(3) HTTP/1.1<br />
 If-Match: W/&quot;3&quot;<br />
 Host: localhost<br />
 Accept: application/json<br />
 Accept-Charset: utf-8<br />
 Content-Type: application/json;charset=utf-8</span><span style="font-size:11.0pt;line-height:115%;
font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:&quot;Times New Roman&quot;;mso-bidi-theme-font:minor-bidi;
color:white;mso-themecolor:background1;mso-style-textfill-fill-color:white;
mso-style-textfill-fill-themecolor:background1;mso-style-textfill-fill-alpha:
100.0%;mso-style-textfill-fill-colortransforms:lumm=50000;mso-ansi-language:
EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA"><br />
 </span>
 <span style="font-size:9.5pt;line-height:115%;font-family:Consolas;
mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:
EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA">{<br />
 <span style="color:maroon">&quot;__metadata&quot;</span>:{<span style="color:maroon">&quot;uri&quot;</span>:<span 
  style="color:maroon">&quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(3)&quot;</span>,<br />
 <span style="color:maroon">&quot;etag&quot;</span>:<span style="color:maroon">&quot;W/\&quot;3\&quot;&quot;</span>,<br />
 <span style="color:maroon">&quot;type&quot;</span>:<span style="color:maroon">&quot;Microsoft.SharePoint.DataService.UserStoriesItem&quot;</span>},<br />
 <span style="color:maroon">&quot;ContentTypeID&quot;</span>:<span style="color:maroon">&quot;0x01080070E2807D369BD94FBD6C057D3110E6D3&quot;</span>,<br />
 <span style="color:maroon">&quot;Title&quot;</span>:<span style="color:maroon">&quot;Renamed 
 Task&quot;</span>,<br />
 <span style="color:maroon">&quot;Predecessors&quot;</span>:{<span style="color:maroon">&quot;__deferred&quot;</span>:{<span 
  style="color:maroon">&quot;uri&quot;</span>:<span style="color:maroon">&quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(3)/Predecessors&quot;</span>}},<br />
 <span style="color:maroon">&quot;Priority&quot;</span>:{<span style="color:
maroon">&quot;__deferred&quot;</span>:{<span style="color:maroon">&quot;uri&quot;</span>:<span 
  style="color:maroon">&quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(3)/Priority&quot;</span>}},<br />
 <span style="color:maroon">&quot;PriorityValue&quot;</span>:<span style="color:maroon">&quot;(2) 
 Normal&quot;</span>,<br />
 <span style="color:maroon">&quot;Status&quot;</span>:{<span style="color:maroon">&quot;__deferred&quot;</span>:{<span 
  style="color:maroon">&quot;uri&quot;</span>:<span style="color:maroon">&quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(3)/Status&quot;</span>}},<br />
 <span style="color:maroon">&quot;StatusValue&quot;</span>:<span style="color:maroon">&quot;Not 
 Started&quot;</span>,<br />
 <span style="color:maroon">&quot;Complete&quot;</span>:<span style="color:blue">null</span>,<br />
 <span style="color:maroon">&quot;AssignedToID&quot;</span>:<span style="color:blue">null</span>,<br />
 <span style="color:maroon">&quot;TaskGroupID&quot;</span>:<span style="color:blue">null</span>,<br />
 <span style="color:maroon">&quot;Description&quot;</span>:<span style="color:maroon">&quot;&lt;div&gt;&lt;/div&gt;&quot;</span>,<br />
 <span style="color:maroon">&quot;StartDate&quot;</span>:<span style="color:
maroon">&quot;\/Date(1266624000000)\/&quot;</span>,<br />
 <span style="color:maroon">&quot;DueDate&quot;</span>:<span style="color:blue">null</span>,<br />
 <span style="color:maroon">&quot;Points&quot;</span>:8,<br />
 <span style="color:maroon">&quot;Iteration&quot;</span>:{<span style="color:maroon">&quot;__deferred&quot;</span>:{<span 
  style="color:maroon">&quot;uri&quot;</span>:<span style="color:maroon">&quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(3)/Iteration&quot;</span>}},<br />
 <span style="color:maroon">&quot;IterationID&quot;</span>:1,<br />
 <span style="color:maroon">&quot;ID&quot;</span>:3,<br />
 <span style="color:maroon">&quot;ContentType&quot;</span>:<span style="color:maroon">&quot;Task&quot;</span>,<br />
 <span style="color:maroon">&quot;Modified&quot;</span>:<span style="color:maroon">&quot;\/Date(1269128451000)\/&quot;</span>,<br />
 <span style="color:maroon">&quot;Created&quot;</span>:<span style="color:maroon">&quot;\/Date(1266679964000)\/&quot;</span>,<br />
 <span style="color:maroon">&quot;CreatedByID&quot;</span>:1,<br />
 <span style="color:maroon">&quot;ModifiedByID&quot;</span>:1,<br />
 <span style="color:maroon">&quot;Owshiddenversion&quot;</span>:3,<br />
 <span style="color:maroon">&quot;Version&quot;</span>:<span style="color:maroon">&quot;3.0&quot;</span>,<br />
 <span style="color:maroon">&quot;Attachments&quot;</span>:{<span style="color:maroon">&quot;__deferred&quot;</span>:{<span 
  style="color:maroon">&quot;uri&quot;</span>:<span style="color:maroon">&quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(3)/Attachments&quot;</span>}},<br />
 <span style="color:maroon">&quot;Path&quot;</span>:<span style="color:maroon">&quot;/demoprep/Lists/User 
 Stories&quot;</span><br />
 }<br />
 </span><span class="style1" 
  style="font-size: 11.0pt; line-height: 115%; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: &quot;Times New Roman&quot;; mso-bidi-theme-font: minor-bidi; mso-style-textfill-fill-color: #000000; mso-style-textfill-fill-alpha: 100.0%; mso-style-textfill-fill-colortransforms: &quot;lumm=60000 lumo=40000&quot;; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">
 --changeset_8a05-bdcd-0b3e--<br />
 --batch_d425-6668-6b05--</span></p>

<p>And that, as you may have noticed, is the JSON for just a single of the rows that we were displaying.</p>
<p>But how did the AdoNetDataContext know which objects were changed?  <a href=" http://lostintangent.com/2009/06/ ">Jonathan Carter</a> explains this better than I could but basically when the data context downloads JSON objects it injects them with the ability to notify itself when they change.  As Jonathan points out it's a neat trick that would not be possible in a statically typed language.</p>
<p><b>Summary</b></p>
<p>We've finally gotten to some of the core benefits of using ASP.Net AJAX 4 Templating.  With very little JavaScript we were able to cleanly separate our UI from our data access code and write data back to the server.  And the amount of HTTP traffic and server operations was kept to a bare minimum, keeping things as fast and responsive as possible.  So all we're missing at this point is how to use it to make something real out of these technologies.  And that will be the topic for the <a href="http://www.nearinfinity.com/blogs/lee_richardson/aspajax_4_templates_part_4_-_j.html">next post</a>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Client Side AJAX Applications in SharePoint 2010 - Part 2</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1716</id>

    <published>2010-03-22T00:36:54Z</published>
    <updated>2010-03-22T02:22:50Z</updated>

    <summary>Note: This is one of a multi-part series exploring building client side AJAX applications with ASP.Net AJAX 4 Templating and the WCF Data Services (aka ADO.Net Data Services, aka oData,...</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term=".NET" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="adonetdataservices" label="ADO.Net Data Services" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="astoria" label="Astoria" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint" label="SharePoint" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint2010" label="SharePoint 2010" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>Note: This is one of a multi-part series exploring building client side AJAX applications with ASP.Net AJAX 4 Templating and the WCF Data Services (aka ADO.Net Data Services, aka oData, aka Astoria) in SharePoint 2010.</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2010/03/client-side-ajax-applications-in_21.html';

        /* Digg */
        var diggIframe = document.createElement('iframe');
        diggIframe.setAttribute('src', 'http://digg.com/tools/diggthis.php?u=' + currentPageUrl);
        diggIframe.setAttribute('height', '80');
        diggIframe.setAttribute('width', '52');
        diggIframe.setAttribute('frameborder', '0');
        diggIframe.setAttribute('scrolling', 'no');
        diggIframe.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');

        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);

        var div = document.createElement('div');
        div.appendChild(dotnetkicksLink);
        div.appendChild(document.createElement('br'));
        div.appendChild(diggIframe);

        document.write(div.innerHTML);
    </script>
</div>


<p>
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications.html">Part 1 - Exploring WCF Data Services in SharePoint 2010</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html">Part 2 - Creating a read-only page with ASP.Net AJAX 4.0 Templates</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html">Part 3 - Writing data back to SharePoint with ASP.Net AJAX 4.0 Templates</a>
</p>

<p>In <a href="http://rapidapplicationdevelopment.blogspot.com/2010/03/client-side-ajax-applications-in.html">Part 1</a> I described how SharePoint 2010 exposes list data through ListData.svc and WCF Data Services.  So far this is interesting, but the next logical question is how would you actually build a Web 2.0 application with the data?  One answer is with a new technology called ASP.Net AJAX 4.0 Client Side Templating.  I'll give you some background and then provide a walkthrough of how to build a SharePoint application page that reads and writes data to SharePoint through ListData.svc.</p>
<p><b>What is ASP.Net AJAX 4.0 Client Side Templating?</b></p>
<p>In Part 1 I talked about some of the problems with the two existing ways of writing Web 2.0 interfaces.  ASP.Net AJAX 4.0 Client Side Templating addresses most of these issues.  Specifically it:</p>

<ul>
<li>Minimizes plumbing code</li>
<li>Cleanly separates presentation from data access code</li>
<li>Simplifies saving data back to the server via Live Data Bindings</li>
<li>Has no ViewState!</li>
<li>Uses lightweight JSON rather than HTML</li>
</ul>

<p>Sounds good?  Ready to see some code?</p>
<p><b>Show Me The Code</b></p>
<p>Note: This walkthrough assumes you haven't played with Visual Studio 2010 and SharePoint 2010, so please skip ahead to "No Really, Show Me the AJAX Templating Code" if you've already seen the sweet SharePoint and Visual Studio integration.</p>
<p>To get started open Visual Studio 2010.  Select New Project and for the template navigate to SharePoint then 2010 select "Empty SharePoint Project" (p.s. see <a href=" http://httpcode.com/blogs/PermaLink,guid,357e4853-9a75-4962-ad68-1e07bcf40bb8.aspx">Visual Web Part</a> in the list?  Make sure you look that up if you haven't heard of it yet).</p>


<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gez10dNhuPk/S6akfBI5uSI/AAAAAAAABr8/XZ97uHe4fIY/s1600-h/part2-1-vstemplates.gif"><img style="cursor:pointer; cursor:hand;width: 400px; height: 306px;" src="http://2.bp.blogspot.com/_gez10dNhuPk/S6akfBI5uSI/AAAAAAAABr8/XZ97uHe4fIY/s400/part2-1-vstemplates.gif" border="0" alt=""id="Img2" /></a>


<p>If you haven't been keeping up with what's new in SharePoint 2010 you should immediately notice that SharePoint integration is built into Visual Studio 2010 out of the box just based on the listed templates.  But just wait, it gets much better. </p>

<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gez10dNhuPk/S6akfS6krBI/AAAAAAAABsE/0hTDT72N8Gc/s1600-h/part2-2-specifysite.gif"><img style="cursor:pointer; cursor:hand;width: 400px; height: 317px;" src="http://2.bp.blogspot.com/_gez10dNhuPk/S6akfS6krBI/AAAAAAAABsE/0hTDT72N8Gc/s400/part2-2-specifysite.gif" border="0" alt=""id="Img4" /></a>


<p>The next screen asks what site you want to use for debugging.  It's asking this because when you hit F5 ("Start Debugging") Visual Studio 2010 packages up your wsp file, deployes it to the URL you enter here, attaches to the w3wp process, and opens a browser into SharePoint, and you're immediately in debug mode!  </p>
<p>If you aren't deeply impressed then you haven't developed in WSS 3.0.  Now we aren't writing any server side code in this tutorial, but it's still extremely impressive how much work Microsoft has put into making SharePoint a first class citizen.</p>
<p>Once you have your site select Project -> Add New Item and select Application Page.</p>


<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_gez10dNhuPk/S6akfkNRsFI/AAAAAAAABsM/5kPkOSkDPRM/s1600-h/part2-3-addnewitem.gif"><img style="cursor:pointer; cursor:hand;width: 400px; height: 323px;" src="http://4.bp.blogspot.com/_gez10dNhuPk/S6akfkNRsFI/AAAAAAAABsM/5kPkOSkDPRM/s400/part2-3-addnewitem.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5451225261180825682" /></a>

<p>Visual Studio then plops out a page that's 100% ready to go including the correct Content controls for the SharePoint master page.</p>

<p><span style="font-size: 9.5pt; line-height: 115%; font-family: Consolas; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; background: yellow; mso-highlight: yellow; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">
 &lt;%</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;
mso-fareast-language:EN-US;mso-bidi-language:AR-SA">@</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA"> <span style="color:maroon">Assembly</span>
 <span style="color:red">Name</span><span style="color:blue">=&quot;$SharePoint.Project.AssemblyFullName$&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <span style="background: yellow; mso-highlight: yellow">&lt;%</span><span 
  style="color:blue">@</span> <span style="color:maroon">Import</span>
 <span style="color:red">Namespace</span><span style="color:blue">=&quot;Microsoft.SharePoint.ApplicationPages&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <span style="background: yellow; mso-highlight: yellow">&lt;%</span><span 
  style="color:blue">@</span> <span style="color:maroon">Register</span>
 <span style="color:red">Tagprefix</span><span style="color:blue">=&quot;SharePoint&quot;</span>
 <span style="color:red">Namespace</span><span style="color:blue">=&quot;Microsoft.SharePoint.WebControls&quot;</span>
 <span style="color:red">Assembly</span><span style="color:blue">=&quot;Microsoft.SharePoint, 
 Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <span style="background: yellow; mso-highlight: yellow">&lt;%</span><span 
  style="color:blue">@</span> <span style="color:maroon">Register</span>
 <span style="color:red">Tagprefix</span><span style="color:blue">=&quot;Utilities&quot;</span>
 <span style="color:red">Namespace</span><span style="color:blue">=&quot;Microsoft.SharePoint.Utilities&quot;</span>
 <span style="color:red">Assembly</span><span style="color:blue">=&quot;Microsoft.SharePoint, 
 Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <span style="background: yellow; mso-highlight: yellow">&lt;%</span><span 
  style="color:blue">@</span> <span style="color:maroon">Register</span>
 <span style="color:red">Tagprefix</span><span style="color:blue">=&quot;asp&quot;</span>
 <span style="color:red">Namespace</span><span style="color:blue">=&quot;System.Web.UI&quot;</span>
 <span style="color:red">Assembly</span><span style="color:blue">=&quot;System.Web.Extensions, 
 Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <span style="background: yellow; mso-highlight: yellow">&lt;%</span><span 
  style="color:blue">@</span> <span style="color:maroon">Import</span>
 <span style="color:red">Namespace</span><span style="color:blue">=&quot;Microsoft.SharePoint&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <span style="background: yellow; mso-highlight: yellow">&lt;%</span><span 
  style="color:blue">@</span> <span style="color:maroon">Assembly</span>
 <span style="color:red">Name</span><span style="color:blue">=&quot;Microsoft.Web.CommandUI, 
 Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <span style="background: yellow; mso-highlight: yellow">&lt;%</span><span 
  style="color:blue">@</span> <span style="color:maroon">Page</span>
 <span style="color:red">Language</span><span style="color:blue">=&quot;C#&quot;</span>
 <span style="color:red">AutoEventWireup</span><span style="color:blue">=&quot;true&quot;</span>
 <span style="color:red">CodeBehind</span><span style="color:blue">=&quot;ApplicationPage1.aspx.cs&quot;</span>
 <span style="color:red">Inherits</span><span style="color:blue">=&quot;MyAppPage.Layouts.MyAppPage.ApplicationPage1&quot;</span>
 <span style="color:red">DynamicMasterPageFile</span><span style="color:blue">=&quot;~masterurl/default.master&quot;</span>
 <span style="background: yellow; mso-highlight: yellow">%&gt;</span><br />
 <br />
 <span style="color:blue">&lt;</span><span style="color:maroon">asp</span><span 
  style="color:blue">:</span><span style="color:maroon">Content</span>
 <span style="color:red">ID</span><span style="color:blue">=&quot;PageHead&quot;</span>
 <span style="color:red">ContentPlaceHolderID</span><span style="color:blue">=&quot;PlaceHolderAdditionalPageHead&quot;</span>
 <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;&gt;<br />
 <br />
 &lt;/</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
  style="color:maroon">Content</span><span style="color:blue">&gt;<br />
 <br />
 &lt;</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
  style="color:maroon">Content</span> <span style="color:red">ID</span><span 
  style="color:blue">=&quot;Main&quot;</span> <span style="color:red">
 ContentPlaceHolderID</span><span style="color:blue">=&quot;PlaceHolderMain&quot;</span>
 <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;&gt;<br />
 </span>Hello World!<br />
 <span style="color:blue">&lt;/</span><span style="color:maroon">asp</span><span 
  style="color:blue">:</span><span style="color:maroon">Content</span><span 
  style="color:blue">&gt;<br />
 <br />
 &lt;</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
  style="color:maroon">Content</span> <span style="color:red">ID</span><span 
  style="color:blue">=&quot;PageTitle&quot;</span> <span style="color:red">
 ContentPlaceHolderID</span><span style="color:blue">=&quot;PlaceHolderPageTitle&quot;</span>
 <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;&gt;<br />
 </span>Application Page<br />
 <span style="color:blue">&lt;/</span><span style="color:maroon">asp</span><span 
  style="color:blue">:</span><span style="color:maroon">Content</span><span 
  style="color:blue">&gt;<br />
 <br />
 &lt;</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
  style="color:maroon">Content</span> <span style="color:red">ID</span><span 
  style="color:blue">=&quot;PageTitleInTitleArea&quot;</span> <span style="color:red">
 ContentPlaceHolderID</span><span style="color:blue">=&quot;PlaceHolderPageTitleInTitleArea&quot;</span>
 <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;</span>
 <span style="color:blue">&gt;<br />
 </span>My Application Page<br />
 <span style="color:blue">&lt;/</span><span style="color:maroon">asp</span><span 
  style="color:blue">:</span><span style="color:maroon">Content</span><span 
  style="color:blue">&gt;</span></span></p>

<p>(ok, the "Hello World!" is mine).  Now if you hit F5 or click Build -> "Deploy Solution" then as I mentioned SharePoint packages up the application page into a wsp file and deployes it out to SharePoint.  Now if you navigate to your application page (in my case http://localhost/mysite/_layouts/MyAppPage/ApplicationPage1.aspx) then you should see something like this:</p>

<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gez10dNhuPk/S6akgCoo_CI/AAAAAAAABsU/ccLTEAhinWQ/s1600-h/part2-4-helloworld.gif"><img style="cursor:pointer; cursor:hand;width: 400px; height: 286px;" src="http://1.bp.blogspot.com/_gez10dNhuPk/S6akgCoo_CI/AAAAAAAABsU/ccLTEAhinWQ/s400/part2-4-helloworld.gif" border="0" alt=""id="Img3" /></a>

<p>Amazed?  You should be.  We didn't write a line of evil looking CAML, didn't have to write any DOS batch files, didn't have to deploy to the GAC, we probably didn't even notice that a feature.xml file was created behind the scenes.  Yet already we're deployed!  Ok, enough exuberance, back to business.</p>

<p><b>No Really, Show Me the AJAX Templating Code</b></p>
<p>Before writing code you should probably create some lists to read and write to.  As I mentioned in a previous post I like <a href=" http://rapidapplicationdevelopment.blogspot.com/2010/02/video-how-to-create-burndown-charts-for.html ">tracking user stories in SharePoint</a>.  So for my examples I have an Iterations list and a User Stories list, which is based off of the Tasks content type (automatically giving you a number of columns like Priority).</p>
<p>After creating some lists you need to ensure you have the latest <a href=" http://ajax.codeplex.com/releases/view/35895 ">ASP.Net Ajax Library</a>.  I suspect an updated copy will be included with the RTM copy of SharePoint 2010, but in my case I downloaded the latest copy and moved the entire Scripts directory into C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ajax.  Note that out of the box SharePoint 2010 already included some of these files in LAYOUTS, but it was missing others, so this step was necessary.</p>
<p>So here is the absolute simplest templating example that still works:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:maroon;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">asp</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">:</span><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:maroon;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">Content</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA"> <span style="color:red">ID</span><span style="color:blue">=&quot;PageHead&quot;</span>
 <span style="color:red">ContentPlaceHolderID</span><span style="color:blue">=&quot;PlaceHolderAdditionalPageHead&quot;</span>
 <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">script</span> <span style="color:red">type</span><span 
  style="color:blue">=&quot;text/javascript&quot;</span> <span style="color:red">src</span><span 
  style="color:blue">=&quot;../ajax/MicrosoftAjax.js&quot;&gt;&lt;/</span><span 
  style="color:maroon">script</span><span style="color:blue">&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">script</span> <span style="color:red">type</span><span 
  style="color:blue">=&quot;text/javascript&quot;</span> <span style="color:red">src</span><span 
  style="color:blue">=&quot;../ajax/MicrosoftAjaxDataContext.js&quot;&gt;&lt;/</span><span 
  style="color:maroon">script</span><span style="color:blue">&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">script</span> <span style="color:red">type</span><span 
  style="color:blue">=&quot;text/javascript&quot;</span> <span style="color:red">src</span><span 
  style="color:blue">=&quot;../ajax/MicrosoftAjaxTemplates.js&quot;&gt;&lt;/</span><span 
  style="color:maroon">script</span><span style="color:blue">&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">script</span> <span style="color:red">type</span><span 
  style="color:blue">=&quot;text/javascript&quot;</span> <span style="color:red">src</span><span 
  style="color:blue">=&quot;../ajax/MicrosoftAjaxAdoNet.js&quot;&gt;&lt;/</span><span 
  style="color:maroon">script</span><span style="color:blue">&gt;<br />
 &lt;/</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
  style="color:maroon">Content</span><span style="color:blue">&gt;<br />
 <br />
 &lt;</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
  style="color:maroon">Content</span> <span style="color:red">ID</span><span 
  style="color:blue">=&quot;Main&quot;</span> <span style="color:red">
 ContentPlaceHolderID</span><span style="color:blue">=&quot;PlaceHolderMain&quot;</span>
 <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">script</span> <span style="color:red">type</span><span 
  style="color:blue">=&quot;text/javascript&quot;&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">
 function</span> pageInit() {<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">var</span> 
 dataContext = $create(Sys.Data.AdoNetDataContext, {
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>serviceUri:
 <span style="color:maroon">&quot;/demoprep/_vti_bin/ListData.svc&quot;</span>
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>});<br />
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>$create(Sys.UI.DataView,
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>autoFetch:
 <span style="color:blue">true</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dataProvider: 
 dataContext,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fetchOperation:
 <span style="color:maroon">&quot;UserStories&quot;</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>fetchParameters: { 
 $top: 20 }<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>},<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:blue">null</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:blue">null</span>,<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>$get(<span 
  style="color:maroon">&quot;userStoriesList&quot;</span>)<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>);<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
 Sys.Application.add_init(pageInit);<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">script</span><span style="color:blue">&gt;<br />
 </span>
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">ul</span> <span style="color:red">id</span><span 
  style="color:blue">=&quot;userStoriesList&quot;</span> <span style="color:red">class</span><span 
  style="color:blue">=&quot;sys-template&quot;&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;</span><span 
  style="color:maroon">li</span><span style="color:blue">&gt;</span>{{ Title }}<span 
  style="color:blue">&lt;/</span><span style="color:maroon">li</span><span 
  style="color:blue">&gt;<br />
 </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">&lt;/</span><span 
  style="color:maroon">ul</span><span style="color:blue">&gt;<br />
 &lt;/</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
  style="color:maroon">Content</span><span style="color:blue">&gt;</span></span></p>

<p>The four script references in the PageHead Content control are necessary to define the required ASP.Net AJAX JavaScript classes you'll need for templating.  But the Main content control is where things get interesting.</p>
<p>Skip over the JavaScript for now and notice the unordered list named userStoriesList.  Inside of the li elements is a strange notation: {{ Title }}.  This specifies a binding to the name of a SharePoint field.  You could also have put in PriorityValue or any of the other columns specified in the JSON that I showed in Part 1.</p>
<p>As far as the JavaScript, the dataContext variable is a class of type AdoNetDataContext, which knows how to talk to WCF Data Services like ListData.svc.  It inherits from a JavaScript class called DataContext which is extensible and knows how to talk with other protocols, but us SharePoint developers probably won't care about this most of the time.</p>
<p>The userStoriesTemplate variable is a class of type DataView.  This is where the magic happens.  DataViews pull data from a DataContext, duplicates the innerHtml of an associated DOM element for each row returned (e.g. userStoriesList), and replace the binding syntax with real data.  Seems simple enough, but it is actually quite sophisticated when you get to some more advanced scenarios that I'll describe later.</p>
<p>One last thing to notice is the sys-template class.  This is a prespecified CSS class that ASP.Net AJAX sets to display: block when it is finished rendering.  It's a good idea to create a CSS class for sys-template with display: none so that end users don't see your template code while the page is loading.  Obviously you should do this in a separate CSS class in LAYOUTS or if you're lazy you can put it in the PageHead content control like so:</p>

 <p class="MsoNormal">
  <span style="font-size:
9.5pt;font-family:Consolas;color:blue">&lt;</span><span style="font-size:9.5pt;
font-family:Consolas;color:maroon">STYLE</span><span style="font-size:9.5pt;
font-family:Consolas"> <span style="color:red">type</span><span style="color:blue">=&quot;text/css&quot;&gt;<br />
  </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  <span style="color:maroon">.sys-template</span> { <span style="color:red">
  display</span>: <span style="color:blue">block</span>; }<br />
  <span style="color:blue">&lt;/</span><span style="color:maroon">STYLE</span><span 
   style="color:blue">&gt;<br />
  <br />
  &lt;</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
   style="color:maroon">Content</span> <span style="color:red">ID</span><span 
   style="color:blue">=&quot;PageHead&quot;</span> <span style="color:red">
  ContentPlaceHolderID</span><span style="color:blue">=&quot;PlaceHolderAdditionalPageHead&quot;</span>
  <span style="color:red">runat</span><span style="color:blue">=&quot;server&quot;&gt;<br />
  </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>
  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>
  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjax.js&quot;&gt;&lt;/</span><span 
   style="color:maroon">script</span><span style="color:blue">&gt;<br />
  </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>
  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>
  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjaxDataContext.js&quot;&gt;&lt;/</span><span 
   style="color:maroon">script</span><span style="color:blue">&gt;<br />
  </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>
  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>
  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjaxTemplates.js&quot;&gt;&lt;/</span><span 
   style="color:maroon">script</span><span style="color:blue">&gt;<br />
  </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  <span style="color:blue">&lt;</span><span style="color:maroon">script</span>
  <span style="color:red">type</span><span style="color:blue">=&quot;text/javascript&quot;</span>
  <span style="color:red">src</span><span style="color:blue">=&quot;../ajax/MicrosoftAjaxAdoNet.js&quot;&gt;&lt;/</span><span 
   style="color:maroon">script</span><span style="color:blue">&gt;<br />
  </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  <span style="color:blue">&lt;</span><span style="color:maroon">STYLE</span>
  <span style="color:red">type</span><span style="color:blue">=&quot;text/css&quot;&gt;<br />
  </span><span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  </span><span style="color:maroon">.sys-template</span> { <span style="color:red">
  display</span>: <span style="color:blue">block</span>; }<br />
  <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  <span style="color:blue">&lt;/</span><span style="color:maroon">STYLE</span><span 
   style="color:blue">&gt;<br />
  &lt;/</span><span style="color:maroon">asp</span><span style="color:blue">:</span><span 
   style="color:maroon">Content</span><span style="color:blue">&gt;<br 
   style="mso-special-character:line-break" />
  <![if !supportLineBreakNewLine]>
  <br style="mso-special-character:line-break" />
  <![endif]></span><o:p></o:p></span>
 </p>

<p>So now if you click If you click Build -> Deploy Solution you should see something like this:</p>

<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gez10dNhuPk/S6akgdn0DlI/AAAAAAAABsc/ePFlii5mG9o/s1600-h/part2-5-endresult.gif"><img style="cursor:pointer; cursor:hand;width: 400px; height: 292px;" src="http://2.bp.blogspot.com/_gez10dNhuPk/S6akgdn0DlI/AAAAAAAABsc/ePFlii5mG9o/s400/part2-5-endresult.gif" border="0" alt=""id="Img1" /></a>

<p><b>Summary</b></p>
<p>Ok, this isn't super exciting yet.  We certainly could have done this much easier with server side code.  But bear with me, this has a lot of potential.  For instance, how do you write data back to the server?  How do you really make it AJAXy?  I'll explore these questions in <a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html">Part 3 - Writing data back to SharePoint with ASP.Net AJAX 4.0 Templates</a> and subsequent posts in the series.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Client Side AJAX Applications in SharePoint 2010 - Part 1</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1715</id>

    <published>2010-03-21T22:37:06Z</published>
    <updated>2010-04-10T19:07:14Z</updated>

    <summary>If you haven&apos;t played with it yet, one of the things you&apos;ll immediately notice about SharePoint 2010 is that the UI is extremely AJAX centric. For instance modifying or adding...</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term=".NET" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="adonetdataservices" label="ADO.Net Data Services" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ajax" label="AJAX" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint2010" label="SharePoint 2010" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>If you haven't played with it yet, one of the things you'll immediately notice about SharePoint 2010 is that the UI is extremely AJAX centric.  For instance modifying or adding list items is either done in-line with partial page refreshes or via lightbox popups.  It's very pleasant to use.</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2010/03/client-side-ajax-applications-in.html';

        /* Digg */
        var diggIframe = document.createElement('iframe');
        diggIframe.setAttribute('src', 'http://digg.com/tools/diggthis.php?u=' + currentPageUrl);
        diggIframe.setAttribute('height', '80');
        diggIframe.setAttribute('width', '52');
        diggIframe.setAttribute('frameborder', '0');
        diggIframe.setAttribute('scrolling', 'no');
        diggIframe.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');

        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);

        var div = document.createElement('div');
        div.appendChild(dotnetkicksLink);
        div.appendChild(document.createElement('br'));
        div.appendChild(diggIframe);

        document.write(div.innerHTML);
    </script>
</div>


<p>One of the consequences of this Web 2.0 design is that the expectations of SharePoint end users will significantly increase.  No longer will long delays and/or full page refreshes in your SharePoint based custom applications be acceptable.  End users may not be able to clearly articulate it, but unless as developers we update our techniques to match the new technology our SharePoint based applications will begin to feel stale and will stick out from the rest of SharePoint 2010.</p>
<p>Fortunately Microsoft has stepped up the support it offers Web 2.0 developers in a big way.  One of the most compelling features is in how SharePoint exposes all list data via REST/ATOM <i>and</i> JSON.  This feature combined with the new templating feature of ASP.Net AJAX 4 allows developers to easily write fast, responsive user interfaces.  I will explore these two technologies in the following series:</p>

<p>
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications.html">Part 1 - Exploring WCF Data Services in SharePoint 2010</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html">Part 2 - Creating a read-only page with ASP.Net AJAX 4.0 Templates</a><br />
<a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html">Part 3 - Writing data back to SharePoint with ASP.Net AJAX 4.0 Templates</a><br/>
<a href="http://www.nearinfinity.com/blogs/lee_richardson/aspajax_4_templates_part_4_-_j.html">Part 4 - jQuery and Manual JSON Object Manipulation</a>
</p>

<p><b>Why do we need yet another framework?</b></p>
<p>If you attempt to develop Web 2.0 applications in SharePoint with the techniques you have today there are really only two approaches: ASP.Net AJAX and server side controls or manually coding JavaScript, probably with jQuery or other JavaScript Libraries.  If you take the ASP.Net AJAX approach you'll undoubtedly be using an UpdatePanel to get partial page refreshes and then writing ASP.Net code like you always have.  There are several problems with this approach:</p>

<ul>
<li>It sends the entire ViewState with every asynchronous request - this can result in slow, unresponsive apps (this can actually sneak up on you once you have a lot of production data as happened to me recently)</li>
<li>Even without a ViewState the UpdatePanel transmits large amounts of HTML (rather than lightweight JSON data)</li>
<li>It runs through the entire page lifecycle on updates, executing everything on the page even if it isn't relevant to what you're doing</li>
<li>ASP.Net AJAX doesn't have the simplicity of an ETag based HTTP caching like with a REST solution</li>
<li>Finally SharePoint just doesn't work well with UpdatePanel, I can't tell you how many issues I've had with various controls not working out of the box</li>
</ul>

<p>And if you take the manual JavaScript rout you are faced with a number of different problems:</p>

<ul>
<li>You have to write <i>a lot</i> of plumbing code</li>
 <ul>
  <li>You have to write a service to return your data</li>
  <li>You have to pay particular attention to security and permissions since you're exposing your API's to the world</li>
  <li>You have to convert your data (ideally JSON) into HTML with probably string concatenation or document.createElement statements</li>
 </ul>
<li>Your UI code is not clearly separated from your data access code making your code hard to maintain</li>
<li>Saving data back to the server involves even more plumbing code</li>
</ul>

<p>SharePoint 2010 combined with ASP.Net AJAX 4.0 solves these problems.  It probably introduces new problems too, but I haven't run into too many thus far.  So over the next couple of posts I hope to convince you that we do need yet another web framework and that Microsoft is headed in a great direction with these technologies.</p>
<p><b>So How Does it Work?</b></p>
<p>In WSS 3.0 you were able to access list data with the SOAP based Lists.asmx.  This technique worked well for .Net desktop apps or server side application pages, but not so well with client side JavaScript.  SharePoint 2010 exposes its list data with REST based ListData.svc (though WCF Data Services which I'll describe in more detail below).  Once you install <a href=" http://ajax.codeplex.com/releases/view/35895 ">WCF Data Services</a> on a machine with SharePoint 2010 you can simply navigate to http://[server]/[optional site]/_vti_bin/ListData.svc and see all of the lists you have permission to access.  The result will look like this:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;?</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:#A31515;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">xml</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA"> </span>
 <span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:red;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">version</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">=</span><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA">&quot;<span style="color:blue">1.0</span>&quot;<span style="color:blue"> </span>
 <span style="color:red">encoding</span><span style="color:blue">=</span>&quot;<span 
  style="color:blue">iso-8859-1</span>&quot;<span style="color:blue"> </span>
 <span style="color:red">standalone</span><span style="color:blue">=</span>&quot;<span 
  style="color:blue">yes</span>&quot;<span style="color:blue">?&gt;<br />
 &lt;</span><span style="color:#A31515">service</span><span style="color:blue">
 </span><span style="color:red">xml:base</span><span style="color:blue">=</span>&quot;<span 
  style="color:blue">http://localhost/mySite/_vti_bin/ListData.svc/</span>&quot;<span 
  style="color:blue">
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span></span><span style="color:red">
 xmlns:atom</span><span style="color:blue">=</span>&quot;<span style="color:blue">http://www.w3.org/2005/Atom</span>&quot;<span 
  style="color:blue">
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span></span><span style="color:red">
 xmlns:app</span><span style="color:blue">=</span>&quot;<span style="color:blue">http://www.w3.org/2007/app</span>&quot;<span 
  style="color:blue">
 <br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span></span><span style="color:red">xmlns</span><span 
  style="color:blue">=</span>&quot;<span style="color:blue">http://www.w3.org/2007/app</span>&quot;<span 
  style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span style="color:#A31515">workspace</span><span 
  style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="color:#A31515">atom:title</span><span 
  style="color:blue">&gt;</span>Default<span style="color:blue">&lt;/</span><span 
  style="color:#A31515">atom:title</span><span style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="color:#A31515">collection</span><span 
  style="color:blue"> </span><span style="color:red">href</span><span 
  style="color:blue">=</span>&quot;<span style="color:blue">Iterations</span>&quot;<span 
  style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="color:#A31515">atom:title</span><span 
  style="color:blue">&gt;</span>Iterations<span style="color:blue">&lt;/</span><span 
  style="color:#A31515">atom:title</span><span style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span style="color:#A31515">collection</span><span 
  style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="color:#A31515">collection</span><span 
  style="color:blue"> </span><span style="color:red">href</span><span 
  style="color:blue">=</span>&quot;<span style="color:blue">UserStories</span>&quot;<span 
  style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="color:#A31515">atom:title</span><span 
  style="color:blue">&gt;</span>UserStories<span style="color:blue">&lt;/</span><span 
  style="color:#A31515">atom:title</span><span style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span style="color:#A31515">collection</span><span 
  style="color:blue">&gt;<br />
 <span style="mso-spacerun:yes">&nbsp; </span>&lt;/</span><span style="color:#A31515">workspace</span><span 
  style="color:blue">&gt;<br />
 &lt;/</span><span style="color:#A31515">service</span><span style="color:blue">&gt;</span></span></p>

<p>You can then append the names of lists (e.g. http://localhost/site/_vti_bin/ListData.svc/UserStories) and immediately view the list items in the list as an ATOM feed.  A typical result looks like this:</p>

 <p class="MsoNormal">
  <span style="font-size:
9.5pt;font-family:Consolas;color:blue">&lt;?</span><span style="font-size:9.5pt;
font-family:Consolas;color:#A31515">xml</span><span style="font-size:9.5pt;
font-family:Consolas;color:blue"> </span>
  <span style="font-size:9.5pt;
font-family:Consolas;color:red">version</span><span style="font-size:9.5pt;
font-family:Consolas;color:blue">=</span><span style="font-size:9.5pt;
font-family:Consolas">&quot;<span style="color:blue">1.0</span>&quot;<span style="color:blue">
  </span><span style="color:red">encoding</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">iso-8859-1</span>&quot;<span style="color:blue"> </span>
  <span style="color:red">standalone</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">yes</span>&quot;<span style="color:blue">?&gt;<br />
  &lt;</span><span style="color:#A31515">feed</span><span style="color:blue"> </span>
  <span style="color:red">xml:base</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://localhost/mySite/_vti_bin/ListData.svc/</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span></span>
  <span style="color:red">xmlns:d</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span></span>
  <span style="color:red">xmlns:m</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices/metadata</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span></span>
  <span style="color:red">xmlns</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://www.w3.org/2005/Atom</span>&quot;<span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span 
   style="color:#A31515">title</span><span style="color:blue"> </span>
  <span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">text</span>&quot;<span style="color:blue">&gt;</span>UserStories<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">title</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span 
   style="color:#A31515">id</span><span style="color:blue">&gt;</span>http://localhost/mySite/_vti_bin/ListData.svc/UserStories<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">id</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span 
   style="color:#A31515">updated</span><span style="color:blue">&gt;</span>2010-03-20T02:20:26Z<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">updated</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span 
   style="color:#A31515">link</span><span style="color:blue"> </span>
  <span style="color:red">rel</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">self</span>&quot;<span style="color:blue"> </span>
  <span style="color:red">title</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories</span>&quot;<span style="color:blue"> </span>
  <span style="color:red">href</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories</span>&quot;<span style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span 
   style="color:#A31515">entry</span><span style="color:blue"> </span>
  <span style="color:red">m:etag</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">W/</span><span style="color:red">&amp;quot;</span><span 
   style="color:blue">3</span><span style="color:red">&amp;quot;</span>&quot;<span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">id</span><span style="color:blue">&gt;</span>http://localhost/mySite/_vti_bin/ListData.svc/UserStories(2)<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">id</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">title</span><span style="color:blue"> </span>
  <span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">text</span>&quot;<span style="color:blue">&gt;</span>Blah<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">title</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">updated</span><span style="color:blue">&gt;</span>2010-03-19T15:13:28-05:00<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">updated</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">author</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">name</span><span style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span 
   style="color:#A31515">author</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">link</span><span style="color:blue"> </span>
  <span style="color:red">rel</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">edit</span>&quot;<span style="color:blue"> </span>
  <span style="color:red">title</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStoriesItem</span>&quot;<span style="color:blue"> </span>
  <span style="color:red">href</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories(2)</span>&quot;<span style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">link</span><span style="color:blue"> </span>
  <span style="color:red">rel</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices/related/Predecessors</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">application/atom+xml;type=feed</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">title</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Predecessors</span>&quot;<span style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">href</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories(2)/Predecessors</span>&quot;<span 
   style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">link</span><span style="color:blue"> </span>
  <span style="color:red">rel</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices/related/Priority</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">application/atom+xml;type=entry</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">title</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Priority</span>&quot;<span style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">href</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories(2)/Priority</span>&quot;<span style="color:blue"> 
  /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">link</span><span style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">rel</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices/related/Status</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">application/atom+xml;type=entry</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">title</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Status</span>&quot;<span style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">href</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories(2)/Status</span>&quot;<span style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">link</span><span style="color:blue"> </span>
  <span style="color:red">rel</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices/related/Iteration</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">application/atom+xml;type=entry</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">title</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Iteration</span>&quot;<span style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">href</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories(2)/Iteration</span>&quot;<span style="color:blue"> 
  /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">link</span><span style="color:blue"> </span>
  <span style="color:red">rel</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices/related/Attachments</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">application/atom+xml;type=feed</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">title</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Attachments</span>&quot;<span style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">href</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">UserStories(2)/Attachments</span>&quot;<span 
   style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">category</span><span style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">term</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Microsoft.SharePoint.DataService.UserStoriesItem</span>&quot;<span 
   style="color:blue">
  <br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  </span><span style="color:red">scheme</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">http://schemas.microsoft.com/ado/2007/08/dataservices/scheme</span>&quot;<span 
   style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">content</span><span style="color:blue"> </span>
  <span style="color:red">type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">application/xml</span>&quot;<span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span 
   style="color:#A31515">m:properties</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:ContentTypeID</span><span 
   style="color:blue">&gt;</span>0x01080070E2807D369BD94FBD6C057D3110E6D3<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:ContentTypeID</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Title</span><span style="color:blue">&gt;</span>Do 
  Something<span style="color:blue">&lt;/</span><span style="color:#A31515">d:Title</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:PriorityValue</span><span 
   style="color:blue">&gt;</span>(2) Normal<span style="color:blue">&lt;/</span><span 
   style="color:#A31515">d:PriorityValue</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:StatusValue</span><span 
   style="color:blue">&gt;</span>Not Started<span style="color:blue">&lt;/</span><span 
   style="color:#A31515">d:StatusValue</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Complete</span><span style="color:blue">
  </span><span style="color:red">m:type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Edm.Double</span>&quot;<span style="color:blue"> </span>
  <span style="color:red">m:null</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">true</span>&quot;<span style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:AssignedToID</span><span 
   style="color:blue"> </span><span style="color:red">m:type</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">Edm.Int32</span>&quot;<span 
   style="color:blue"> </span><span style="color:red">m:null</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">true</span>&quot;<span 
   style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:TaskGroupID</span><span 
   style="color:blue"> </span><span style="color:red">m:type</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">Edm.Int32</span>&quot;<span 
   style="color:blue"> </span><span style="color:red">m:null</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">true</span>&quot;<span 
   style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Description</span><span 
   style="color:blue">&gt;</span><span style="color:red">&amp;lt;</span>div<span 
   style="color:red">&amp;gt;&amp;lt;</span>/div<span style="color:red">&amp;gt;</span><span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:Description</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:StartDate</span><span style="color:blue">
  </span><span style="color:red">m:type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Edm.DateTime</span>&quot;<span style="color:blue">&gt;</span>2010-02-20T00:00:00<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:StartDate</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:DueDate</span><span style="color:blue">
  </span><span style="color:red">m:type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Edm.DateTime</span>&quot;<span style="color:blue"> </span>
  <span style="color:red">m:null</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">true</span>&quot;<span style="color:blue"> /&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Points</span><span style="color:blue">
  </span><span style="color:red">m:type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Edm.Double</span>&quot;<span style="color:blue">&gt;</span>3<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:Points</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:IterationID</span><span 
   style="color:blue"> </span><span style="color:red">m:type</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">Edm.Int32</span>&quot;<span 
   style="color:blue">&gt;</span>3<span style="color:blue">&lt;/</span><span 
   style="color:#A31515">d:IterationID</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:ID</span><span style="color:blue"> </span>
  <span style="color:red">m:type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Edm.Int32</span>&quot;<span style="color:blue">&gt;</span>2<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:ID</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:ContentType</span><span 
   style="color:blue">&gt;</span>Task<span style="color:blue">&lt;/</span><span 
   style="color:#A31515">d:ContentType</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Modified</span><span style="color:blue">
  </span><span style="color:red">m:type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Edm.DateTime</span>&quot;<span style="color:blue">&gt;</span>2010-03-19T15:13:28<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:Modified</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Created</span><span style="color:blue">
  </span><span style="color:red">m:type</span><span style="color:blue">=</span>&quot;<span 
   style="color:blue">Edm.DateTime</span>&quot;<span style="color:blue">&gt;</span>2010-02-20T15:32:26<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:Created</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:CreatedByID</span><span 
   style="color:blue"> </span><span style="color:red">m:type</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">Edm.Int32</span>&quot;<span 
   style="color:blue">&gt;</span>1<span style="color:blue">&lt;/</span><span 
   style="color:#A31515">d:CreatedByID</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:ModifiedByID</span><span 
   style="color:blue"> </span><span style="color:red">m:type</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">Edm.Int32</span>&quot;<span 
   style="color:blue">&gt;</span>1<span style="color:blue">&lt;/</span><span 
   style="color:#A31515">d:ModifiedByID</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Owshiddenversion</span><span 
   style="color:blue"> </span><span style="color:red">m:type</span><span 
   style="color:blue">=</span>&quot;<span style="color:blue">Edm.Int32</span>&quot;<span 
   style="color:blue">&gt;</span>3<span style="color:blue">&lt;/</span><span 
   style="color:#A31515">d:Owshiddenversion</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Version</span><span style="color:blue">&gt;</span>3.0<span 
   style="color:blue">&lt;/</span><span style="color:#A31515">d:Version</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
  &lt;</span><span style="color:#A31515">d:Path</span><span style="color:blue">&gt;</span>/mySite/Lists/User 
  Stories<span style="color:blue">&lt;/</span><span style="color:#A31515">d:Path</span><span 
   style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span style="color:
#A31515">m:properties</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span 
   style="color:#A31515">content</span><span style="color:blue">&gt;<br />
  <span style="mso-spacerun:yes">&nbsp; </span>&lt;/</span><span 
   style="color:#A31515">entry</span><span style="color:blue">&gt;<br />
  &lt;/</span><span style="color:#A31515">feed</span><span style="color:blue">&gt;<br 
   style="mso-special-character:line-break" />
  <![if !supportLineBreakNewLine]>
  <br style="mso-special-character:line-break" />
  <![endif]></span><o:p></o:p></span>
 </p>

<p>You can append various parameters to filter, sort, or paginate your data from this page.  For example http://localhost/site/_vti_bin/ListData.svc/UserStories?$filter=(PriorityValue eq '(2) Normal')&$orderby=Title will return list items whose priority is normal sorted by title.  See <a href="http://msdn.microsoft.com/en-us/magazine/cc668784.aspx ">Query Expressions</a> on MSDN for more details.</p>

<p>Now if you're interested you can take it a step further by viewing the data as JSON.  To do this you'll need to modify the HTTP headers.  Fortunately there is a tool from Microsoft for viewing, replaying, and modify HTTP sessions called <a href="http://www.fiddler2.com/fiddler2/ ">Fiddler</a>.  After you install it open Fiddler from the add-in in your web browser (I used IE, but Firefox should work too).  Then refresh the web page for a list (in my case ListData.svc/UserStories).  Now in Fiddler drag the last request to the Request Builder, ensure "Automatically Authenticate" is checked in options, and replace "Accept: */*" with "Accept application/json". When you click Execute you should see something like:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA">{<br />
 <span style="color:maroon">&quot;d&quot;</span> : {<br />
 <span style="color:maroon">&quot;results&quot;</span>: [<br />
 {<br />
 <span style="color:maroon">&quot;__metadata&quot;</span>: {<br />
 <span style="color:maroon">&quot;uri&quot;</span>: <span style="color:maroon">
 &quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(2)&quot;</span>,
 <br />
 <span style="color:maroon">&quot;etag&quot;</span>: <span style="color:maroon">&quot;W/\&quot;3\&quot;&quot;</span>,
 <br />
 <span style="color:maroon">&quot;type&quot;</span>: <span style="color:maroon">
 &quot;Microsoft.SharePoint.DataService.UserStoriesItem&quot;<br />
 </span>}, <span style="color:maroon">&quot;ContentTypeID&quot;</span>:
 <span style="color:maroon">&quot;0x01080070E2807D369BD94FBD6C057D3110E6D3&quot;</span>,
 <br />
 <span style="color:maroon">&quot;Title&quot;</span>: <span style="color:maroon">&quot;Blah&quot;</span>,
 <br />
 <span style="color:maroon">&quot;Predecessors&quot;</span>: {<br />
 <span style="color:maroon">&quot;__deferred&quot;</span>: {<br />
 <span style="color:maroon">&quot;uri&quot;</span>: <span style="color:maroon">
 &quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(2)/Predecessors&quot;<br />
 </span>}<br />
 }, <span style="color:maroon">&quot;Priority&quot;</span>: {<br />
 <span style="color:maroon">&quot;__deferred&quot;</span>: {<br />
 <span style="color:maroon">&quot;uri&quot;</span>: <span style="color:maroon">
 &quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(2)/Priority&quot;<br />
 </span>}<br />
 }, <span style="color:maroon">&quot;PriorityValue&quot;</span>: <span style="color:maroon">
 &quot;(2) Normal&quot;</span>, <span style="color:maroon">&quot;Status&quot;</span>: {<br />
 <span style="color:maroon">&quot;__deferred&quot;</span>: {<br />
 <span style="color:maroon">&quot;uri&quot;</span>: <span style="color:maroon">
 &quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(2)/Status&quot;<br />
 </span>}<br />
 }, <span style="color:maroon">&quot;StatusValue&quot;</span>: <span style="color:maroon">
 &quot;Not Started&quot;</span>,
 <br />
 <span style="color:maroon">&quot;Complete&quot;</span>: <span style="color:
blue">null</span>,
 <br />
 <span style="color:maroon">&quot;AssignedToID&quot;</span>: <span style="color:blue">null</span>,
 <br />
 <span style="color:maroon">&quot;TaskGroupID&quot;</span>: <span style="color:blue">null</span>,
 <br />
 <span style="color:maroon">&quot;Description&quot;</span>: <span style="color:maroon">
 &quot;&lt;div&gt;&lt;/div&gt;&quot;</span>,
 <br />
 <span style="color:maroon">&quot;StartDate&quot;</span>: <span style="color:maroon">
 &quot;\/Date(1266624000000)\/&quot;</span>,
 <br />
 <span style="color:maroon">&quot;DueDate&quot;</span>: <span style="color:blue">null</span>,
 <br />
 <span style="color:maroon">&quot;Points&quot;</span>: 3,
 <br />
 <span style="color:maroon">&quot;Iteration&quot;</span>: {<br />
 <span style="color:maroon">&quot;__deferred&quot;</span>: {<br />
 <span style="color:maroon">&quot;uri&quot;</span>: <span style="color:maroon">
 &quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(2)/Iteration&quot;<br />
 </span>}<br />
 }, <span style="color:maroon">&quot;IterationID&quot;</span>: 3,
 <br />
 <span style="color:maroon">&quot;ID&quot;</span>: 2,
 <br />
 <span style="color:maroon">&quot;ContentType&quot;</span>: <span style="color:maroon">
 &quot;Task&quot;</span>,
 <br />
 <span style="color:maroon">&quot;Modified&quot;</span>: <span style="color:
maroon">&quot;\/Date(1269011608000)\/&quot;</span>,
 <br />
 <span style="color:maroon">&quot;Created&quot;</span>: <span style="color:maroon">
 &quot;\/Date(1266679946000)\/&quot;</span>,
 <br />
 <span style="color:maroon">&quot;CreatedByID&quot;</span>: 1,
 <br />
 <span style="color:maroon">&quot;ModifiedByID&quot;</span>: 1,
 <br />
 <span style="color:maroon">&quot;Owshiddenversion&quot;</span>: 3,
 <br />
 <span style="color:maroon">&quot;Version&quot;</span>: <span style="color:maroon">&quot;3.0&quot;</span>,
 <br />
 <span style="color:maroon">&quot;Attachments&quot;</span>: {<br />
 <span style="color:maroon">&quot;__deferred&quot;</span>: {<br />
 <span style="color:maroon">&quot;uri&quot;</span>: <span style="color:maroon">
 &quot;http://localhost/demoprep/_vti_bin/ListData.svc/UserStories(2)/Attachments&quot;<br />
 </span>}<br />
 }, <span style="color:maroon">&quot;Path&quot;</span>: <span style="color:maroon">
 &quot;/demoprep/Lists/User Stories&quot;<br />
 </span>}<br />
 ]<br />
 }<br />
 }<br style="mso-special-character:line-break" />
 <![if !supportLineBreakNewLine]>
 <br style="mso-special-character:line-break" />
 <![endif]></span></p>

<p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gez10dNhuPk/S6YnvZgs-4I/AAAAAAAABr0/lFSbUWxfsAc/s1600-h/Fiddler.gif"><img style="cursor:pointer; cursor:hand;width: 400px; height: 191px;" src="http://2.bp.blogspot.com/_gez10dNhuPk/S6YnvZgs-4I/AAAAAAAABr0/lFSbUWxfsAc/s400/Fiddler.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5451088094233951106" /></a>
</p>

<p>That's SharePoint data as JavaScript Object Notation.  Notice the etag and href's to associated list data.  Cool.</p>

<p>But ListData.svc isn't just for reading data.  To experiment with it try deleting a list item.  To do this in fiddler set the HTTP verb to "DELETE", set the URL to a particular list item's URL (e.g. http://localhost/site/_vti_bin/ListData.svc/UserStories(2) where 2 is the ID for a list item), leave Request Headers empty, and hit Execute.  Refresh the list of items and yours is gone.  Permanently.  The item isn't even in the recycle bin.</p>
<p><b>Security in WCF Data Services</b></p>
<p>So at this point you are undoubtedly concerned about security.  Just to give some background ListData.svc is provided by a technology called <a href="http://en.wikipedia.org/wiki/ADO.NET_Data_Services">WCF Data Services</a>, which was formerly called ADO.Net Data Services, which was code named Astoria.  And WCF Data Services is an implementation of the open data protocol (OData) which <a href=" http://www.hanselminutes.com/default.aspx?showID=223 ">Scott Hanselman</a> has an excellent podcast about.</p>
<p>This technology was originally designed for exposing database data.  And in this scenario you do have to handle your own security.  SharePoint 2010, however, takes things a step further by giving you WCF Data Services (nearly) out of the box while also handling your authorization security.</p>
<p>For instance if you modify the row level permissions for a list item to deny read permissions to a user then ListData.svc will not return that list item for that user.  If you try to access the URL for that list item directly SharePoint returns a 404.  If you try to modify or delete a list item you don't have permissions to modify then SharePoint returns a 401 Unauthorized.</p>
<p>Very cool.  I find this especially nice because you don't have to worry about maintaining your security code.  It's intimately tied to SharePoint 2010's security model which is already quite sophisticated.</p>
<p>Incidentally, security is not all that's included when you use these services.  SharePoint also performs data validation and returns the appropriate HTTP error codes if you for instance violate the new uniqueness constraint.</p>
<p><b>Summary</b></p>
<p>SharePoint offers everything you've seen so far (nearly) out of the box and without a line of code.  This sets the stage for writing some nice client side applications with technologies like ASP.Net AJAX 4.0 client site templating.  Which is exactly what I intend to do in <a href="http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html">Part 2 - Creating a read-only page with ASP.Net AJAX 4.0 Templates</a>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>The Agile Attitude Part 2: Letting Go</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/jeff_borst/the_agile_attitude_part_2_lett.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1711</id>

    <published>2010-03-15T03:04:03Z</published>
    <updated>2010-03-14T20:12:57Z</updated>

    <summary><![CDATA[For many of us in the IT industry, the popularity of Agile development has been a freeing experience.&nbsp; When an organization understands its role in Agile development and allows the...]]></summary>
    <author>
        <name>Jeff Borst</name>
        
    </author>
    
        <category term="Agile Development" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[For many of us in the IT industry, the popularity of Agile development has been a freeing experience.&nbsp; When an organization understands its role in Agile development and allows the team to self organize and come up with creative solutions, many of the stress and tensions that can be felt by the development team can melt away.&nbsp; This is because Agile processes allow development teams to do what they do best: develop software.&nbsp; The drivel that follows is advice for development teams on how to let go of some habits or preconceptions in order to better benefit from using an Agile development process.<br /><font style="font-size: 1.25em;"><br /><font style="font-size: 1em;">Follow the Agile Process - it will make your life easier</font></font><font style="font-size: 1em;"><br /></font><br />One of my favorite things about Agile development is that it removes the burden of decision making from the development team.&nbsp; The team gets to provide facts to the decision maker (Product Owner) and then execute once a decision is made.&nbsp; There is no more need to hide problems or try to make up schedule time (although I'm sure that no IT professional has ever done such a thing).&nbsp; Developing software is what it is - unpredictable - and Agile development accounts for that through continuous planning.&nbsp; The best thing that a team can do is be as transparent as possible, help decision makers gather all the information that they need in order to make a decision and then sit back and wait for the next Sprint's marching orders.&nbsp; This allows the team to spend more time and energy on what they do really well - building good software.<div><br /><img src="file:///Users/jborst/Library/Caches/TemporaryItems/moz-screenshot.png" alt="" /><br /><font style="font-size: 1.25em;">Remember who owns the system</font><br /><br />The majority of software developers out there are building a system for somebody else.&nbsp; Yes, there is a tremendous amount of pride and sweat equity that is built up when building any system, but we always need to keep in mind who it is for.&nbsp; Many times its not our system that we our building, its our customer's.&nbsp; Software developers get paid to develop software and thanks to Scrum, Product Owners now get paid to make decisions that directly shape the software.&nbsp; They get to make big decisions every month, and they should be making little decisions every day.&nbsp; So remember, what makes sense to you should be a starting point for implementation.&nbsp; Many times as developers we understand how our users think and can implement features in ways that are both elegant and intuitive - but not always.&nbsp; Sometimes we completely fail to grasp our customer's environment or needs and if left to our druthers would create a system that would completely miss the mark.&nbsp; This is the way of the past.&nbsp; The future (powered by Agile process) is to let our customer's be intimately involved with the software right from the beginning, and let them shape our actions so that the systems we build will be as useful as possible to their users.<br /><br /><font style="font-size: 1.25em;">Help Make Decisions</font><br /><br />It may sound like I want to purge thought and creativity from the development team, but I really don't.&nbsp; The team is the Product Owner's biggest asset.&nbsp; The team should let the Product Owner understand the possibilities that technology can provide.&nbsp; We are responsible for keeping our Product Owners informed, providing suggestions, and laying out the pros and cons of various options so that they can make good decisions. There is nothing more beautiful in software development than a well oiled development team that has an intimate relationship with its Product Owner.&nbsp; With ideas flying all over the place, creativity and experience can come together to create game changing software that really adds value on top of the regular automation of business processes that we have learned to do so well over the past 10 - 20 years.&nbsp; Just remember, ultimately it is the Product Owner who is responsible for the return on investment for the system, and when it is all said and done, they have final say for implementation.<br /><br /><font style="font-size: 1.25em;">Don't fight the process</font><br /><br />Agile requires a different way of thinking than many IT professionals are used to.&nbsp; Agile development asks us to give up some control over the process for building software.&nbsp; For many, this change can be hard to swallow, especially when we are asked to do things that we don't agree with, be it adding a particular feature or changing the layout of the UI. In these cases, feel free to voice your opposition, but remember your role. System design and implementation is your thing.&nbsp; Deciding what to do and when is up to your Product Owner.&nbsp; You will likely have very good input on these matters, and if you voice your opinion respectfully (not forcefully) in time your Product Owner will come to trust and depend on your sage advice.&nbsp; Allow the iterative nature of the Agile process to work to your advantage.&nbsp; If your Product Owner fails to follow your advice and makes a bad decision, it will be brought to light rather quickly.&nbsp; Its OK to cut them some slack. &nbsp;One thing that as developers we love about Agile is that it tells us that we don't always need to have all of the answers.&nbsp; I think its reasonable that we don't expect our Product Owners to always have all of the right answers either.<br /><br /><font style="font-size: 1.25em;">Let me sum up</font><br /><br />Agile development isn't easy.&nbsp; Bridging the gap between the business side of an organization and the IT side of an organization is extremely hard.&nbsp; As software developers, by giving up a little bit of control and not giving in to our egos always telling us we have the right answer, it will be easier to benefit from all of the wonderful joys that Agile Development has to offer.<br /></div>]]>
        
    </content>
</entry>

<entry>
    <title>Learning ANTLR part I</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/bill_bejeck/learning_antlr_part_i.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1713</id>

    <published>2010-02-27T05:44:19Z</published>
    <updated>2010-02-27T08:14:25Z</updated>

    <summary>This year one of my goals is to try and become proficient in using ANTLR. I think that learning to translate text or build an external DSL is skill that,...</summary>
    <author>
        <name>Bill Bejeck</name>
        
    </author>
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<div style="font-size: 10pt;">This year one of my goals is to try and become proficient in using ANTLR.  I think that learning to translate text or build an external DSL is skill that, although not used everyday, will be very useful to know. For my first attempt I settled on something fairly easy, a SQL like grammar that could be used to search for files and the content within those files.  You should also be able to narrow the search results based on when the file was last modified.   My goal is to take something like the following:
<pre class="prettyprint">select * from /logs where file="*.out" and pattern="foobar" and modified &lt; 2 days ago
select * from /logs where file='*.out' and pattern='foobar' and modified between 20 and 30 minutes ago
</pre>
and translate it to the corresponding find command and pipe the results to xargs and grep:
<pre class="prettyprint">find /logs -name '*.out' -mtime -2 | xargs grep 'foobar'
find /logs -name '*.out' -mmin +20 -mmin -30 | xargs grep 'foobar'
</pre>
As an aside, if you are not familiar with xargs, check out <a href="http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/" target="new">this xargs tutorial</a> or the <a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?xargs" target="new">xargs man pages</a> , it's a great utility that executes a command with the output of a previous command.
<h4>Disclaimer</h4>
Now before the villagers gather up with torches and pitch forks to run me out of town (I'm channeling <a href="http://en.wikipedia.org/wiki/Young_Frankenstein" target="new"> Young Frankenstein</a> here), I would like to make somewhat of a disclaimer.  I am not suggesting a new language or discouraging learning the *nix command line tools.  The point here is to learn ANTLR.  I found it more interesting to translate something I use everyday on my current project, versus some of the other "Hello World" ANTLR examples I have seen.  So other than a using this grammar as a learning exercise, I don't see it as being useful.
<h4>Introduction</h4>
ANTLR is a deep topic, so obviously one blog post can not go into any great detail.   So what follows is not in-depth coverage of ANTLR, but a detailed description of the grammar developed.  I will explain each section as well as  some of the decisions and trade-offs I made.  For my development environment I'm using:
<ol>
	<li>Eclipse 3.5.1</li>
	<li>Java 6</li>
	<li>The <a href="http://antlrv3ide.sourceforge.net/" target="new">ANTLR IDE </a>plugin for Eclipse.  You could also use <a href="http://www.antlr.org/works/index.html" target="new">ANTLRWorks</a>, the gui development environment for ANTLR.  ANTLRWorks is an excellent tool, I just felt more comfortable to do this work in Eclipse.</li>
	<li> ANTLR version 3.2</li>
	<li> Mac OS X 10.6.2.</li>
</ol>
So with all of that out of the way,  let's get started looking at the grammar.
<h3>options, @header</h3>
<pre class="prettyprint">grammar FQL;
options {
     language = Java;
}
@header {
     package bbejeck.antlr.fql;
}
</pre>
Here I am specifying a combined grammar named FQL.  (FQL is short for File Query Language and yes, I know the name sucks)
In options I'm specifying that I want the generated code to be  Java.  I could have also specified C,C++ or Python here as well.  ANTLR also has support for generating code in Ruby, but with the version I am using (v 3.2) I could not get it to work.  I did find <a href="http://rubyforge.org/projects/antlr3/" target="new">ANTLR Ruby</a>.  I have not tried it out, but from the documentation it looks promising.  The @header option is setting the package for the generated parser code.  This is also where I would have specified any needed imports.
<h3>@members</h3>

The @members section is where you place instance variables and methods that will be placed and used in the generated parser.  Most likely the code in the members section will be used in embedded actions in the parser rules.
<pre class="prettyprint"> @members {
  private StringBuilder findBuilder = new StringBuilder("find ");
  
  private StringBuilder filter = new StringBuilder();
  
  private void addString(String s){
    if(s!=null){
        findBuilder.append(s);
     }
  }
  
  private String buildTimeArg(String s, String snum, String sign){
       StringBuilder timeBuilder = new StringBuilder();
       int num = Integer.parseInt(snum);
       
       if(s.equals("days")){
           return timeBuilder.append(" -mtime ").append(sign).append(num).toString();
       }
       if(s.equals("hours")){
           return timeBuilder.append(" -mmin ").append(sign).append((num*60)).toString();
       }
       
       return timeBuilder.append(" -mmin ").append(sign).append(num).toString();
  }
  
  protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException{
        throw new MismatchedTokenException(ttype,input);
  }
  
  public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException{
     throw e;
  }
  
}
</pre>
The two StringBuilders <i>findBuilder</i> and <i>filter</i> will be used by embedded actions to build up our translated query.   The reason for two StringBuilders will be explained when we cover the parsing rules.  The <i>addString</i> method is to check for optional tokens that could be null.  I could have easily checked for null in the embedded code within each rule,  but I felt it cluttered the grammar too much.  The <i>buildTimeArg</i> method is used as sort of a poor man's symbol table to translate the <i>modified</i> clause to the proper time format for the <i>mmin</i> or <i>mtime</i> arguments.  
The final two methods override how the generated parser responds to recognition errors (the generated parser extends ANTRL's Parser class which in turn extends the BaseRecognizer class).  By default ANTLR will recover from recognition errors and continue on, trying to read more tokens if available.   But in this grammar, if there is a recognition error along the way I want to stop processing right there.  

<h3>@rulecatch</h3>
Each parser rule is converted into a method call in the generated parser with a try - catch block surrounding the parsing code.  The catch statement here will be embedded in each one of the try-catch blocks in the parser.  
<pre class="prettyprint">@rulecatch{
    catch (RecognitionException e){
            throw e;
      }
}</pre>
If you remember from the previous section we want to stop parsing stop when RecognitionExceptions are encountered, so we re-throw the caught exception.
<h3>@lexer::header</h3>
Here we are specifying the package for the generated lexer.
<pre class="prettyprint">@lexer::header {
  package bbejeck.antlr.fql;
}
</pre>

Now let's move on to the parsing rules.

<h3>Parsing Rules</h3>
<pre class="prettyprint">evaluate returns [String query]
      :  query';' {$query = builder.toString() + filter.toString() ;}
      ;

query
       :   select_stmt where_stmt
       ;

select_stmt
      :  'select' '*' 'from' directory
      ;
</pre>
Here <i>evaluate</i> is our top level rule and returns a String, translated and built as the input is parsed.  Anything within the curly braces is code that will be embedded in the generated parser.  Note how we reference query from the grammar by placing a '$' before the word 'query'.  Also note that the string returned is a concatenation from the two StringBuilders we declared in the @members section.  The <i>query</i> rule is comprised of a <i>select_stmt</i> followed by a <i>where_stmt</i>.  The <i>select_stmt</i> is "select * from" followed by the directory rule.
<pre class="prettyprint">directory
       : (p='.'{addString($p.text);} | (p='/'?{addString($p.text);}IDENT{addString($IDENT.text);})+ )
       ;
</pre>
The directory rule accepts either a '.', a relative or an absolute path.  If the first expression is not provided there must be at least one path expression denoted by the '+'.  The variable 'p' is used to give a handle to the '.' or '/' token so it can be extracted . IDENT is a lexer rule which will be explained a little bit later.  All tokens here are passed into the <i>addString</i> method defined in the members section.
<pre class="prettyprint">where_stmt
       :  ('where'  clause ('and' clause)* ) ?
       ;
clause
       : file_name
       | pattern
       | modified
       ;
</pre>
The <i>where_stmt</i> rule expects the string 'where' followed by 0 or more clauses.  Also the entire <i>where_stmt</i>  is optional.  Here I chose form over substance.  By that I mean the grammar as it stands here will allow multiple clause's that would not make sense, i.e multiple file_name arguments etc.  I could have specified an exact order of clauses that would have also effectively set the limit of clauses entered, but I would rather the grammar be flexible and trust that the user knows what they want to do.
<pre class="prettyprint">  
file_name
       : 'file'  '=' STRING_LITERAL
         {addString(" -name ");addString($STRING_LITERAL.text);}
       ;

pattern
       :   'pattern'  '=' STRING_LITERAL
             { filter.append(" | xargs grep  ").append($STRING_LITERAL.text); }
       ;
</pre>
The <i>file_name</i> rule sets the -name argument again using the <i>addString</i> method.  The lexer rule STRING_LITERAL will accept whatever the user inputs.  The <i>pattern</i> rule builds up the grep command.  Here we see the use of the second StringBuilder <i>filter</i> that was defined in the @members section.  I feel that having a second StringBuilder to capture text for the grep filter is a hack.   The issue is that the <i>grep</i> command needs to be last in our translated query, but I really want the where statement to be in any order.  So by placing the tokens captured by the <i>pattern</i> rule in a separate StringBuilder I can easily guarantee the <i>grep</i> statement will be last.  
<pre class="prettyprint">modified
       :  modified_less
       |  modified_more
       |  modified_between
       ;
</pre>
The modified rule has three options.  This portion builds the mmin/mtime argument(s) for the <i>find</i> command.
<pre class="prettyprint">   
modified_less
       :   'modified'  '&lt;'  INTEGER time_span                             
           { addString(buildTimeArg($time_span.text,$INTEGER.text,"-")); }                     
       ; 
  
modified_more                     
       :   'modified'  '&gt;' INTEGER time_span
           { addString(buildTimeArg($time_span.text,$INTEGER.text,"+")); }
       ;

modified_between
       :   'modified' 'between' int1=INTEGER 'and' int2=INTEGER time_span
            { addString(buildTimeArg($time_span.text,$int1.text,"+")); }
            { addString(buildTimeArg($time_span.text,$int2.text,"-")); }
       ;
</pre>
The grammar allows you to specify searching by the time a file was last modified.  Here we use the method <i>buildTimeArg</i> to translate the input to the correct argument for either <i>mmin</i> (minutes modified) or <i>mtime</i> (days modified). Also take note of setting the two variables <i>int1</i> and <i>int2</i>.  Those are used to disambiguate which INTEGER token to use.
<pre class="prettyprint">time_span
       :   'days'
       |   'minutes'
       |   'hours'
       ;
</pre>
The time_span rule allows input of days, minutes or hours.  The hours argument is converted into minutes by the <i>buildTimeArg</i> method.

That's it for the parsing rules, now on to the lexer rules.
<h3>Lexer Rules</h3>
<pre class="prettyprint">fragment DIGIT : '0'..'9';
fragment LETTER : 'a'..'z'|'A'..'Z' ;

STRING_LITERAL : '\''.*'\'';
INTEGER : DIGIT+ ;
IDENT : LETTER(LETTER | DIGIT)* ;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+  {$channel=HIDDEN;};
</pre>
DIGIT and LETTER are not lexer rules, as you can see by the fragment definition.  These are used for making the grammar more readable.  In the WS definition the {$channel=HIDDEN;} is used to ignore whitespace in the input.

<h3>Test Code</h3>
I used the following code to test the grammar from the command line:
<pre class="prettyprint">public class FQLTester {

public static void main(String[] args) throws Exception{
     BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
     String line = null;
     System.out.println("Enter your search:");
     while((line = reader.readLine())!= null){
         if(line.equalsIgnoreCase("quit")){
            System.exit(0);
         }
        CharStream charstream = new ANTLRStringStream(line);
        FQLLexer lexer = new FQLLexer(charstream);

        TokenStream tokenStream = new CommonTokenStream(lexer);
        FQLParser parser = new FQLParser(tokenStream);

        String parsed = null;
        try{
            parsed = parser.evaluate();
            System.out.println("parsed query is ["+parsed+"]");
            Process process = Runtime.getRuntime().exec(new String[]{"sh","-c",parsed});
            InputStream input = process.getInputStream();
            BufferedReader procReader = new BufferedReader(new InputStreamReader(input));
            String searchResults = null;
            while((searchResults=procReader.readLine())!=null){
                  System.out.println(searchResults);
            }
        }catch(Exception e){
               e.printStackTrace();
        }
      System.out.println("Enter your search:");
    }
}
</pre>

Since this blog is just scratching the surface as far as ANTLR's capabilities are concerned, I plan to be writing more about ANTLR in the near future.  Full source code for everything presented is <a href="http://github.com/bbejeck/antlr_code" target="new">available here</a>.
More resources for learning ANTLR are:
<ul>
	<li><a href="http://javadude.com/articles/antlr3xtut/index.html" target="new">Scott Stanchfield's video tutorial on ANTLR</a></li>
	<li><a href="http://www.pragprog.com/titles/tpantlr/the-definitive-antlr-reference" target="new">Definitive Guide to ANTLR, Pragmatic Books</a></li>
</ul>

That's it for now, thanks for your time.</div>]]>
        

    </content>
</entry>

<entry>
    <title>Hanging out with industry leaders...</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/andrew_wagner/hanging_out_with_industry_lead.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1712</id>

    <published>2010-02-26T14:50:17Z</published>
    <updated>2010-02-26T16:54:06Z</updated>

    <summary><![CDATA[Thanks to Near Infinity's generous training budget, I had the opportunity last week to spend 3 days with several members of the&nbsp;Object Mentors&nbsp;group. These guys have an enormous amount of...]]></summary>
    <author>
        <name>Andrew Wagner</name>
        
    </author>
    
        <category term="Agile Development" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[Thanks to Near Infinity's generous training budget, I had the opportunity last week to spend 3 days with several members of the&nbsp;<a href="http://www.objectmentor.com/">Object Mentors</a>&nbsp;group. These guys have an enormous amount of experience, especially&nbsp;<a href="http://www.objectmentor.com/omTeam/martin_r.html">"Uncle" Bob Martin</a>. So I thought I would share a few of the pearls of wisdom they dropped along the way:<div><br /><div><ul><li>"Programming is a social exercise" - I thought this was a really good point. It was mentioned in the context of pair-programming, but I think it has far-reaching implications. Software development is more than just running through a bunch of formulas and crunching out an answer. Interaction within the team and with domain experts is crucial, to not only build the software right, but build the right software.</li><li>"A refactoring is something that takes a few seconds, or a few minutes at most" - I was really impressed with the importance of automated refactorings in his discussions. I think most of the time that I spend "refactoring" is in small, manual edits, whereas most of the time that he spends is in using automated refactoring to "chunk" his edits. I definitely need to learn these keystrokes and refactorings better. Maybe I should start a "Refactoring Driven Development" movement...</li><li>"Don't put refactoring on the schedule; do it all the time" - Simple, but effective. My tendency is to want to spend all my time refactoring, but this curbs that, because it forces me to refactor while I'm delivering user stories.&nbsp;</li><li>"There are 3 essential design skills: nose, vision, and plan" - A nose for recognizing design smells, a vision for seeing a good design for your codebase, and an ability to come up with a plan to get from point A to point B.&nbsp;</li><li>"Testing trumps good design" - This bothered me at first, but I think it's a really good point. The idea &nbsp;here is not to say that design is not important. But, rather, if you are forced to choose between between a "bad" design that allows better test coverage (e.g., less encapsulation), and "good" design which is hard to test, choose testability. The reason here is that the biggest roadblock to changing your codebase is not bad design, but FEAR of breaking something. If you know you will know when you've broken something, then you can retrofit a better design later.</li><li>"There is self-worth tied up in "finishing" something" - He also drew a distinction between having something working (which some developers will call "finishing" it), and finishing it - making it not only work, but be thoroughly tested, maintainable, etc.</li><li>Presentation layer - he talked about having the thinnest possible UI layer, which talks to a presentation layer to find out everything about how it should render. Then test the UI and business logic completely separately</li><li>"You aren't doing agile development unless you are tracking your velocity and remaining story points in terms of passing, automated acceptance tests" - I balked at this at first, feeling like it was too easy to use this as a performance to beat the team over the head with. After I thought about it, though, it's really about the definition of done. We are done if all the features we said would be working are working. And how can we know this? Only by testing them. Continuously. Which means it should be automated.</li><li>Acceptance tests don't need to be end-to-end, and, in fact, shouldn't be. This is another one that made me hesitate. After all, how do you know the feature is really working unless you go all the way from the UI to the database and back? Well, in short, because you're the developer. There's more value in being able to test features fast, constantly, than in being able to truly test them all the way from one end to the other. Mock/stub out what you need to to make that happen.</li><li>FitNesse is cool. This is the second time I've played around with that tool, and the second time I've been impressed with its power and simplicity. I definitely need to play around with it some more.</li></ul></div></div>]]>
        
    </content>
</entry>

<entry>
    <title>[video] How To Create Burndown Charts For User Stories in SharePoint</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/video_how_to_create_burndown_c.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1710</id>

    <published>2010-02-12T21:46:16Z</published>
    <updated>2010-02-12T23:39:07Z</updated>

    <summary> I love tracking user stories in SharePoint. It&apos;s free (assuming you have access to a Windows Server 2003 or 2008 machine with WSS turned on) and is extremely flexible....</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term="Agile Development" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="agile" label="agile" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="burndown" label="burndown" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="burnup" label="burnup" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="excel" label="excel" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="projectmanagement" label="project management" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sharepoint" label="SharePoint" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[ <p>I love tracking user stories in SharePoint.  It's free (assuming you have access to a Windows Server 2003 or 2008 machine with WSS turned on) and is extremely flexible.  Adding new custom columns is easy.  Adding custom views is easy.  Bulk editing is amazingly simple and powerful (assuming you're willing to use IE).  And building a custom home page "portal" with all the states of your team's workflow (e.g. unassigned, stories I'm working on, my resolved stories, to peer test, etc) is easy and is intuitive to use.</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2010/02/video-how-to-create-burndown-charts-for.html';

        /* Digg */
        var diggIframe = document.createElement('iframe');
        diggIframe.setAttribute('src', 'http://digg.com/tools/diggthis.php?u=' + currentPageUrl);
        diggIframe.setAttribute('height', '80');
        diggIframe.setAttribute('width', '52');
        diggIframe.setAttribute('frameborder', '0');
        diggIframe.setAttribute('scrolling', 'no');
        diggIframe.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');

        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);

        var div = document.createElement('div');
        div.appendChild(dotnetkicksLink);
        div.appendChild(document.createElement('br'));
        div.appendChild(diggIframe);

        document.write(div.innerHTML);
    </script>
</div>

<p>This 13 minute screencast shows you how to create a user stories list in SharePoint and build burn up and burn down charts off of the data using Microsoft Excel.  It includes the custom fields you'll need in SharePoint, the formula's you'll have to create in Excel, and shows tips along the way like how to simplify refreshing your reports when data changes.</p>

<object width="580" height="435"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9404991&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=e97000&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9404991&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=e97000&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="580" height="435"></embed></object>

<p>Once you've watched the screencast if you want to implement this yourself here is the information you'll need:</p>

<p><b>Custom SharePoint Columns</b></p>

<ul>
<li>Iteration (Choice column e.g. Iteration00, Iteration01, zBacklog)</li>
<li>Released (Date - the date the iteration was closed out)</li>
<li>Points (Number)</li>
<li>Created Date (for demo only, you should be able to use "Created" on your project)</li>
</ul>

<p><b>Calculated Columns in Excel</b></p>

<ul>
<li>Total Points to Date
  <ul>
  <li>The total points on a specific date including backlog, current iteration and all completed stories</li>
  <li>=SUMIF([Created Date],CONCATENATE("<=",Table_owssvr_1[[#This Row],[Released]]),[Points])</li>
  </ul>
</li>
<li>Completed To Date
  <ul>
  <li>Total points for stories released prior to current story's release date</li>
  <li>=SUMIF([Released],CONCATENATE("<=",Table_owssvr_1[[#This Row],[Released]]),[Points])</li>
  </ul>
</li>
<li>Backlog
  <ul>
  <li>What remains to be completed at a point in time (e.g. don't include user stories added to the backlog in iteration 4 if this is for a task in iteration 03)</li>
  <li>=Table_owssvr_1[[#This Row],[Total Points to Date]]-Table_owssvr_1[[#This Row],[Completed to Date]]</li>
  </ul>
</li>
</ul>

<p><b>Burndown Pivot Table Values</b></p>

<ul>
<li>Row: Released</li>
<li>Filter: Released After [Some Date]</li>
<li>Values: Max(Backlog)</li>
</ul>

<p><b>Burnup Pivot Table Values</b></p>

<ul>
<li>Row: Released</li>
<li>Filter: Released After</li>
<li>Values
  <ul>
  <li>Max(Total Points to Date)</li>
  <li>Max(Completed To Date)</li>
  </ul>
</li>
</ul>

<p><b>Summary</b></p>
<p>I hope you found the presentation useful and if you are currently using SharePoint for tracking user stories please comment on your experiences.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Sharepoint ASP .Net Ajax Configuration</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/sean_howell/sharepoint_asp_net_ajax_configuration.html" />
    <id>tag:www.nearinfinity.com,2010:/blogs//7.1707</id>

    <published>2010-02-02T23:34:17Z</published>
    <updated>2010-02-03T20:00:25Z</updated>

    <summary>In the world of web development, there is a little thing called ajax. Ajax is so simple because it is built in to Javascript. I like to use ajax to...</summary>
    <author>
        <name>Sean Howell</name>
        
    </author>
    
        <category term=".NET" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Web Development" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[In the world of web development, there is a little thing called ajax. Ajax is so simple because it is built in to Javascript. I like to use ajax to make web applications that look like they are not stuck in the past. Tools like jQuery make ajax so simple with its commands like:<div><pre class="prettyprint">$.get $.post $.load</pre>ASP .Net has, what they tout as ultra simple, the update panel for ajax post backs to the server. But, this tool is not as simple as it seems. While deceptively simple to stick on a page and wire up to the code behind, it takes much more to make this tool work.<div><br /><div>Like everything else in the Microsoft world, to make ASP .Net have ajax requires a dll and, through reading the documentation, a crap load of changes to the web.config file. Sure, it is easy to get the web.config all nice and set up if you have Visual Studios do it for you. Just create a new Web Site and start debugging the website. Voila, all of the configuration setting needed to use ajax are there.<br /></div><div><br /></div><div>But, for those whose have to do through code for, say, a Sharepoint web site that has to be deployed anywhere, they feel the pain of drudging through the required assembly strings and making SPWebConfigModifications. So, the first step on the path to Sharepoint ajaxiness is to go out to all the dlls and collect all the assembly strings needed:</div><div><br /><pre class="prettyprint">const string scriptResourceHandler = "System.Web.Handlers.ScriptResourceHandler,System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
const string scripthandlerfactory = "ScriptHandlerFactory";
const string scripthandlerfactoryappservice = "ScriptHandlerFactoryAppService";
const string scriptresource = "ScriptResource";
const string scriptModuleAssembly = "System.Web.Handlers.ScriptModule,System.Web.Extensions,Version=3.5.0.0,Culture=Neutral,PublicKeyToken=31bf3856ad364e35";
const string webScriptAssembly = "System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35";
const string webExtensionAssembly = "System.Web.Extensions,Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</pre>After you have done that, or just copied the above assemblies, those assemblies have to be added to the web.config. That is where the SPWebConfigModification comes into play. First, you'll want to clear the modifications otherwise, modifications might appear for items that are long gone.&nbsp;</div><div><br /><pre class="prettyprint">webApp.WebConfigModifications.Clear();</pre>After that is set up, there is quite a bit to add to the WebConfigModification collection. Here OWNER, is something you set somewhere else and keep handy for when you have to remove all of the changes from the web.config.</div><div><br /><pre class="prettyprint">webApp.WebConfigModifications.Add(CreateControlSection());		webApp.WebConfigModifications.Add(CreateSafeControl(webExtensionAssembly,"System.Web.UI"));
webApp.WebConfigModifications.Add(CreateAjaxAssembly(webExtensionAssembly));			webApp.WebConfigModifications.Add(CreateHttpScriptHandler(scriptModuleAssembly,"ScriptModule"));
webApp.WebConfigModifications.Add(CreateScriptResource(scriptResourceHandler,"ScriptResource.axd","GET,HEAD"))
webApp.WebConfigModifications.Add(CreateScriptResource(webScriptAssembly,"*_AppService.axd","*"));
webApp.WebConfigModifications.Add(CreateScriptResource(webScriptAssembly,"*.asmx","*"));
webApp.WebConfigModifications.Add(CreateWebServerSection());
webApp.WebConfigModifications.Add(CreateWebServerHandlerSection());
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scripthandlerfactory));
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scripthandlerfactoryappservice));
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scriptresource));
webApp.WebConfigModifications.Add(CreateWebServiceHandler(webScriptAssembly,"*.asmx","*",scripthandlerfactory));
webApp.WebConfigModifications.Add(CreateWebServiceHandler(webScriptAssembly,"*_AppService.axd","*",scripthandlerfactoryappservice));webApp.WebConfigModifications.Add(CreateWebServiceHandler(scriptResourceHandler,"ScriptResource.axd", "GET,HEAD", scriptresource));
webApp.Farm.Services.GetValue<spwebservice>().ApplyWebConfigModifications();
webApp.Update();
/* Thus begins the many methods to add each little piece of the web.config */
private SPWebConfigModification CreateScriptResource(string assembly,string path,string verb) {
      return new SPWebConfigModification {
		Path = "configuration/system.web/httpHandlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@verb='{2}'][@path='{1}'][@type='{0}'][@validate='false']",assembly,path,verb),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add verb="{2}" path="{1}" type="{0}" validate="false">", assembly,path,verb)
	};
}

private SPWebConfigModification CreateWebServiceHandler(string assembly,string path,string verb,string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.webServer/handlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@verb='{2}'][@path='{1}'][@type='{0}'][@preCondition='integratedMode'][@name='{3}']",assembly,path,verb,name),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add verb="{2}" path="{1}" type="{0}" precondition="integratedMode" name="{3}">", assembly,path,verb,name)
	};
}
private SPWebConfigModification RemoveWebServiceHandler(string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.webServer/handlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@name='{0}']",name),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<remove name="{0}">",name)
	};
}

private static SPWebConfigModification CreateHttpScriptHandler(string assembly,string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.web/httpModules",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@name='{0}'] [@type='{1}']",name, assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add name="{0}" type="{1}">",name, assembly)
	};
}

private static SPWebConfigModification CreateAssembly(string assembly) {
	return new SPWebConfigModification {
	        Path = "configuration/system.web/compilation/assemblies",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@assembly='{0}']", assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<add assembly="{0}">", assembly)
	};
}
private static SPWebConfigModification CreateAjaxAssembly(string assembly) {
	return new SPWebConfigModification {
		Path = "configuration/system.web/pages/controls",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@tagPrefix='{0}'][@namespace='{1}'][@assembly='{2}']","asp","System.Web.UI", assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<add tagprefix="{0}" namespace="{1}" assembly="{2}">","asp","System.Web.UI", assembly)
	};
}
private static SPWebConfigModification CreateSafeControl(string assembly, string nameSpace) {
	return new SPWebConfigModification {
		Path = "configuration/SharePoint/SafeControls",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "SafeControl[@Assembly='{0}'][@Namespace='{1}'][@TypeName='*'][@Safe='True']", assembly, nameSpace),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<safecontrol assembly="{0}" namespace="{1}" typename="*" safe="True">", assembly,				nameSpace)
	};
}
private static SPWebConfigModification CreateControlSection() {
	return new SPWebConfigModification {
		Path = "configuration/system.web/pages",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "controls",
		Value =@"<controls></controls>",
		Sequence = 0,
		Owner = OWNER
	};
}
private static SPWebConfigModification CreateWebServerSection() {
	return new SPWebConfigModification {
		Path = "configuration",
	        Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "system.webServer",
		Value =@"<system.webserver></system.webserver>",
		Sequence = 0,
		Owner = OWNER
	};
}
private static SPWebConfigModification CreateWebServerHandlerSection() {
       return new SPWebConfigModification {
		Path = "configuration/system.webServer",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "handlers",
		Value =@"<handlers></handlers>",
		Sequence = 0,
		Owner = OWNER
	};		
}</safecontrol></add></add></add></remove></add></add></spwebservice></pre><br />So, why on earth does it take that much code to generate the xml required to use ajax in Sharepoint?</div></div></div>]]>
        
    </content>
</entry>

</feed>
