<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>.NET - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2012</copyright>
        <lastBuildDate>Tue, 23 Aug 2011 23:09:48 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Integrating JavaScript and C# with Script#</title>
            <description><![CDATA[<p>Have you ever had an enum in your server code that you wanted to access in client side code?  Or wanted the safety of compile time errors when there are discrepancies between your server-side and client-side code?  Or had a C# Data Transfer Object (DTO) that you wanted to enable Intellisense for in JavaScript?  I hadn't found a good solution either ... until now.</p>
<p><b>Compiling C# to What!?</b></p>

<div style="float:right; overflow: auto; margin-left:10px;">
<script type='text/javascript'> 
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2011/08/integrating-javascript-and-c-with.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>Compiling C# code into JavaScript may seem foreign, but <a href=" http://projects.nikhilk.net/ScriptSharp ">Script#</a> is a mature technology that is absolutely worth a look.  Our team has been using it very happily for about three months.  We've found a number of benefits  including:</p>

<ul>
<li>Consistently working Intellisense</li>
<li>Better encapsulation</li>
<li>Simpler Object Orientation</li>
<li>Easier deployment (Script# compiles multiple files to a single, optionally minified file)</li>
<li>Safer refactoring</li>
<li>Simpler unit testing</li>
<li>Type safety; and</li>
<li>Design time syntax checking (no more mistyping a variable and accidentally declaring it to the global scope)</li>
</ul>

<p>Scott Hanselman covered most of these topics in last month's Hanselminutes episode: <a href=" http://www.hanselminutes.com/default.aspx?showID=296">Script# Compiles to JavaScript</a>.  If you have a spare car ride I definitely recommend the listen.  But what wasn't covered were some additional benefits provided by an off the beaten path approach to this great technology.  The main benefit is tighter server side C# to client side JavaScript integration.  A secondary benefit is less of a dependency on Script#.</p>

<p><b>To the Command Line</b></p>

<p>Typically to get going with Script# you: </p>

<ol>
<li>Install the Script# Visual Studio plug-in</li>
<li>File -> New project</li>
<li>Select "Script Library" and</li>
<li>Compile to generate JavaScript</li>
</ol>

<p>Nice and easy.  The down side to this approach is you can't easily include files outside of your project.  Specifically, you can't include data transfer objects or enum's from your server side code.  Furthermore, all of your team members must install Script#.  If instead you compile with Script#'s "ssc.exe" command you obtain more control and get less dependency.</p>

<p><b>How-To</b></p>

<p>The how-to looks something like this:</p>

<ol>

<li><a href="http://projects.nikhilk.net/ScriptSharp">Download</a> and install Script#</li>
<li>Add a Class Library (not a Script# project)</li>
<li>Project properties -> Build -> Advanced -> "Do not reference mscorlib"<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-u7QvzHOOfxE/TlRhVwoGyII/AAAAAAAABu8/Vonkzc8nNLc/s1600/mscorlib.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 235px;" src="http://4.bp.blogspot.com/-u7QvzHOOfxE/TlRhVwoGyII/AAAAAAAABu8/Vonkzc8nNLc/s400/mscorlib.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5644243259460339842" /></a>
</li>

<li>Ideally move the Script# files (C:\Program Files (x86)\ScriptSharp) locally to the solution and check them into source control to a Libs or something similar</li>

<li>Remove all references, but add: ScriptSharp.dll, ScriptSharp.Web.dll, Script.Jquery</li>
<li>Edit your .csproj to manually reference Script#'s mscorlib (right click, Unload project, Edit MyProject.csproj)<br />
    <br />
    <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">Reference</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">Include</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">mscorlib, Version=0.7.0.0, 
    Culture=neutral, PublicKeyToken=8fc0e3af5abcb6c4, processorArchitecture=MSIL</span>&quot;<span 
        style="color:blue">&gt;<br />
    <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span style="color:#A31515">SpecificVersion</span><span 
        style="color:blue">&gt;</span>True<span style="color:blue">&lt;/</span><span 
        style="color:#A31515">SpecificVersion</span><span style="color:blue">&gt;<br />
    <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span style="color:#A31515">HintPath</span><span 
        style="color:blue">&gt;</span>..\Libs\ScriptSharp\v1.0\mscorlib.dll<span 
        style="color:blue">&lt;/</span><span style="color:#A31515">HintPath</span><span 
        style="color:blue">&gt;<br />
    &lt;/</span><span style="color:#A31515">Reference</span><span style="color:
blue">&gt;</span></span><br /><br /></li>

<li>Modify AssemblyInfo.cs and remove the following lines:<br />
<br />
[assembly: ComVisible(false)]<br />
[assembly: Guid("b5e2449f-193c-46d1-9023-9143618d8491")]<br />
<br />
</li>

<li>Modify AssemblyInfo.cs and add the following:<br />
<br />
[assembly: ScriptAssembly("ScriptSharpDemoAssembly")<br />
<br />
</li>

<li>Ensure it compiles in Visual Studio</li>
<li>Create a batch script or PowerShell script that compiles using ssc.exe like this:<br />
<br />
..\Libs\ScriptSharp\v1.0\ssc.exe ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;/debug ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;/out:MyScriptSharp.js ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;/ref:"..\Libs\ScriptSharp\v1.0\Framework\mscorlib.dll" ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;.\Properties\AssemblyInfo.cs ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;.\Class1.cs<br />
<br />

</li>
</ol>

<p>Notice the last two lines in the script are a list of the files that you want to include.  The point of this exercise is that you can now include files outside of your main Script# project in that list.</p>
<p>Now for completeness if you put a simple static method in Class1.cs, 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">namespace</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"> MyScriptSharp<br />
        {<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>
        <span style="color:blue">class</span> <span style="color:#2B91AF">Class1<br />
        </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>{<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>
        <span style="color:blue">static</span> <span style="color:blue">string</span> 
        HelloWorld()<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><span style="color:blue">
        return</span> <span style="color:#A31515">&quot;Hello World!&quot;</span>;<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>}<br />
        }</span></p>

<p>Then run the batch file you should get 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">Type.registerNamespace(<span style="color:maroon">&#39;MyScriptSharp&#39;</span>);<br />
    <br />
    <span style="color:darkgreen">
    ////////////////////////////////////////////////////////////////////////////////<br />
    // MyScriptSharp.Class1<br />
    <br />
    </span>MyScriptSharp.Class1 = <span style="color:blue">function</span> 
    MyScriptSharp_Class1() {<br />
    }<br />
    MyScriptSharp.Class1.helloWorld = <span style="color:blue">function</span> 
    MyScriptSharp_Class1$helloWorld() {<br />
    <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">return</span>
    <span style="color:maroon">&#39;Hello World!&#39;</span>;<br />
    }<br />
    <br />
    MyScriptSharp.Class1.registerClass(<span style="color:maroon">&#39;MyScriptSharp.Class1&#39;</span>);</span></p>

<p>Obviously you could get these results faster with approach #1.  But now you have a lot more control.</p>

<p><b>Summary</b></p>

<p>The main downside to this approach is maintaining the batch file is a bit of a hassle.  But the upsides are that you can include any file from your server-side C# code.  And any changes in that server-side code are automatically reflected in your JavaScript.  And any breaking changes in your server-side code generate compile time errors in your client side code.  And furthermore none of your team members need to install Script#.  For our team it's an easy tradeoff.  What about for yours?  Please share your thoughts in the comments or on <a href="http://twitter.com/#!/lprichar">twitter</a>.</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/integrating_javascript_and_c_w.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/integrating_javascript_and_c_w.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">JavaScript</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">script#</category>
            
            <pubDate>Tue, 23 Aug 2011 23:09:48 -0500</pubDate>
        </item>
        
        <item>
            <title>Modeling multiple logical views of a document</title>
            <description><![CDATA[<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><b>Problem:</b></font><b>
</b><font size="3"><span style="font-weight: normal"> The domain model
contains the idea of a document, and one of the documents in the
model has multiple purposes. By purpose, I mean that the physical
document is filled out with different data depending on who the
document is for. Each purpose may or may not have different logic
associated with the creation. The document abstractions should be
easily testable to make document creation as robust as possible.</span></font></font></p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	</span></font><font size="3"><b>A
Solution: </b></font><font size="3"><span style="font-weight: normal">One
solution that I found was based on the template method from the GoF
book. The intent of this solution was to simplify the creation of the
known views of the document. The key idea of the solution is to put
as much of the logic involved in document creation into to the base
class. </span></font></font>
</p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	</span></font><font size="3"><b>Implementation:
</b></font></font>
</p>
<pre class="prettyprint">abstract class Document
{
	IDictionary<string, string=""> FormTextFields
	{
		get
		{
			return new Dictionary<string, string="">
			{
				{ "NameField", this.NameField },
				{ "AgeField", this.AgeField }
			};
		}
	}
	
	private string NameField
	{
		get
		{
			if(this.DocumentType == DocumentType.Big)
			{
				return "Big name";
			}
			else if(this.DocumentType == DocumentType.Small)
			{
				return "Small name";
			}
			
			return string.Empty;
		}
	}
	
	private string AgeField
	{
		get
		{
			if(this.DocumentType == DocumentType.Big)
			{
				return "42";
			}
			
			return string.Empty;
		}
	}
	
	protected abstract DocumentType DocumentType { get; }
}

class BigDocument : Document
{
	protected override DocumentType DocumentType
	{
		get
		{
			return DocumentType.Big;
		}
	}
}
</string,></string,></pre>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><b>	Benefits:
</b></font><font size="3"><span style="font-weight: normal">As
previously stated, the main purpose of the base class is to simplify
the creation of the subclasses. This solution does just that by
reducing the amount of work needed to create a new subclass. The
subclasses have only two main actions required for creation. The
first action is to define the type of the document which is an
abstract method in the base class. The second action, not shown in the subclass, is the
validation of the specific concrete document type. Just doing these
two actions, as oppose to adding new creation logic, speeds up the
creation of new subclasses.</span></font></font></p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	Two
other benefits to this solution are centralization of the logic for
document creation and having reduced unit testing needs for the subclasses.
When the logic of the document creation is centralized into a single
base class, reasoning about the document creation becomes easier. Problems arising from document creation are easier to track down. The
document base class becomes the focal point for the majority of  the
unit tests written for document creation. The focal point reduces the
need to test the subclasses since the vast majority of the behavior
is in the base.</span></font></font></p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	</span></font><font size="3"><b>Drawbacks:</b></font><font size="3"><span style="font-weight: normal">
A large drawback of placing all the logic relating to the document
creation in the base is that the rules for creation have to be
completely available. If the rules of the creation of the document
are not known then the base class will be incomplete. When the base
class is incomplete, it has to be reopened every time a new rule is
found. The problem of adding rules leads to the main drawback of the
solution: extensibility. This solution is in no way extensible since
all the logic is congregated in the base class. This drawback does
pose problems, however with a little rejiggering the impact of this
drawback can be minimized. One possible fix, that will reduce the
extensibility problem, but will increase the work to create a
subclass, is to add an abstract method to the base that filters the
dictionary before it is sent out.&nbsp;</span></font></font>
</p> 
<pre class="prettyprint">abstract class Document
{
	IDictionary<string, string=""> FormTextFields
	{
		get
		{
			return new Dictionary<string, string="">
			{
				{ "NameField", this.NameField },
				{ "AgeField", this.AgeField }
			};
		}
	}
	
	protected abstract IDictionary<string,string> FilterTextFields(IDictionary<string,string> textFields);
}

class SmallDocument : Document
{
	protected override IDictionare<string, string=""> FilterTextFields(IDictionary<string,string> textFields)
	{
		textFields["NameField"] = SmallLogic();
		return textFields;
	}
	
	protected override DocumentType DocumentType
	{
		get
		{
			return DocumentType.Small;
		}
	}
}
</string,string></string,></string,string></string,string></string,></string,></pre>]]></description>
            <link>http://www.nearinfinity.com/blogs/sean_howell/modeling_multiple_logical_view.html</link>
            <guid>http://www.nearinfinity.com/blogs/sean_howell/modeling_multiple_logical_view.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">General</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Domain modeling</category>
            
            <pubDate>Sun, 20 Feb 2011 21:49:24 -0500</pubDate>
        </item>
        
        <item>
            <title>Type-Safe Entity Framework Include</title>
            <description><![CDATA[<p>Unlike many ORM solutions MS Entity Framework does not lazy fetch accessed tables. Coming from LINQ to SQL I didn't like this feature at first because it meant adding a bunch of loosely typed include statements to every SQL call. But I quickly realized the performance benefits, not to mention the<a href="http://www.codeproject.com/Articles/102647/Select-Nplus1-Problem-How-to-Decrease-Your-ORM-Per.aspx">N+1</a> problem just goes away. But, I still had heartburn over the loose typing of the include statement, so I came up with my own include. But first to set the stage let me show you what you currently have to write.</p>

<pre class="prettyprint">
  ctx.Users.Include("Order.Item");
</pre>

<p>This will fetch all Users as well as all the items that they ordered.</p>

<p>To fix this we need to add some method to Users which is of type ObjectQuery. To do that we will use <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx">extension methods</a> to add my own include to ObjectQuery. Here is the code for that.</p>

<pre class="prettyprint">
public static class ObjectQueryExtensionMethods {
  public static ObjectQuery&lt;T&gt; Include&lt;T&gt;(this ObjectQuery&lt;T&gt; query, Expression&lt;Func&lt;T, object&gt;&gt; exp) {
    Expression body = exp.Body;
    MemberExpression memberExpression = (MemberExpression)exp.Body;
    string path = GetIncludePath(memberExpression);
    return query.Include(path);
  }

  private static string GetIncludePath(MemberExpression memberExpression) {
    string path = "";
    if (memberExpression.Expression is MemberExpression) {
      path = GetIncludePath((MemberExpression)memberExpression.Expression) + ".";
    }
    PropertyInfo propertyInfo = (PropertyInfo)memberExpression.Member;
    return path + propertyInfo.Name;
  }
}
</pre>

<p>Using C# expressions and extension methods we now can write this</p>

<pre class="prettyprint">
  ctx.Users.Include(u => u.Order.Item);
</pre>

<p>Refactor and type-safe</p>

<p>Entity Framework still has it's annoyances, but hopefully this will make it a little less painful. Now if it would only throw an exception if you tried to access a non-included entity instead of just returning null.</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/joe_ferner/type-safe_entity_framework_inc.html</link>
            <guid>http://www.nearinfinity.com/blogs/joe_ferner/type-safe_entity_framework_inc.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">EntityFramework</category>
            
            <pubDate>Thu, 18 Nov 2010 15:27:48 -0500</pubDate>
        </item>
        
        <item>
            <title>Death to the DAO and How to Test LINQ</title>
            <description><![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>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/death_to_the_dao_and_how_to_te.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/death_to_the_dao_and_how_to_te.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">architecture</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">LINQ</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">testing</category>
            
            <pubDate>Thu, 22 Jul 2010 22:42:43 -0500</pubDate>
        </item>
        
        <item>
            <title>ASP.AJAX 4 Templates Part 4 - jQuery, and Manual JSON Object Manipulation</title>
            <description><![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>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/aspajax_4_templates_part_4_-_j.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/aspajax_4_templates_part_4_-_j.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">AJAX</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">jQuery</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint 2010</category>
            
            <pubDate>Sat, 10 Apr 2010 14:03:06 -0500</pubDate>
        </item>
        
        <item>
            <title>Client Side AJAX Applications in SharePoint 2010 - Part 3</title>
            <description><![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>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_2.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">ADO.Net Data Services</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint 2010</category>
            
            <pubDate>Sun, 21 Mar 2010 22:17:25 -0500</pubDate>
        </item>
        
        <item>
            <title>Client Side AJAX Applications in SharePoint 2010 - Part 2</title>
            <description><![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>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications_1.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">ADO.Net Data Services</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Astoria</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint 2010</category>
            
            <pubDate>Sun, 21 Mar 2010 20:36:54 -0500</pubDate>
        </item>
        
        <item>
            <title>Client Side AJAX Applications in SharePoint 2010 - Part 1</title>
            <description><![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>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/client_side_ajax_applications.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">ADO.Net Data Services</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">AJAX</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint 2010</category>
            
            <pubDate>Sun, 21 Mar 2010 18:37:06 -0500</pubDate>
        </item>
        
        <item>
            <title>Sharepoint ASP .Net Ajax Configuration</title>
            <description><![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>]]></description>
            <link>http://www.nearinfinity.com/blogs/sean_howell/sharepoint_asp_net_ajax_configuration.html</link>
            <guid>http://www.nearinfinity.com/blogs/sean_howell/sharepoint_asp_net_ajax_configuration.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web Development</category>
            
            
            <pubDate>Tue, 02 Feb 2010 18:34:17 -0500</pubDate>
        </item>
        
        <item>
            <title>Ruby on Rails, a Microsoft Developer&apos;s Perspective</title>
            <description><![CDATA[<p>I suppose I'm a pretty hard core Microsoft developer.  I've been doing Microsoft .Net C# development since the .Net framework was first released in 2002.  Before that, starting in 1997 about when the technology was first released, I developed in Visual Basic with classic ASP (Active Server Pages).  So that's twelve years of Microsoft development all told.  Which is why the Ruby on Rails class I've been taking this week is so interesting.  Ruby represents a significant branching out for me.  So these are my initial impressions.  I am a complete Ruby neophyte, so please keep all flames at least friendly in tone :).</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2009/11/ruby-on-rails-microsoft-developers.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>Dynamic Typing</b></p>
<p>Let's get to the heart of this Ruby stuff.  I thought I would passionately hate dynamic typing.  I was getting ready to fill pages ranting about its evils.  But that moment never came.  Don't get me wrong the Visual Studio strongly typed intellisense no-reading-documentation-needed experience is far nicer than the NetBeans look-it-up-in-irb-with-.methods experience.  But the feeling was more like mild to moderate annoyance rather than unbridled hatred.  Like when I mistyped a variable and Ruby decided it was a new variable initialized as nil.  Annoying, and hard to track down, but hey I'm a Ruby newbie, experts probably don't make these mistakes, right?  Anyway, I would be interested to hear how non-trivial, well tested applications perform with refactoring (e.g. variables/fields in views?) and how bad things get during O&amp;M.</p>
<p><b>Speed of Development</b></p>
<p>I figured speed of development would be Ruby's saving grace.  It was that and more.  The Ctrl-S-Alt-Tab-Ctrl-R-zero-delay development cycle is frickin' amazing!  It made development feel more fun than it has in a long time.  Part of that may be the slower-than-molasses-in-December speed of development I experience today on my (not 2010) SharePoint project.  Regardless, even if I were working in an ASP.Net MVC project I suspect the extra speed of development in Rails by skipping the main compilation and JIT compilation steps would increase the enjoyment of a Ruby project enough to equal out the lack of strong typing.</p>
<p><b>Active Record vs LINQ</b></p>
<p>Perhaps I'm just not experienced enough with active record, but to me the syntax feels contrived, non-intuitive, and just kind of agitating.  I mean it's cool that you can write </p>
<p><code style="color: black">p = Person.find_all_by_first_name_and_last_name("Lee", "Richardson")</code>
</p>
<p>Ugly as sin, but cool.  The alternative doesn't feel much better: </p>
<p><code style="color: black">p = Person.all(:conditions => <br />&nbsp;&nbsp;&nbsp;&nbsp;{ :first_name => "Lee", :last_name => "Richardson" })</code>
</p>
<p>Uch.  Of course I am biased.  I'm passionate about LINQ.  I love LINQ more than any single feature in Microsoft development.  I think LINQ may be the most brilliant stroke of genius Microsoft (Anders Hejlsberg) has ever had.  And I don't think I realized how passionately I felt about the technology until I didn't have it.  So for me I'll stick with:</p>
<p><code style="color: black">Person p = ctx.People.Where(p => <br />&nbsp;&nbsp;&nbsp;&nbsp;p.FirstName == "Lee" && p.LastName == "Richardson");</code></p>
<br />
<p><b>Duck Typing</b></p>
<p>My mind was blown when the instructor showed us polymorphism without inheritance.  I can't argue about how incredibly powerful it is.  I just cringe to think of the potential misuse.  But without any real Ruby experience I'll have to just leave it at "Wow!"</p>
<p><b>Mocking</b></p>
<p>It's pretty scary that you can override the functionality of any method anywhere in Ruby.  But when the instructor showed us overriding DateTime.now for the purposes of mocking I had an "ah ha!" moment.  Mocking DateTime.Now in C# is an awful experience that involves an intermediate class with a virtual "Now()" method.  Ruby sure got C# on that one.</p>
<p><b>YAML</b></p>
<p>It's no secret that I passionately hate XML.  And it's no secret that Microsoft passionately loves XML.  Pity about the mismatch.  Ruby on Rails really endeared itself to me when its designers recognized that XML is a travesty against humanity and used <a href="http://en.wikipedia.org/wiki/Yaml">YAML Ain't Markup Language</a> instead.  Nice!</p>
<p><b>Interactive Ruby Console</b></p>
<p>The Interactive Ruby Console (IRB) is just wonderful.  Now I can at least get that functionality today in C# with <a href="http://www.nearinfinity.com/blogs/joe_ferner/">Joe Ferner's</a> excellent <a href="http://devtoolbox.codeplex.com/">Developer's Toolbox</a>.  What I can't get is the Interactive Rails Console (ruby script/console).  Now that is awesome.  I can't wait for C# 4.0 which I suspect will have this.  For now RoR++, C#-- .</p>
<p><b>Tooling</b></p>
<p>I'm not sure how related this is to dynamic typing, but surprisingly I really, really missed Visual Studio.  Perhaps RubyMine is better that NetBeans.  I sure wasn't impressed with Komodo.  I just felt like constantly switch between my IDE and various console windows, and a database viewer felt clumsy yet somehow necessary with Rails.  It just felt so 1999.</p>
<p><b>Summary</b></p>
<p>There's no doubt about it, I could be very happy on a Ruby project.  The no XML thing is just a perk, the fast development cycles and bringing fun back to coding again is truly awesome.  But am I ready to give up Microsoft development full time just yet?  No way.  LINQ, strong typing, and believe it or not Visual Studio tip the scales back to about equal.  Now if only Microsoft could somehow make compilation instantaneous.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/ruby_on_rails_a_microsoft_deve.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/ruby_on_rails_a_microsoft_deve.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">LINQ</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ruby</category>
            
            <pubDate>Wed, 18 Nov 2009 10:42:15 -0500</pubDate>
        </item>
        
        <item>
            <title>SharePoint 2010 Expectations Meet Reality</title>
            <description><![CDATA[<p>The current version of SharePoint and I have a love hate relationship.  Since I want to be able to look forward to a more joyful and fulfilling relationship with the tool/platform, I made a list of my biggest frustrations before I left for the SharePoint 2010 conference (<a href="http://www.bing.com/twitter/search?q=%23spc09&form=QB ">#spc09</a>).  My objective was to return with most of the items checked off as resolved and to have a bunch of new functionality that I hadn't realized I needed.  SharePoint 2010 easily fulfils the second promise with stuff like Business Data Services (Awesome!) and Visio Data Services (Amazing!).  But I don't want to try to recap the whole conference so here's just how it compares to my initial list:</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2009/10/sharepoint-2010-expectations-meet.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>Testability</b></p>
<p>SharePoint is <a href="http://rapidapplicationdevelopment.blogspot.com/2009/08/sharepoint-wild-west-of-software.html">notoriously hard to unit test</a>.  The good news is Microsoft provided a whole session devoted to software development best practices that included a good chunk on unit testing.  It was wonderful to see!</p>
<p>The bad news: SharePoint 2010 will not have public constructors and classes will still be sealed (final).  The good news to the bad news: After discussing this issue with Chris Keyser I discovered that Peli de Halleux of Microsoft Research has a free tool called <a href="http://research.microsoft.com/en-us/projects/pex/default.aspx">Pex</a> that solves the whole problem.  It allows what it calls detours, which allow you to mock non-virtual methods.  This stuff is amazing and I'll blog more about it later.</p>
<p>Summary: Testability is better even for existing SharePoint installs -- so between <a href=" http://sporm.codeplex.com/">Sporm</a> and Pex this is a non-issue -- I'm happy.</p>
<p><b>No Referential Integrity</b></p>
<p>It kills me that if you create an employee list item that references a company list item and you delete the company list item then nothing happens.  No cascading delete.  No error message.  Just an orphan record.  SharePoint 2010 now supports both true referential integrity through errors and cascading deletes!</p>
<p>Summary: Awesome!</p>
<p><b>Validation is Terrible</b></p>
<p>Ever tried to validate by pattern in SharePoint (e.g. social security number)?  How about range validate (e.g. date of birth can't be after today)?  Or maybe validate one field against another?  The answer is you can't.  Not easily or consistently.  If you handle validation in an event receiver then the user doesn't get the error until after a postback on a separate page.  And custom field controls are a lot of work and they don't work in datasheet view.</p>
<p>SharePoint 2010 mostly solves these validation issues by allowing field level and list level validation.  The error messages even show in datasheet view.  The bad news is that pattern matching is not currently supported (e.g. you can't validate social security number).</p>
<p>Summary: Good stuff, need to see the final version to be extremely happy.</p>
<p><b>Poor Documentation</b></p>
<p>Ever noticed that blogs give you better details on SharePoint APIs than MSDN does?  I don't even bother looking on MSDN for SharePoint content anymore.  Since the hands on labs didn't contain any documentation I'll have to refer to what Steve Ballmer said during the Q&A session, which was that better documentation will be a priority.</p>
<p>Summary: high hopes, but TBD.</p>
<p><b>Views Don't Allow Precedence</b></p>
<p>If you've ever needed a view with A and (B or C) and ended up with (A and B) or C, you know where I'm coming from.  As a developer you can implement precedence in CAML, but as an end user you're stuck.  Sadly this issue is still not fixed in SharePoint 2010.</p>
<p>Summary: Fail.</p>
<p><b>Re-Deployment is Hard</b></p>
<p>Currently redeploying lists is hard; redeploying web parts without overwriting user settings is hard; and redeploying workflows is very hard.</p>
<p>Without documentation and intermittent Internet <a href="http://www.nearinfinity.com/blogs/joe_ferner/">Joe Ferner</a> and I had a hard time manually confirming that this is better.  We also missed a key session on Thursday that talked about it.  There were some tweets that looked promising, but I'll have to wait until Thursday's presentations are posted to be able to comment for sure.</p>
<p>Summary: Good I think, but still TBD.</p>
<p><b>Massive Duplication in CAML Instantiated Lists</b></p>
<p>Using CAML to instantiate a list is currently awful in SharePoint.  It's like 5 pages of CDATA and HTML and XML with massive duplication.  Sadly SharePoint 2010 doesn't solve the root problem: list instantiation looks exactly the same.  The good news is that along with just about every other aspect of SharePoint 2010 development, Visual Studio makes this task mind numbingly easy to do.  If you can just try not to look in that file that was auto-generated for you, then you should be fine.</p>
<p>Summary: Better.</p>
<p><b>Poor Usability</b></p>
<p>Once you get used to the current version of SharePoint the user interface is extremely consistent and many users really like it.  But if you were to compare it to any modern Web 2.0 site it's a complete failure.  SharePoint 2010 does an excellent job of implementing selective refresh/AJAX/Web 2.0.  But to me it feels more complicated.  Maybe this is because it introduces the ribbon, which I have never liked.  Maybe it just is more complicated.  In any event I'm not the best judge of usability, so I'll have to wait and see what others say.</p>
<p>Summary: Definitely better, but jury's still out.</p>
<p><b>Can't Reference a List <i>AND</i> Content Type</b></p>
<p>Suppose you have a Calendar list.  The list supports two content types: Events, and Iterations (sprints).  It's a nice architecture because you want to view iterations and events in the same calendar views.  Now if you have a User Story list, wouldn't it be nice to have a lookup field that points only to Iterations?  Sadly you couldn't do this before and you won't be able to for the foreseeable future.</p>
<p>Summary: Fail.</p>
<p><b>CAML for Queries</b></p>
<p>Technically this wasn't on my list because I use <a href="http://sporm.codeplex.com">Sporm</a>, but on behalf of my non-spormified software development brethren let me say that writing <a href="http://rapidapplicationdevelopment.blogspot.com/2009/09/sporm-out-of-depths-of-sharepoints-xml.html">queries in CAML is awful</a>.</p>
<p>SharePoint 2010 makes enormous strides in this area.  I won't go into great detail, but you can now use LINQ on the server side <i>and on the client side</i>!</p>
<p>Summary: Awesome!</p>
<p><b>Summary</b></p>
<p>Lots of TBD, lots of awesomeness, still some fail.  Worth upgrading?  Absolutely.  Will it still be a love hate relationship?  Probably, but at the moment it's looking pretty darn good.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/sharepoint_2010_expectations_m.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/sharepoint_2010_expectations_m.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">LINQ</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">testing</category>
            
            <pubDate>Sat, 24 Oct 2009 01:26:55 -0500</pubDate>
        </item>
        
        <item>
            <title>Spell checking your SharePoint custom application pages</title>
            <description><![CDATA[<p>I had a requirement to spell check some fields on a custom application page and I knew SharePoint had the ability because on the edit item page there is a "Spelling" button.  Come to find out this is one of the easiest things to do and there is really no excuse to not include it on all of your application pages.</p>

<p>First step is to include the javascript needed to run the spell checking. You'll need two includes form.js and SpellCheckEntirePage.js.
</p>

<pre class="prettyprint">
&lt;script type="text/javascript" language="javascript" 
  src="/_layouts/1033/form.js?rev=df60y6YolDjUVbi91%2BZw%2Fg%3D%3D"&gt;&lt;/script&gt;
&lt;script type="text/javascript" language="javascript"
  src="/_layouts/1033/SpellCheckEntirePage.js?rev=zYQ05cOj5Dk74UkTZzEIRw%3D%3D"&gt;&lt;/script&gt;
</pre>

<p>When I saw SpellCheckEntirePage.js for the first time I had to laugh because my initial estimate of the task was 3-4 days, I ended up doing it in less than 4 hours.</p>

<p>Next step is to add the button to actually check the spelling.</p>
<pre class="prettyprint">
&lt;input type="button" value="Spell Check"
  onclick="javascript:SpellCheckEntirePage('<%= SPContext.Current.Web.Url %>/_vti_bin/SpellCheck.asmx', '<%= SPContext.Current.Web.Url %>/_layouts/SpellChecker.aspx');" /&gt;
</pre>

<p>
<b>Done!</b>
</p>

<p>
Well almost. There were a couple of fields on the form which didn't make sense to spell check. But looking at the source of SpellCheckEntirePage.js you can quickly find the solution.  Just add excludeFromSpellCheck="true" to the fields you don't want to check.
</p>

<p>
OK, now I'm done.
</p>

<p>
Well not quite yet. The "excludeFromSpellCheck" doesn't work on People pickers. But SharePoint has this problem too.  If you edit a list item with a people picker and run the spell checker it will try to spell check people's login names which is never going to work. I went ahead and added a method to my master page which turns spell check off for people picker fields. It fixed the edit list item spell checking problem too :).  I do have to warn you I suck at javascript so if anyone can send me a better way of doing this I would appreciate it.
</p>

<pre class="prettyprint">
function disableSpellCheckOnPeoplePickers() {
  var elements = document.body.getElementsByTagName("*");
  for (index = 0; index &lt; elements.length; index++) {
    if (elements[index].tagName == "INPUT"
        && elements[index].parentNode
        && elements[index].parentNode.tagName == "SPAN") {
      var elem = elements[index];
      if (elem.parentNode.getAttribute("NoMatchesText") != "") {
        disableSpellCheckOnPeoplePickersAllChildren(elem.parentNode);
      }
    }
  }
}

function disableSpellCheckOnPeoplePickersAllChildren(elem) {
  try {
    elem.setAttribute("excludeFromSpellCheck", "true");
    for (var i = 0; i &lt; elem.childNodes.length; i++) {
      disableSpellCheckOnPeoplePickersAllChildren(elem.childNodes[i]);
    }
  } catch (e) {
  }
}
</pre>
]]></description>
            <link>http://www.nearinfinity.com/blogs/joe_ferner/spell_checking_your_custom_lay.html</link>
            <guid>http://www.nearinfinity.com/blogs/joe_ferner/spell_checking_your_custom_lay.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">C#</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint</category>
            
            <pubDate>Tue, 29 Sep 2009 11:05:03 -0500</pubDate>
        </item>
        
        <item>
            <title>Sporm - Out of the Depths of SharePoint&apos;s XML Hell</title>
            <description><![CDATA[<p>In my last post I described how a new open source tool called <a href="http://sporm.codeplex.com/">sporm</a> significantly simplifies <a href=" http://rapidapplicationdevelopment.blogspot.com/2009/09/unit-testing-sharepoint-past-present.html">unit testing SharePoint</a>.  Making SharePoint unit testable is my absolute favorite feature of sporm because SharePoint is notoriously hard to unit test.  But sporm provides other benefits as well and its ability to pull us out of the depths of verbose loosely typed XML hell and into LINQ excellence is next on my list of favorite features.  So in this post I'll describe the pre-sporm technique of querying with CAML, how to query data using sporm, and finally how sporm supports SharePoint's unique architecture of allowing multiple content types per list and what that means to you.</p>

<p><b>Caml's Are Ugly</b></p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2009/09/sporm-out-of-depths-of-sharepoints-xml.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><i>Warning: if you're new to SharePoint then what you're about to see may shock and upset you.  If, like me, you hate both XML and loose typing then you will agree that CAML is awful, but bear with me I promise sporm will make it better.  Much better.</i></p>

<p>CAML or Collaborative Application Markup Language is how one queries for data in SharePoint.  A simple query might look like this:</p>

<p>        <span style="font-size:10.0pt;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;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">Query</span><span style="font-size:10.0pt;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">&gt;<br />        <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span style="font-size:10.0pt;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">Where</span><span style="font-size:10.0pt;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">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="font-size:10.0pt;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">And</span><span style="font-size:10.0pt;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">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="font-size:10.0pt;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">And</span><span style="font-size:10.0pt;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">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="font-size:10.0pt;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">Eq</span><span style="font-size:10.0pt;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">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="font-size:10.0pt;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">FieldRef</span><span style="font-size:10.0pt;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"> </span>        <span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;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;mso-no-proof:yes">Name</span><span style="font-size:10.0pt;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">=</span><span style="font-size:10.0pt;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">&#39;<span style="color:blue">First_Name</span>&#39;<span             style="color:blue"> /&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span             style="color:#A31515">Value</span><span style="color:blue"> </span>        <span style="color:red">Type</span><span style="color:blue">=</span>&#39;<span             style="color:blue">Text</span>&#39;<span style="color:blue">&gt;</span>Lee<span             style="color:blue">&lt;/</span><span style="color:#A31515">Value</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">Eq</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">BeginsWith</span><span style="color:blue">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span             style="color:#A31515">FieldRef</span><span style="color:blue"> </span>        <span style="color:red">Name</span><span style="color:blue">=</span>&#39;<span             style="color:blue">Last_Name</span>&#39;<span style="color:blue"> /&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span             style="color:#A31515">Value</span><span style="color:blue"> </span>        <span style="color:red">Type</span><span style="color:blue">=</span>&#39;<span             style="color:blue">Text</span>&#39;<span style="color:blue">&gt;</span>Rich<span             style="color:blue">&lt;/</span><span style="color:#A31515">Value</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">BeginsWith</span><span style="color:blue">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span style="color:#A31515">And</span><span style="color:blue">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span style="color:#A31515">Leq</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">FieldRef</span><span style="color:blue"> </span>        <span style="color:red">Name</span><span style="color:blue">=</span>&#39;<span             style="color:blue">Dob</span>&#39;<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">Value</span><span style="color:blue"> </span>        <span style="color:red">Type</span><span style="color:blue">=</span>&#39;<span             style="color:blue">DateTime</span>&#39;<span style="color:blue">&gt;</span>2009-01-01T00:00:00Z<span             style="color:blue">&lt;/</span><span style="color:#A31515">Value</span><span             style="color:blue">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span style="color:#A31515">Leq</span><span style="color:blue">&gt;<br />        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span style="color:#A31515">And</span><span            style="color:blue">&gt;<br />        <span style="mso-spacerun:yes">&nbsp; </span>&lt;/</span><span style="color:#A31515">Where</span><span             style="color:blue">&gt;<br />        &lt;/</span><span style="color:#A31515">Query</span><span style="color:blue">&gt;<br             style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>        <br style="mso-special-character:line-break" />        <![endif]></span></span>    </p>

<p>Simple right?  ;) In case you didn't catch the meaning from the slightly, uh verbose, query this asks for records with a First_Name of "Lee", a Last_Name starting with "Rich" and a "Dob" less than or equal January 1 2009.</p>

<p>There are a couple of things to note about this query:</p>

<ul>
<li>Field names are loosly typed.  If Dob were ever renamed to DateOfBirth the query would fail at runtime (probably during a demo to a customer, or if you're lucky during integration tests), but certainly not at compile time.</li>
<li>And is a binary operator.  This forces explicit precedence and removes the need for parenthesis, but at the cost of readability.</li>
<li>Types must be explicitly defined.  I guess this is necessary since it's XML, but somehow I just don't feel like this should be necessary.</li>
<li>It's XML.  Ok obviously, but the point is you have to type everything twice.  &lt;BeginsWith&gt; &lt;/BeginsWith&gt;.  Ouch, so verbose, so angley, I so hate XML.</li>
</ul>

<p>Now, there are tools that make this better.  U2U's free <a href=" http://www.u2u.be/Res/Tools/CamlQueryBuilder.aspx ">CAML Query Builder</a> tool significantly improves the experience of querying SharePoint data.</p>

<p><a href="http://3.bp.blogspot.com/_gez10dNhuPk/Sq2PcGTvHUI/AAAAAAAABqM/YB6rGTZrIpA/s1600-h/CamlQueryBuilder.jpg"><img style="WIDTH: 400px; HEIGHT: 268px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5381114842670112066" border="0" alt="" src="http://3.bp.blogspot.com/_gez10dNhuPk/Sq2PcGTvHUI/AAAAAAAABqM/YB6rGTZrIpA/s400/CamlQueryBuilder.jpg" /></a></p>

<p>But it makes you wonder if something is wrong when you need a tool to retrieve data from your data store.  Do you typically use tools to assist when you're writing SQL?  Probably not.  But like I said hang in there, sporm make things better.</p>

<p><b>Unlinq my Caml</b></p>

<p>If you were to write the same query as above using sporm it would look like this:</p>

<p>        <span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:#2B91AF;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">IQueryable</span><span style="font-size:10.0pt;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">&lt;<span style="color:#2B91AF">Employee</span>&gt; employees =         GetEmployees().Where(e =&gt;<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>e.FirstName ==        <span style="color:#A31515">&quot;Lee&quot;<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&amp;&amp; e.LastName.StartsWith(<span             style="color:#A31515">&quot;Rich&quot;</span>)<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&amp;&amp; e.Dob &lt;= <span style="color:blue">        new</span> <span style="color:#2B91AF">DateTime</span>(2009, 1, 1));<br             style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>        <br style="mso-special-character:line-break" />        <![endif]></span>    </p>

<p>Just a little easier to read than CAML, right?  A couple of things to note:</p>

<ul>
<li>Fields are strongly typed.  If you were to rename FirstName the compiler would catch every single instance at design time.</li>
<li>Operators are standard C# operators.  &&, .StartsWith(), and <= are all familiar and concise and use a standard, known precedence.</li>
<li>Types are standard C# types.  You never have to explicitly say that "Rich" is a string, it just is.</li>
<li>Your query is actual C# code.  The lambda (closure) and the fact that it uses <a href="http://rapidapplicationdevelopment.blogspot.com/2008/03/how-systemlinqwhere-really-works.html">deferred execution</a> might throw off a junior developer in some scenarios, but the query is readable and works exactly the same as if you were querying in memory objects or querying a database with LINQ to SQL or the Entity Framework.</li>
</ul>

<p>Nice!  What's beautiful about this is that sporm converts your C# directly into CAML using C# 3.0's <a href="http://rapidapplicationdevelopment.blogspot.com/2008/03/expression-trees-why-linq-to-sql-is.html">expression trees</a> feature.  What sporm can't convert to CAML it executes in memory transparently to you.  Sporm uses log4net and outputs its CAML queries to the console by default, so it is a good idea to watch the output if you're concerned about performance.</p>

<p>Now the following isn't relevant to the comparison with CAML, but I would be negligent if I didn't explain how the GetEmployees() function works.</p>

<p><b>SP != DB B/C of Content Types</b></p>

<p>First of all GetEmployees looks like this:</p>

<p>        <span style="font-size:10.0pt;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">private</span><span style="font-size:10.0pt;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:#2B91AF">IQueryable</span>&lt;<span style="color:#2B91AF">Employee</span>&gt;         GetEmployees() {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">return</span>        <span style="color:#2B91AF">MySPDataContext<br />        </span><span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetCurrent()<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetList&lt;<span             style="color:#2B91AF">Employees</span>&gt;()<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.OfType&lt;<span             style="color:#2B91AF">Employee</span>&gt;();<br />        }<br style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>        <br style="mso-special-character:line-break" />        <![endif]></span>   </p>

<p>How it works is that the static GetCurrent() method retrieves sporm's context object, which knows how to query a SharePoint site, from either the web context or thread local storage; next the GetList() method tells sporm which list you want to query; and the OfType() method tells sporm which content type within the list you want to query.  This last part is important because sporm supports SharePoint's ability to have multiple content types per list, which other LINQ providers like LINQ to SharePoint do not.  But what are content types and why should you care?</p>

<p>SharePoint's List/Content Type architecture seems odd at first, but it allows interesting scenarios not available in a traditional database.  For instance you might have a calendar list that contains multiple types of records (list items) in the same list.  Your calendar list might contain some combination of the following three record types: meetings with unique fields like Organizer (a person); iterations with unique fields like DeployedToProduction (a Boolean); and actions with unique fields like RelatedEmployee (a reference to another list).  This architecture allows SharePoint to view all three types of records in a single view: like a per month calendar view.  The data might look like this:</p>

<table border="1">
<tr>
<td><b>Title</b></td>
<td><b>Start</b></td>
<td><b>End</b></td>
<td><b>ContentType</b></td>
<td><b>Organizer</b></td>
<td><b>Deployed To Production</b></td>
<td><b>Related Employee</b></td>
</tr>
<tr>
<td>Iteration16</td>
<td>1/12/09</td>
<td>1/19/09</td>
<td>Iteration</td>
<td>&nbsp;</td>
<td>false</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Stakeholder Demo</td>
<td>1/19/09 3 PM</td>
<td>&nbsp;</td>
<td>Meeting</td>
<td>Lee Richardson</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Tag Trunk</td>
<td>1/19/09</td>
<td>&nbsp;</td>
<td>Action</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>Lee Richardson</td>
</tr>
</table>

<p>Sporm's unique architecture supports this scenario by allowing you to retrieve iterations like this:</p>

<p>        <span style="font-size:10.0pt;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">return</span><span style="font-size:10.0pt;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:#2B91AF">MySPDataContext<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetCurrent()<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetList&lt;<span style="color:#2B91AF">Calendar</span>&gt;()<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.OfType&lt;<span style="color:#2B91AF">Iteration</span>&gt;();<br             style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>        <br style="mso-special-character:line-break" />        <![endif]></span>    </p>

<p>Or get meetings from the same list like this:</p>

<p>        <span style="font-size:10.0pt;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">return</span><span style="font-size:10.0pt;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:#2B91AF">MySPDataContext<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetCurrent()<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetList&lt;<span style="color:#2B91AF">Calendar</span>&gt;()<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.OfType&lt;<span style="color:#2B91AF">Meeting</span>&gt;();<br             style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>      <br style="mso-special-character:line-break" />        <![endif]></span>    </p>

<p>While you may only use multiple content types per list occasionally you can feel comfortable knowing that sporm will support you when you need it.  The rest of the time you can arrange your architecture to accommodate your 90% scenario of one content type per list.  I'll discuss the architecture I'm using on my current project in my next post.</p>

<p>For now I hope this has clarified some of the benefits of using sporm, and I hope that you'll consider using it on your next SharePoint project.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/sporm_-_out_of_the_depths_of_s.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/sporm_-_out_of_the_depths_of_s.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">LINQ</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint</category>
            
            <pubDate>Sun, 13 Sep 2009 21:10:03 -0500</pubDate>
        </item>
        
        <item>
            <title>Why I dislike TFS - Team Foundation Server</title>
            <description><![CDATA[<p>I don't usually blog about subjective things like my likes and dislikes, and I usually like (some will say I am in love with) Microsoft, but TFS is just horrible.</p>

<p>Here is a list of why I don't like it, in no particular order:</p>

<ul>
<li><strong>CodePlex</strong> -- First there was the SVN bridge (yes, someone hated TFS enough to make a product to make it look like something else) then Microsoft just caved and supported SVN directly. Not really a problem with TFS, it's just an indication that others feel the same way as I do.</li>
<li><strong>Size</strong> -- I guess Microsoft doesn't really like it either since they don't even ship it with Visual Studios, if you do need it, its a separate download and a big one at that -- 200MB+. Subversion, Tortoise SVN, and Ankh on the other hand combined are less than 15MB. How they filled up 200MB I have no idea, maybe they installed a client that doesn't suck somewhere I don't know about.</li>
<li><strong>Read-only Files</strong> -- Every file on your system is read-only. Why does everything need to be read-only. If I'm in another editor and I want to make a change to a file, I need to switch over to VS and check out a file for edit. This is rediculous.</li>
<li><strong>Identical Files</strong> -- I just want to see what changed. Why does TFS insist upon showing me all the files even if they are identical. Call me crazy but I like to see what files I actually changed when I check in. Someone told me there is some command line tool to see this but that's just silly.</li>
<li><strong>Code reviews/update</strong> -- On my current project I'm the project lead and I like to review the junior developers code when I update my code. Yeah, I can't do that, or I haven't found the button yet. Nor can I find the button to view a particular revision without finding a file that was part of that change and viewing it's history.</li>
<li><strong>Deleted files</strong> -- Team Explorer doesn't show them by default. This took me a while to figure this one out. You need to go into VS options then find TFS and then click show deleted files. Why is this not on by default and why isn't there a button to toggle this setting in Team Explorer.</li>
<li><strong>Project file modification</strong> -- We have some people working inside a VPN and some out, the TFS server name is different depending on where you sit. Since the solution file stores the connection string to TFS it's constantly getting checked in.</li>
<li><strong>Everything needs to be in the solution</strong> -- If you have a bunch of support files or non-.NET files, all of them need to be added to the solution or they don't get checked in or out. VS doesn't help you with this either because you can't have a solution folder map to a directory.</li>
<li><strong>Integrating with non-.NET developers</strong> -- If you have a mixed development environment (Java, Ruby, etc) like we do. You need to run TFS and something else because all the non-.NET developers can't use TFS especially if they are on a Mac. Usually the something else is much better anyway so you might as well use that instead.</li>
<li><strong>Working offline/Speed</strong> -- If you ever travel relax and take a nap because you won't be developing. Everything you do talks to the server and that in turn makes it slow. Open up a file and start making changes, to the server you go.  Move a file, to the server you go. Diff a change you made, to the server you go.</li>
<li><strong>Workspaces</strong> -- Who ever came up with the concept of workspaces at Microsoft should be ashamed of him/herself. They are just a stupid idea. If you want two copies of the same project checked out (I do it with SVN if I'm working on a quick bug fix and a big feature at the same time) good luck because I can't figure it out.</li>
<li><strong>Server isn't free</strong> -- 'Nuff said.</li>
</ul>

<p>I'm sure there are other problems but this is all I could think of while writing this.</p>

<p>Sure there are some nice things about TFS, but honestly the cons far outweigh the pros. So if you have to decide which SCM to use and you run across this blog I think it's pretty obvious that I don't recommend it. I love SVN and as GIT (tools) mature I'm sure I will switch to that.</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/joe_ferner/why_i_dislike_tfs_-_team_found.html</link>
            <guid>http://www.nearinfinity.com/blogs/joe_ferner/why_i_dislike_tfs_-_team_found.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">TFS</category>
            
            <pubDate>Wed, 09 Sep 2009 18:43:05 -0500</pubDate>
        </item>
        
        <item>
            <title>Unit Testing SharePoint - Past, Present, and Sporm</title>
            <description><![CDATA[<p>As I described in <a href=" http://rapidapplicationdevelopment.blogspot.com/2009/08/sharepoint-wild-west-of-software.html">SharePoint: The Wild West of Software Development</a> there is a serious problem when you develop for SharePoint: ensuring quality through unit testing is really, really hard.  And that's where a new open source tool just released today called <a href=" http://sporm.codeplex.com/ ">sporm</a> (SharePoint Object Relational Mapper) comes in.  While sporm provides many benefits besides simplified unit testing I wanted to focus on this topic first, because sporm's approach, which models the <a href="http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx">entity framework</a> in the way it supports POCO's, is a unique feature not available with other SharePoint tools like LINQ to SharePoint.</p>

<div style='float:right; margin-left:10px;'>
<script type='text/javascript'>
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2009/09/unit-testing-sharepoint-past-present.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>I'll start by describing the unit testing problem, then provide a conventional solution with mocking, then finish with the elegance of a sporm based solution.</p>

<p><b>Simple Unit Testing Turns Ugly</b></p>

<p>I would bet anyone that attempts to develop a tiered solution with SharePoint ends up with entities that look something like this:</p>

<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:normal;mso-layout-grid-align:none;text-autospace:none">        <span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;color:blue;mso-no-proof:yes">public</span><span             style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-no-proof:yes">        <span style="color:blue">class</span> <span style="color:#2B91AF">Employee</span>         {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:blue">public</span> <span style="color:#2B91AF">SPListItem</span>         ListItem { <span style="color:blue">get</span>; <span style="color:blue">private</span>        <span style="color:blue">set</span>; }<br />        <br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> </span>        <span style="color:gray">&lt;summary&gt;<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> The constructor         requires that you pass in a list item        <br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> that is used by         your strongly typed properties<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> </span>        <span style="color:gray">&lt;/summary&gt;<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:blue">public</span> Employee(<span style="color:#2B91AF">SPListItem</span>         listItem) {<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;        </span>ListItem = listItem;<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />        <br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> </span>        <span style="color:gray">&lt;summary&gt;<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> This provides your         entities strong typing to hide        <br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> the native weak         typing in SharePoint<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:gray">///</span><span style="color:green"> </span>        <span style="color:gray">&lt;/summary&gt;<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="color:blue">public</span> <span style="color:blue">virtual</span>        <span style="color:blue">string</span> LastName {<br />      <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;        </span><span style="color:blue">get</span> { <span style="color:blue">return</span>         (<span style="color:blue">string</span>)ListItem[<span style="color:#A31515">&quot;LastName&quot;</span>];         }<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;        </span><span style="color:blue">set</span> { ListItem[<span             style="color:#A31515">&quot;LastName&quot;</span>] = <span style="color:blue">value</span>;         }<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />        }<br style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>        <br style="mso-special-character:line-break" />        <![endif]><o:p></o:p></span>    </p>

<p>And if you have some function that you'd like to unit test like this:</p>

<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:gray;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">///</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:green;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes"> </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:gray;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">&lt;summary&gt;<br />        ///</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:green;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes"> Typically returns &quot;[LastName], [FirstName]&quot; but skips        <br />        </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:gray;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">///</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:green;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes"> the comma if either is missing<br />        </span>        <span style="font-size:10.0pt;line-height:115%;font-family:&quot;Courier New&quot;;o-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;color:gray;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">///</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:green;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes"> </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:gray;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">&lt;/summary&gt;<br />        </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:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">public</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:blue">string</span> GetNameFormatted() {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">bool</span>         noFirst = <span style="color:blue">string</span>.IsNullOrEmpty(FirstName);<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">bool</span>         noLast = <span style="color:blue">string</span>.IsNullOrEmpty(LastName);<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">if</span>         (noFirst &amp;&amp; noLast) <span style="color:blue">return</span>        <span style="color:#A31515">&quot;&quot;</span>;<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">if</span>         (noFirst) <span style="color:blue">return</span> LastName;<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">if</span>         (noLast) <span style="color:blue">return</span> FirstName;<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">return</span>        <span style="color:blue">string</span>.Format(<span style="color:#A31515">&quot;{0},         {1}&quot;</span>, LastName, FirstName);<br />        }<br />        <br style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>        <br style="mso-special-character:line-break" />        <![endif]></span>    </p>

<p>Now you face a major problem: LastName is tightly coupled with SPListItem.  And SPListItem only contains internal constructors making it unmockable.  So if you keep the tight coupling and pass an SPListItem into the constructor then you need a connection to SharePoint and an employee list (table) and you need to create an employee list item (record), then you test it, and finally you ought to clean up after yourself and delete the list item.  Talk about a simple unit test turned fragile integration test.  Yuck.</p>

<p><b>Mocking the Solution</b></p>

<p>So at this point you're undoubtedly thinking it's time to mock.  To do this you'll have to make a public constructor that takes no arguments and mark your properties virtual.  Then you can write a test like this:</p>

<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;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">[<span style="color:#2B91AF">TestMethod</span>]<br />        <span style="color:blue">public</span> <span style="color:blue">void</span>         TestGetNameFormatted_FirstAndLastExist_LastCommaFirst() {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">        MockRepository</span> mocks = <span style="color:blue">new</span>        <span style="color:#2B91AF">MockRepository</span>();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">Employee</span>         mockEmployee = mocks.StrictMock&lt;<span style="color:#2B91AF">Employee</span>&gt;();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">Expect</span>.Call(mockEmployee.FirstName).Return(<span             style="color:#A31515">&quot;Lee&quot;</span>).Repeat.Any();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">Expect</span>.Call(mockEmployee.LastName).Return(<span             style="color:#A31515">&quot;Richardson&quot;</span>).Repeat.Any();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mocks.ReplayAll();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">string</span>         actual = mockEmployee.GetNameFormatted();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>mocks.VerifyAll();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">Assert</span>.AreEqual(<span             style="color:#A31515">&quot;Richardson, Lee&quot;</span>, actual);<br />        }</span></p>

<p>And then if you're like me you absolutely hate your unit tests.  Because let alone that you had to modify your production code to accommodate unit testing, more importantly your unit tests are now unreadable.  All of them.  Even in simple methods without dependencies your unit tests contain almost as much plumbing code as actual test code.  Enter sporm.</p>

<p><b>Unmocking with Sporm</b></p>

<p>Sporm is an open source tool released on codeplex that was developed by fellow <a href="http://www.nearinfinity.com/">Near Infinity</a> employee <a href=" http://www.nearinfinity.com/blogs/joe_ferner/ ">Joe Ferner</a> (who, incidentally, is one of the most brilliant developers I know).  While this is a version 1.0 product Joe has been using it on his project and independently I've been using it on my project for several months now, so it is relatively mature.</p>

<p>So how it works is that at design time sporm will read from your SharePoint site and generate partial classes for each of your list items and each of your content types.  The generated classes don't inherit from anything, giving you the ability architect your solution how you see fit.  And the properties are auto-properties, making the classes just pure POCO.  Here's an example if you're interested:</p>

<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;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">[<span style="color:#2B91AF">SPOrmContentType</span>(Name=<span             style="color:#A31515">&quot;Employee&quot;</span>)]<br />        <span style="color:blue">public</span> <span style="color:blue">partial</span>        <span style="color:blue">class</span> <span style="color:#2B91AF">Employee</span>         : <span style="color:#2B91AF">ISPOrmContentType</span> {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>        <span style="color:blue">static</span> <span style="color:blue">class</span>        <span style="color:#2B91AF">FieldTitles</span> {<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>        <span style="color:blue">const</span> <span style="color:blue">string</span>         FirstName = <span style="color:#A31515">&quot;First Name&quot;</span>;<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />        <br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>        <span style="color:blue">static</span> <span style="color:blue">class</span>        <span style="color:#2B91AF">FieldStaticName</span> {<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>        <span style="color:blue">const</span> <span style="color:blue">string</span>         FirstName = <span style="color:#A31515">&quot;FirstName&quot;</span>;<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />        <br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[<span style="color:#2B91AF">SPOrmIdField</span>()]<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>        <span style="color:blue">virtual</span> <span style="color:blue">int</span> Id {        <span style="color:blue">get</span>; <span style="color:blue">set</span>; }<br />        <br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[<span style="color:#2B91AF">SPOrmField</span>(Title         = <span style="color:#2B91AF">FieldTitles</span>.FirstName, StaticName =        <span style="color:#2B91AF">FieldStaticName</span>.FirstName)]<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>      <span style="color:blue">virtual</span> <span style="color:blue">string</span>         FirstName { <span style="color:blue">get</span>; <span style="color:blue">set</span>;         }<br />        }<br style="mso-special-character:line-break" />        <![if !supportLineBreakNewLine]>        <br style="mso-special-character:line-break" />        <![endif]></span>    </p>

<p>Since generated entities look like that, your entities can now look like this:</p>

<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">public</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:blue">partial</span>        <span style="color:blue">class</span> <span style="color:#2B91AF">Employee</span>         {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>        <span style="color:blue">string</span> GetNameFormatted() {<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">bool</span>         noFirst = <span style="color:blue">string</span>.IsNullOrEmpty(FirstName);<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">bool</span>         noLast = <span style="color:blue">string</span>.IsNullOrEmpty(LastName);<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">...<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />        }</span></p>

<p>Now if that isn't a picture of beauty to you then you haven't been working with SharePoint.  But wait, I hear you asking, how does this have anything to do with SharePoint?  How would an instance of an employee be able to retrieve the data in a SharePoint ListItem?  The answer is in the DataContext.  In your production code you write something like this:</p>

<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">public</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:blue">static</span>         Employee FindById(<span style="color:blue">int</span> id) {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">return</span>        <span style="color:#2B91AF">MySPDataContext<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetCurrent()<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.GetList&lt;TList&gt;()<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.OfType&lt;TContentType&gt;()<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.FirstOrDefault(c =&gt; c.Id ==         id);<br />        }</span></p>

<p>While it might not look so pretty at first you can hide these details in a base type and the nice thing is that it does handle SharePoint's ability to have multiple content types per list (which LINQ to SharePoint does not do, incidentally).  But for now all you need to know is that when you return an Employee thorugh MySPDataContext it subtypes your Employee class and returns you a proxy at runtime.  The proxy overrides each property to return you the appropriate value in the SPListItem.  And if you instantiate an Employee directly (as you would in unit testing) then you can use it like a pure POCO.  If you're familiar with the entity framework this should sound extremely similar.  The result is that you can write your unit tests like this:</p>

<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;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;mso-no-proof:yes">[<span style="color:#2B91AF">TestMethod</span>]<br />        <span style="color:blue">public</span> <span style="color:blue">void</span>         TestGetNameFormatted_FirstAndLastExist_CommaSeparate() {<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">Employee</span>         employee = <span style="color:blue">new</span> <span style="color:#2B91AF">        Employee</span> {<br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>FirstName =        <span style="color:#A31515">&quot;Lee&quot;</span>,        <br />        <span style="mso-tab-count:2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LastName =        <span style="color:#A31515">&quot;Richardson&quot;<br />        </span><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>};<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">string</span>         actual = employee.GetNameFormatted();<br />        <span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:#2B91AF">Assert</span>.AreEqual(<span             style="color:#A31515">&quot;Richardson, Lee&quot;</span>, actual);<br />        }</span></p>

<p>No SharePoint dependencies.  No mocking.  Nothing but pure, unadulterated unit test.  Now that a thing of beauty.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/lee_richardson/unit_testing_sharepoint_-_past.html</link>
            <guid>http://www.nearinfinity.com/blogs/lee_richardson/unit_testing_sharepoint_-_past.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">SharePoint</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">testing</category>
            
            <pubDate>Wed, 09 Sep 2009 15:44:18 -0500</pubDate>
        </item>
        
    </channel>
</rss>

