<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
   <channel>
      <title>Superexpert Blog</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=874ca9249aa4965241676885c8cac652</link>
      <atom:link rel="next" href="http://pipes.yahoo.com/pipes/pipe.run?_id=874ca9249aa4965241676885c8cac652&amp;_render=rss&amp;page=2" />
      <pubDate>Fri, 24 May 2013 04:57:58 +0000</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Superexpert" /><feedburner:info uri="superexpert" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
         <title>Good Book for Learning Meteor: Discover Meteor</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/NePSeBy4KhY/good-book-for-learning-meteor-discover-meteor.aspx</link>
         <description>A week or so ago, Sacha Greif asked me whether I would be willing to write a review of his new book on Meteor (published today) entitled Discover Meteor. Sacha wrote the book with Tom Coleman. Both Sacha and Tom are very active in the Meteor community – they are responsible for several well-known Meteor [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=807</guid>
         <pubDate>Tue, 07 May 2013 19:33:40 +0000</pubDate>
         <content:encoded><![CDATA[<p>A week or so ago, Sacha Greif asked me whether I would be willing to write a review of his new book on Meteor (published today) entitled <i>Discover Meteor</i>. Sacha wrote the book with Tom Coleman. Both Sacha and Tom are very active in the Meteor community – they are responsible for several well-known Meteor packages and projects including Atmosphere, Meteorite, meteor-router and Telescope &#8212; so I suspected that their book would be good.
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/05/clip_image0021.jpg"><img title="clip_image002" style="border-top:0px;border-right:0px;border-bottom:0px;margin:15px 0px 15px 35px;border-left:0px;display:inline;" border="0" alt="clip_image002" align="right" src="http://stephenwalther.com/wp-content/uploads/2013/05/clip_image002_thumb1.jpg" width="244" height="188"></a>
<p>If you have not heard of Meteor, Meteor is a new framework for building web applications which is built on top of Node.js. Meteor excels at building a new category of constantly-connected, real-time web applications. It has some jaw-dropping features which I described in a previous blog entry:
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/archive/2013/03/18/an-introduction-to-meteor.aspx">http://stephenwalther.com/archive/2013/03/18/an-introduction-to-meteor.aspx</a>
<p>So, I am super excited about Meteor. Unfortunately, because it is evolving so quickly, learning how to write Meteor applications can be challenging. The official documentation at Meteor.com is good, but it is too basic.
<p>I’m happy to report that Discovering Meteor is a really good book:
<p>· <b>The book is a fun read</b>. The writing is smooth and I read through the book from cover to cover in a single Saturday afternoon with pleasure.
<p>· <b>The book is well organized.</b> It contains a walk-through of building a social media app (Microscope). Interleaved through the app building chapters, it contains tutorial chapters on Meteor features such as deployment and reactivity.
<p>· <b>The book covers several advanced topics which I have not seen covered anywhere else</b>. The chapters on publications and subscriptions, routing, and animation are especially good. I came away from the book with a deeper understanding of all of these topics.
<p>I wish that I had read <i>Discover Meteor</i> a couple of months ago and it would have saved me several weeks of reading Stack Overflow posts and struggling with the Meteor documentation
<p>If you want to buy <i>Discover Meteor</i>, the authors gave me the following link which provides you with a 20% discount:
<p><a rel="nofollow" target="_blank" href="http://discovermeteor.com/orionids">http://discovermeteor.com/orionids</a><style>.aab5{}</style><div class="aab5">same day <a rel="nofollow" target="_blank" href="http://t0inpaydayloans.com/">payday loans</a></div> 
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=DW9F6xiWIyE:OnqAhNxSWzg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/DW9F6xiWIyE" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/NePSeBy4KhY" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/DW9F6xiWIyE/good-book-for-learning-meteor-discover-meteor.aspx</feedburner:origLink></item>
      <item>
         <title>April 2013 Release of the Ajax Control Toolkit</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/LXUrJHEMgR8/april-2013-release-of-the-ajax-control-toolkit.aspx</link>
         <description>I’m excited to announce the April 2013 release of the Ajax Control Toolkit. For this release, we focused on improving two controls: the AjaxFileUpload and the MaskedEdit controls. You can download the latest release from CodePlex at http://AjaxControlToolkit.CodePlex.com or, better yet, you can execute the following NuGet command within Visual Studio 2010/2012: There are three [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=798</guid>
         <pubDate>Tue, 30 Apr 2013 15:14:44 +0000</pubDate>
         <content:encoded><![CDATA[<p>I’m excited to announce the April 2013 release of the Ajax Control Toolkit. For this release, we focused on improving two controls: the AjaxFileUpload and the MaskedEdit controls.
<p>You can download the latest release from CodePlex at <a rel="nofollow" target="_blank" href="http://AjaxControlToolkit.CodePlex.com">http://AjaxControlToolkit.CodePlex.com</a> or, better yet, you can execute the following NuGet command within Visual Studio 2010/2012:
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image002.jpg"><img title="clip_image002" style="border-top:0px;border-right:0px;border-bottom:0px;border-left:0px;display:inline;" border="0" alt="clip_image002" src="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image002_thumb.jpg" width="784" height="84"></a>
<p>There are three builds of the Ajax Control Toolkit: .NET 3.5, .NET 4.0, and .NET 4.5.<br />
<h3>A Better AjaxFileUpload Control</h3>
<p>We completely rewrote the AjaxFileUpload control for this release. We had two primary goals.
<p>First, we wanted to support uploading really large files. In particular, we wanted to support uploading multi-gigabyte files such as video files or application files.
<p>Second, we wanted to support showing upload progress on as many browsers as possible. The previous version of the AjaxFileUpload could show upload progress when used with Google Chrome or Mozilla Firefox but not when used with Apple Safari or Microsoft Internet Explorer. The new version of the AjaxFileUpload control shows upload progress when used with any browser.<br />
<h4>Using the AjaxFileUpload Control</h4>
<p>Let me walk-through using the AjaxFileUpload in the most basic scenario. And then, in following sections, I can explain some of its more advanced features.
<p>Here’s how you can declare the AjaxFileUpload control in a page:
<pre>&lt;ajaxToolkit:ToolkitScriptManager runat="server" /&gt;

&lt;ajaxToolkit:AjaxFileUpload 
    ID="AjaxFileUpload1"
    AllowedFileTypes="mp4"
    OnUploadComplete="AjaxFileUpload1_UploadComplete" 
    runat="server" /&gt;

</pre>
<p>The exact appearance of the AjaxFileUpload control depends on the features that a browser supports. In the case of Google Chrome, which supports drag-and-drop upload, here’s what the AjaxFileUpload looks like: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image003.png"><img title="clip_image003" style="border-top:0px;border-right:0px;border-bottom:0px;border-left:0px;display:inline;" border="0" alt="clip_image003" src="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image003_thumb.png" width="644" height="317"></a> </p>
<p>Notice that the page above includes two Ajax Control Toolkit controls: the AjaxFileUpload and the ToolkitScriptManager control. You always need to include the ToolkitScriptManager with any page which uses Ajax Control Toolkit controls. </p>
<p>The AjaxFileUpload control declared in the page above includes an event handler for its UploadComplete event. This event handler is declared in the code-behind page like this:
<pre>protected void AjaxFileUpload1_UploadComplete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e) {
    // Save uploaded file to App_Data folder
    AjaxFileUpload1.SaveAs(MapPath("~/App_Data/" + e.FileName));
} 

</pre>
<p>This method saves the uploaded file to your website’s App_Data folder. I’m assuming that you have an App_Data folder in your project – if you don’t have one then you need to create one or you will get an error. </p>
<p>There is one more thing that you must do in order to get the AjaxFileUpload control to work. The AjaxFileUpload control relies on an HTTP Handler named AjaxFileUploadHandler.axd. You need to declare this handler in your application’s root web.config file like this:
<pre>&lt;configuration&gt;
  &lt;system.web&gt;
    &lt;compilation debug="true" targetFramework="4.5" /&gt;
    &lt;httpRuntime targetFramework="4.5" maxRequestLength="42949672" /&gt;
    &lt;httpHandlers&gt;
      &lt;add verb="*" path="AjaxFileUploadHandler.axd" type="AjaxControlToolkit.AjaxFileUploadHandler, AjaxControlToolkit"/&gt;
    &lt;/httpHandlers&gt;
  &lt;/system.web&gt;
  &lt;system.webServer&gt;
    &lt;validation validateIntegratedModeConfiguration="false"/&gt;
    &lt;handlers&gt;
      &lt;add name="AjaxFileUploadHandler" verb="*" path="AjaxFileUploadHandler.axd" type="AjaxControlToolkit.AjaxFileUploadHandler, AjaxControlToolkit"/&gt;
    &lt;/handlers&gt;
    &lt;security&gt;
      &lt;requestFiltering&gt;
        &lt;requestLimits maxAllowedContentLength="4294967295"/&gt;
      &lt;/requestFiltering&gt;
    &lt;/security&gt;
  &lt;/system.webServer&gt;
&lt;/configuration&gt;

</pre>
<p>Notice that the web.config file above also contains configuration settings for the maxRequestLength and maxAllowedContentLength. You need to assign large values to these configuration settings &#8212; as I did in the web.config file above &#8212; in order to accept large file uploads. </p>
<h4>Supporting Chunked File Uploads</h4>
<p>Because one of our primary goals with this release was support for large file uploads, we added support for client-side chunking. When you upload a file using a browser which fully supports the HTML5 File API &#8212; such as Google Chrome or Mozilla Firefox &#8212; then the file is uploaded in multiple chunks. </p>
<p>You can see chunking in action by opening F12 Developer Tools in your browser and observing the Network tab: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image005.jpg"><img title="clip_image005" style="border-top:0px;border-right:0px;border-bottom:0px;border-left:0px;display:inline;" border="0" alt="clip_image005" src="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image005_thumb.jpg" width="570" height="484"></a> </p>
<p>Notice that there is a crazy number of distinct post requests made (about 360 distinct requests for a 1 gigabyte file). Each post request looks like this: </p>
<p>http://localhost:24338/AjaxFileUploadHandler.axd?contextKey={DA8BEDC8-B952-4d5d-8CC2-59FE922E2923}&amp;fileId=B7CCE31C-6AB1-BB28-2940-49E0C9B81C64</p>
<p>&amp;fileName=Sita_Sings_the_Blues_480p_2150kbps.mp4&amp;chunked=true&amp;firstChunk=false </p>
<p>Each request posts another chunk of the file being uploaded. Notice that the request URL includes a chunked=true parameter which indicates that the browser is breaking the file being uploaded into multiple chunks. </p>
<h4>Showing Upload Progress on All Browsers</h4>
<p>The previous version of the AjaxFileUpload control could display upload progress only in the case of browsers which fully support the HTML5 File API. The new version of the AjaxFileUpload control can display upload progress in the case of all browsers. </p>
<p>If a browser does not fully support the HTML5 File API then the browser polls the server every few seconds with an Ajax request to determine the percentage of the file that has been uploaded. This technique of displaying progress works with any browser which supports making Ajax requests. </p>
<p>There is one catch. Be warned that this new feature only works with the .NET 4.0 and .NET 4.5 versions of the AjaxControlToolkit. To show upload progress, we are taking advantage of the new ASP.NET <a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.web.httprequest.getbufferedinputstream.aspx">HttpRequest.GetBufferedInputStream()</a> and <a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/ff406798.aspx">HttpRequest.GetBufferlessInputStream()</a> methods which are not supported by .NET 3.5. </p>
<p>For example, here is what the Network tab looks like when you use the AjaxFileUpload with Microsoft Internet Explorer: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image007.jpg"><img title="clip_image007" style="border-top:0px;border-right:0px;border-bottom:0px;border-left:0px;display:inline;" border="0" alt="clip_image007" src="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image007_thumb.jpg" width="644" height="294"></a> </p>
<p>Here’s what the requests in the Network tab look like: </p>
<p>GET /WebForm1.aspx?contextKey={DA8BEDC8-B952-4d5d-8CC2-59FE922E2923}&amp;poll=1&amp;guid=9206FF94-76F9-B197-D1BC-EA9AD282806B HTTP/1.1 </p>
<p>Notice that each request includes a poll=1 parameter. This parameter indicates that this is a polling request to get the size of the file buffered on the server. Here’s what the response body of a request looks like when about 20% of a file has been uploaded: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image009.jpg"><img title="clip_image009" style="border-top:0px;border-right:0px;border-bottom:0px;border-left:0px;display:inline;" border="0" alt="clip_image009" src="http://stephenwalther.com/wp-content/uploads/2013/04/clip_image009_thumb.jpg" width="593" height="484"></a> </p>
<h4>Buffering to a Temporary File</h4>
<p>When you upload a file using the AjaxFileUpload control, the file upload is buffered to a temporary file located at Path.GetTempPath(). When you call the SaveAs() method, as we did in the sample page above, the temporary file is copied to a new file and then the temporary file is deleted. </p>
<p>If you don’t call the SaveAs() method, then you must ensure that the temporary file gets deleted yourself. For example, if you want to save the file to a database then you will never call the SaveAs() method and you are responsible for deleting the file. The easiest way to delete the temporary file is to call the AjaxFileUploadEventArgs.DeleteTemporaryData() method in the UploadComplete handler:
<pre>protected void AjaxFileUpload1_UploadComplete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e) {
    // Save uploaded file to a database table
   e.DeleteTemporaryData();
}

</pre>
<p>You also can call the static AjaxFileUpload.CleanAllTemporaryData() method to delete all temporary data and not only the temporary data related to the current file upload. For example, you might want to call this method on application start to ensure that all temporary data is removed whenever your application restarts. </p>
<h3>A Better MaskedEdit Extender</h3>
<p>This release of the Ajax Control Toolkit contains bug fixes for the top-voted issues related to the MaskedEdit control. We closed over 25 MaskedEdit issues. Here is a complete list of the issues addressed with this release: </p>
<p>· 17302 MaskedEditExtender MaskType=Date, Mask=99/99/99 Undefined JS Error </p>
<p>· 11758 MaskedEdit causes error in JScript when working with 2-digits year </p>
<p>· 18810 Maskededitextender/validator Date validation issue </p>
<p>· 23236 MaskEditValidator does not work with date input using format dd/mm/yyyy </p>
<p>· 23042 Webkit based browsers (Safari, Chrome) and MaskedEditExtender </p>
<p>· 26685 MaskedEditExtender@(ClearMaskOnLostFocus=false) adds a zero character when you each focused to target textbox </p>
<p>· 16109 MaskedEditExtender: Negative amount, followed by decimal, sets value to positive </p>
<p>· 11522 MaskEditExtender of AjaxtoolKit-1.0.10618.0 does not work properly for Hungarian Culture </p>
<p>· 25988 MaskedEditExtender &#8211; CultureName (HU-hu) &gt; DateSeparator </p>
<p>· 23221 MaskedEditExtender date separator problem </p>
<p>· 15233 Day and month swap in Dynamic user control </p>
<p>· 15492 MaskedEditExtender with ClearMaskOnLostFocus and with MaskedEditValidator with ClientValidationFunction </p>
<p>· 9389 MaskedEditValidator &#8211; when on no entry </p>
<p>· 11392 MaskedEdit Number format messed up </p>
<p>· 11819 MaskedEditExtender erases all values beyond first comma separtor </p>
<p>· 13423 MaskedEdit(Extender/Validator) combo problem </p>
<p>· 16111 MaskedEditValidator cannot validate date with DayMonthYear in UserDateFormat of MaskedEditExtender </p>
<p>· 10901 MaskedEdit: The months and date fields swap values when you hit submit if UserDateFormat is set. </p>
<p>· 15190 MaskedEditValidator can&#8217;t make use of MaskedEditExtender&#8217;s UserDateFormat property </p>
<p>· 13898 MaskedEdit Extender with custom date type mask gives javascript error </p>
<p>· 14692 MaskedEdit error in &#8220;yy/MM/dd&#8221; format. </p>
<p>· 16186 MaskedEditExtender does not handle century properly in a date mask </p>
<p>· 26456 MaskedEditBehavior. ConvFmtTime : function(input,loadFirst) fails if this._CultureAMPMPlaceholder == &#8220;&#8221; </p>
<p>· 21474 Error on MaskedEditExtender working with number format </p>
<p>· 23023 MaskedEditExtender&#8217;s ClearMaskOnLostFocus property causes problems for MaskedEditValidator when set to false </p>
<p>· 13656 MaskedEditValidator Min/Max Date value issue </p>
<h3>Conclusion</h3>
<p>This latest release of the Ajax Control Toolkit required many hours of work by a team of talented developers. I want to thank the members of the Superexpert team for the long hours which they put into this release.</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=EIfNSCovJLY:34DAM9VBCRM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/EIfNSCovJLY" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/LXUrJHEMgR8" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/EIfNSCovJLY/april-2013-release-of-the-ajax-control-toolkit.aspx</feedburner:origLink></item>
      <item>
         <title>An Introduction to Meteor</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/oM73eFAQxj4/an-introduction-to-meteor.aspx</link>
         <description>The goal of this blog post is to give you a brief introduction to Meteor which is a framework for building Single Page Apps. In this blog entry, I provide a walkthrough of building a simple Movie database app. What is special about Meteor? Meteor has two jaw-dropping features: Live HTML – If you make [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=746</guid>
         <pubDate>Mon, 18 Mar 2013 00:37:24 +0000</pubDate>
         <content:encoded><![CDATA[<p>The goal of this blog post is to give you a brief introduction to Meteor which is a framework for building Single Page Apps. In this blog entry, I provide a walkthrough of building a simple Movie database app.
<p>What is special about Meteor? Meteor has two jaw-dropping features:
<p><b>Live HTML</b> – If you make any changes to the HTML, CSS, JavaScript, or data on the server then every client shows the changes automatically without a browser refresh. For example, if you change the background color of a page to yellow then every open browser will show the new yellow background color without a refresh. Or, if you add a new movie to a collection of movies, then every open browser will display the new movie automatically.
<p>With Live HTML, users no longer need a refresh button. Changes to an application happen everywhere automatically without any effort. The Meteor framework handles all of the messy details of keeping all of the clients in sync with the server for you.
<p><b>Latency Compensation</b> – When you modify data on the client, these modifications appear as if they happened on the server without any delay. For example, if you create a new movie then the movie appears instantly. However, that is all an illusion. In the background, Meteor updates the database with the new movie. If, for whatever reason, the movie cannot be added to the database then Meteor removes the movie from the client automatically.
<p>Latency compensation is extremely important for creating a responsive web application. You want the user to be able to make instant modifications in the browser and the framework to handle the details of updating the database without slowing down the user.<br />
<h3>Installing Meteor</h3>
<p>Meteor is licensed under the open-source MIT license and you can start building production apps with the framework right now. Be warned that Meteor is still in the “early preview” stage. It has not reached a 1.0 release. According to the Meteor FAQ, Meteor will reach version 1.0 in “More than a month, less than a year.”
<p>Don’t be scared away by that. You should be aware that, unlike most open source projects, Meteor has financial backing. The Meteor project received an $11.2 million round of financing from Andreessen Horowitz. So, it would be a good bet that this project will reach the 1.0 mark. And, if it doesn’t, the framework as it exists right now is still very powerful.
<p>Meteor runs on top of Node.js. You write Meteor apps by writing JavaScript which runs both on the client and on the server. You can build Meteor apps on Windows, Mac, or Linux (Although the support for Windows is still officially unofficial).
<p>If you want to install Meteor on Windows then download the MSI from the following URL:
<p><a rel="nofollow" target="_blank" href="http://win.meteor.com/">http://win.meteor.com/</a>
<p>If you want to install Meteor on Mac/Linux then run the following CURL command from your terminal:
<p>curl https://install.meteor.com | /bin/sh
<p>Meteor will install all of its dependencies automatically including Node.js. However, I recommend that you install Node.js before installing Meteor by installing Node.js from the following address:
<p><a rel="nofollow" target="_blank" href="http://nodejs.org/">http://nodejs.org/</a>
<p>If you let Meteor install Node.js then Meteor won’t install NPM which is the standard package manager for Node.js. If you install Node.js and then you install Meteor then you get NPM automatically.<br />
<h3>Creating a New Meteor App</h3>
<p>To get a sense of how Meteor works, I am going to walk through the steps required to create a simple Movie database app. Our app will display a list of movies and contain a form for creating a new movie.
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image0021.jpg"><img title="clip_image002" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image002" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image002_thumb1.jpg" width="603" height="547"></a>
<p>The first thing that we need to do is create our new Meteor app. Open a command prompt/terminal window and execute the following command:
<p><i>Meteor create MovieApp</i>
<p>After you execute this command, you should see something like the following:
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image0041.jpg"><img title="clip_image004" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image004" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image004_thumb1.jpg" width="784" height="268"></a>
<p>Follow the instructions: execute <i>cd MovieApp</i> to change to your MovieApp directory, and run the <i>meteor</i> command.
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image005.png"><img title="clip_image005" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image005" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image005_thumb.png" width="780" height="139"></a>
<p>Executing the <i>meteor</i> command starts Meteor on port 3000. Open up your favorite web browser and navigate to <a rel="nofollow" target="_blank" href="http://localhost:3000">http://localhost:3000</a> and you should see the default Meteor Hello World page:
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image007.jpg"><img title="clip_image007" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image007" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image007_thumb.jpg" width="493" height="399"></a>
<p>Open up your favorite development environment to see what the Meteor app looks like. Open the MovieApp folder which we just created. Here’s what the MovieApp looks like in Visual Studio 2012:
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image009.jpg"><img title="clip_image009" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image009" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image009_thumb.jpg" width="548" height="375"></a>
<p>Notice that our MovieApp contains three files named MovieApp.css, MovieApp.html, and MovieApp.js. In other words, it contains a Cascading Style Sheet file, an HTML file, and a JavaScript file.
<p>Just for fun, let’s see how the Live HTML feature works. Open up multiple browsers and point each browser at <a rel="nofollow" target="_blank" href="http://localhost:3000">http://localhost:3000</a>. Now, open the MovieApp.html page and modify the text “Hello World!” to “Hello Cruel World!” and save the change. The text in all of the browsers should update automatically without a browser refresh. Pretty amazing, right?
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image011.jpg"><img title="clip_image011" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image011" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image011_thumb.jpg" width="784" height="618"></a><br />
<h3>Controlling Where JavaScript Executes</h3>
<p>You write a Meteor app using JavaScript. Some of the JavaScript executes on the client (the browser) and some of the JavaScript executes on the server and some of the JavaScript executes in both places.
<p>For a super simple app, you can use the Meteor.isServer and Meteor.isClient properties to control where your JavaScript code executes. For example, the following JavaScript contains a section of code which executes on the server and a section of code which executes in the browser:
<pre>if (Meteor.isClient) {
    console.log("Hello Browser!");
}

if (Meteor.isServer) {
    console.log("Hello Server!");
}

console.log("Hello Browser and Server!");

</pre>
<p>When you run the app, the message “Hello Browser!” is written to the browser JavaScript console. The message “Hello Server!” is written to the command/terminal window where you ran Meteor. Finally, the message “Hello Browser and Server!” is execute on both the browser and server and the message appears in both places. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image013.jpg"><img title="clip_image013" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image013" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image013_thumb.jpg" width="784" height="242"></a> </p>
<p>For simple apps, using Meteor.isClient and Meteor.isServer to control where JavaScript executes is fine. For more complex apps, you should create separate folders for your server and client code. Here are the folders which you can use in a Meteor app: </p>
<p>· client – This folder contains any JavaScript which executes only on the client. </p>
<p>· server – This folder contains any JavaScript which executes only on the server. </p>
<p>· common – This folder contains any JavaScript code which executes on both the client and server. </p>
<p>· lib – This folder contains any JavaScript files which you want to execute before any other JavaScript files. </p>
<p>· public – This folder contains static application assets such as images. </p>
<p>For the Movie App, we need the client, server, and common folders. </p>
<p>Delete the existing MovieApp.js, MovieApp.html, and MovieApp.css files. We will create new files in the right locations later in this walkthrough. </p>
<h3>Combining HTML, CSS, and JavaScript Files</h3>
<p>Meteor combines all of your JavaScript files, and all of your Cascading Style Sheet files, and all of your HTML files automatically. If you want to create one humongous JavaScript file which contains all of the code for your app then that is your business. However, if you want to build a more maintainable application, then you should break your JavaScript files into many separate JavaScript files and let Meteor combine them for you. </p>
<p>Meteor also combines all of your HTML files into a single file. HTML files are allowed to have the following top-level elements: </p>
<p>&lt;head&gt; &#8212; All &lt;head&gt; files are combined into a single &lt;head&gt; and served with the initial page load. </p>
<p>&lt;body&gt; &#8212; All &lt;body&gt; files are combined into a single &lt;body&gt; and served with the initial page load. </p>
<p>&lt;template&gt; &#8212; All &lt;template&gt; files are compiled into JavaScript templates. </p>
<p>Because you are creating a single page app, a Meteor app typically will contain a single HTML file for the &lt;head&gt; and &lt;body&gt; content. However, a Meteor app typically will contain several template files. In other words, all of the interesting stuff happens within the &lt;template&gt; files. </p>
<h3>Displaying a List of Movies</h3>
<p>Let me start building the Movie App by displaying a list of movies. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image015.jpg"><img title="clip_image015" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image015" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image015_thumb.jpg" width="528" height="428"></a> </p>
<p>In order to display a list of movies, we need to create the following four files: </p>
<p>· client&#92;movies.html – Contains the HTML for the &lt;head&gt; and &lt;body&gt; of the page for the Movie app. </p>
<p>· client&#92;moviesTemplate.html – Contains the HTML template for displaying the list of movies. </p>
<p>· client&#92;movies.js – Contains the JavaScript for supplying data to the moviesTemplate. </p>
<p>· server&#92;movies.js – Contains the JavaScript for seeding the database with movies. </p>
<p>After you create these files, your folder structure should looks like this: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image017.jpg"><img title="clip_image017" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image017" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image017_thumb.jpg" width="379" height="450"></a> </p>
<p>Here’s what the client&#92;movies.html file looks like:
<pre>&lt;head&gt;
    &lt;title&gt;My Movie App&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;h1&gt;Movies&lt;/h1&gt;
    {{&gt; moviesTemplate }}
&lt;/body&gt;

</pre>
<p>&nbsp;
<p>Notice that it contains &lt;head&gt; and &lt;body&gt; top-level elements. The &lt;body&gt; element includes the moviesTemplate with the syntax {{&gt; moviesTemplate }}. </p>
<p>The moviesTemplate is defined in the client/moviesTemplate.html file:
<pre>&lt;template name="moviesTemplate"&gt;
    &lt;ul&gt;
    {{#each movies}}
    &lt;li&gt;
        {{title}}
    &lt;/li&gt;
    {{/each}}
    &lt;/ul&gt;
&lt;/template&gt;

</pre>
<p>By default, Meteor uses the <a rel="nofollow" target="_blank" href="http://handlebarsjs.com/">Handlebars</a> templating library. In the moviesTemplate above, Handlebars is used to loop through each of the movies using {{#each}}…{{/each}} and display the title for each movie using {{title}}. </p>
<p>The client&#92;movies.js JavaScript file is used to bind the moviesTemplate to the Movies collection on the client. Here’s what this JavaScript file looks like:
<pre>// Declare client Movies collection
Movies = new Meteor.Collection("movies");

// Bind moviesTemplate to Movies collection
Template.moviesTemplate.movies = function () {
    return Movies.find();
};

</pre>
<p>The Movies collection is a client-side proxy for the server-side Movies database collection. Whenever you want to interact with the collection of Movies stored in the database, you use the Movies collection instead of communicating back to the server. </p>
<p>The moviesTemplate is bound to the Movies collection by assigning a function to the Template.moviesTemplate.movies property. The function simply returns all of the movies from the Movies collection. </p>
<p>The final file which we need is the server-side server&#92;movies.js file:
<pre>// Declare server Movies collection
Movies = new Meteor.Collection("movies");

// Seed the movie database with a few movies
Meteor.startup(function () {
    if (Movies.find().count() == 0) {
        Movies.insert({ title: "Star Wars", director: "Lucas" });
        Movies.insert({ title: "Memento", director: "Nolan" });
        Movies.insert({ title: "King Kong", director: "Jackson" });
    }
});

</pre>
<p>The server&#92;movies.js file does two things. First, it declares the server-side Meteor Movies collection. When you declare a server-side Meteor collection, a collection is created in the MongoDB database associated with your Meteor app automatically (Meteor uses MongoDB as its database automatically). </p>
<p>Second, the server&#92;movies.js file seeds the Movies collection (MongoDB collection) with three movies. Seeding the database gives us some movies to look at when we open the Movies app in a browser. </p>
<h3>Creating New Movies</h3>
<p>Let me modify the Movies Database App so that we can add new movies to the database of movies. First, I need to create a new template file – named client&#92;movieForm.html – which contains an HTML form for creating a new movie:
<pre>&lt;template name="movieForm"&gt;
    &lt;fieldset&gt;
    &lt;legend&gt;Add New Movie&lt;/legend&gt;
    &lt;form&gt;
        &lt;div&gt;
            &lt;label&gt;
                Title:
                &lt;input id="title" /&gt;
            &lt;/label&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label&gt;
                Director:
                &lt;input id="director" /&gt;
            &lt;/label&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;input type="submit" value="Add Movie" /&gt;
        &lt;/div&gt;
    &lt;/form&gt;
    &lt;/fieldset&gt;
&lt;/template&gt;

</pre>
<p>In order for the new form to show up, I need to modify the client&#92;movies.html file to include the movieForm.html template. Notice that I added {{&gt; movieForm }} to the client&#92;movies.html file:
<pre>&lt;head&gt;
    &lt;title&gt;My Movie App&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;h1&gt;Movies&lt;/h1&gt;
    {{&gt; moviesTemplate }}
    {{&gt; movieForm }}
&lt;/body&gt;

</pre>
<p>After I make these modifications, our Movie app will display the form: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image019.jpg"><img title="clip_image019" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image019" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image019_thumb.jpg" width="748" height="587"></a> </p>
<p>The next step is to handle the submit event for the movie form. Below, I’ve modified the client&#92;movies.js file so that it contains a handler for the submit event raised when you submit the form contained in the movieForm.html template:
<pre>// Declare client Movies collection
Movies = new Meteor.Collection("movies");

// Bind moviesTemplate to Movies collection
Template.moviesTemplate.movies = function () {
    return Movies.find();
};

// Handle movieForm events
Template.movieForm.events = {
    'submit': function (e, tmpl) {
        // Don't postback
        e.preventDefault();

        // create the new movie
        var newMovie = {
            title: tmpl.find("#title").value,
            director: tmpl.find("#director").value
        };

        // add the movie to the db
        Movies.insert(newMovie);
    }
};

</pre>
<p>The Template.movieForm.events property contains an event map which maps event names to handlers. In this case, I am mapping the form submit event to an anonymous function which handles the event. </p>
<p>In the event handler, I am first preventing a postback by calling e.preventDefault(). This is a single page app, no postbacks are allowed! </p>
<p>Next, I am grabbing the new movie from the HTML form. I’m taking advantage of the template find() method to retrieve the form field values. </p>
<p>Finally, I am calling Movies.insert() to insert the new movie into the Movies collection. Here, I am explicitly inserting the new movie into the client-side Movies collection. Meteor inserts the new movie into the server-side Movies collection behind the scenes. When Meteor inserts the movie into the server-side collection, the new movie is added to the MongoDB database associated with the Movies app automatically. </p>
<p>If server-side insertion fails for whatever reasons – for example, your internet connection is lost – then Meteor will remove the movie from the client-side Movies collection automatically. In other words, Meteor takes care of keeping the client Movies collection and the server Movies collection in sync. </p>
<p>If you open multiple browsers, and add movies, then you should notice that all of the movies appear on all of the open browser automatically. You don’t need to refresh individual browsers to update the client-side Movies collection. Meteor keeps everything synchronized between the browsers and server for you. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image021.jpg"><img title="clip_image021" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image021" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image021_thumb.jpg" width="784" height="626"></a> </p>
<h3>Removing the Insecure Module</h3>
<p>To make it easier to develop and debug a new Meteor app, by default, you can modify the database directly from the client. For example, you can delete all of the data in the database by opening up your browser console window and executing multiple Movies.remove() commands. </p>
<p>Obviously, enabling anyone to modify your database from the browser is not a good idea in a production application. Before you make a Meteor app public, you should first run the <i>meteor remove insecure</i> command from a command/terminal window: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image023.jpg"><img title="clip_image023" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image023" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image023_thumb.jpg" width="784" height="242"></a> </p>
<p>Running <i>meteor remove insecure</i> removes the insecure package from the Movie app. Unfortunately, it also breaks our Movie app. We’ll get an “Access denied” error in our browser console whenever we try to insert a new movie. No worries. I’ll fix this issue in the next section. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image024.png"><img title="clip_image024" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image024" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image024_thumb.png" width="812" height="177"></a> </p>
<h3>Creating Meteor Methods</h3>
<p>By taking advantage of Meteor Methods, you can create methods which can be invoked on both the client and the server. By taking advantage of Meteor Methods you can: </p>
<p>1. Perform form validation on both the client and the server. For example, even if an evil hacker bypasses your client code, you can still prevent the hacker from submitting an invalid value for a form field by enforcing validation on the server. </p>
<p>2. Simulate database operations on the client but actually perform the operations on the server. </p>
<p>Let me show you how we can modify our Movie app so it uses Meteor Methods to insert a new movie. First, we need to create a new file named common&#92;methods.js which contains the definition of our Meteor Methods:
<pre>Meteor.methods({
    addMovie: function (newMovie) {
        // Perform form validation
        if (newMovie.title == "") {
            throw new Meteor.Error(413, "Missing title!");
        }
        if (newMovie.director == "") {
            throw new Meteor.Error(413, "Missing director!");
        }

        // Insert movie (simulate on client, do it on server)
        return Movies.insert(newMovie);
    }

});

</pre>
<p>The addMovie() method is called from both the client and the server. This method does two things. First, it performs some basic validation. If you don’t enter a title or you don’t enter a director then an error is thrown. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image026.jpg"><img title="clip_image026" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image026" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image026_thumb.jpg" width="748" height="625"></a> </p>
<p>Second, the addMovie() method inserts the new movie into the Movies collection. When called on the client, inserting the new movie into the Movies collection just updates the collection. When called on the server, inserting the new movie into the Movies collection causes the database (MongoDB) to be updated with the new movie. </p>
<p>You must add the common&#92;methods.js file to the common folder so it will get executed on both the client and the server. Our folder structure now looks like this: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image028.jpg"><img title="clip_image028" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image028" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image028_thumb.jpg" width="525" height="564"></a> </p>
<p>We actually call the addMovie() method within our client code in the client&#92;movies.js file. Here’s what the updated file looks like:
<pre>// Declare client Movies collection
Movies = new Meteor.Collection("movies");

// Bind moviesTemplate to Movies collection
Template.moviesTemplate.movies = function () {
    return Movies.find();
};

// Handle movieForm events
Template.movieForm.events = {
    'submit': function (e, tmpl) {
        // Don't postback
        e.preventDefault();

        // create the new movie
        var newMovie = {
            title: tmpl.find("#title").value,
            director: tmpl.find("#director").value
        };

        // add the movie to the db
        Meteor.call(
            "addMovie",
            newMovie,
            function (err, result) {
                if (err) {
                    alert("Could not add movie " + err.reason);
                }
            }
       );

    }
};

</pre>
<p>The addMovie() method is called – on both the client and the server – by calling the Meteor.call() method. This method accepts the following parameters: </p>
<p>· The string name of the method to call. </p>
<p>· The data to pass to the method (You can actually pass multiple params for the data if you like). </p>
<p>· A callback function to invoke after the method completes. </p>
<p>In the JavaScript code above, the addMovie() method is called with the new movie retrieved from the HTML form. The callback checks for an error. If there is an error then the error reason is displayed in an alert (please don’t use alerts for validation errors in a production app because they are ugly!). </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image029.jpg"><img title="clip_image029" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image029" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image029_thumb.jpg" width="748" height="625"></a> </p>
<h3>Summary</h3>
<p>The goal of this blog post was to provide you with a brief walk through of a simple Meteor app. I showed you how you can create a simple Movie Database app which enables you to display a list of movies and create new movies. </p>
<p>I also explained why it is important to remove the Meteor insecure package from a production app. I showed you how to use Meteor Methods to insert data into the database instead of doing it directly from the client. </p>
<p>I’m very impressed with the Meteor framework. The support for Live HTML and Latency Compensation are required features for many real world Single Page Apps but implementing these features by hand is not easy. Meteor makes it easy.</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=eZtViTYbWww:Rit_ekhA_0A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/eZtViTYbWww" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/oM73eFAQxj4" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/eZtViTYbWww/an-introduction-to-meteor.aspx</feedburner:origLink></item>
      <item>
         <title>Security Issues with Single Page Apps</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/VEvjG7vxAyg/security-issues-with-single-page-apps.aspx</link>
         <description>Last week, I was asked to do a code review of a Single Page App built using the ASP.NET Web API, Durandal, and Knockout (good stuff!). In particular, I was asked to investigate whether there any special security issues associated with building a Single Page App which are not present in the case of a [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=711</guid>
         <pubDate>Tue, 05 Mar 2013 15:21:47 +0000</pubDate>
         <content:encoded><![CDATA[<p>Last week, I was asked to do a code review of a Single Page App built using the ASP.NET Web API, Durandal, and Knockout (good stuff!). In particular, I was asked to investigate whether there any special security issues associated with building a Single Page App which are not present in the case of a traditional server-side ASP.NET application.
<p>In this blog entry, I discuss two areas in which you need to exercise extra caution when building a Single Page App. I discuss how Single Page Apps are extra vulnerable to both Cross-Site Scripting (XSS) attacks and Cross-Site Request Forgery (CSRF) attacks.
<p>This goal of this blog post is NOT to persuade you to avoid writing Single Page Apps. I’m a big fan of Single Page Apps. Instead, the goal is to ensure that you are fully aware of some of the security issues related to Single Page Apps and ensure that you know how to guard against them.<br />
<h3>Cross-Site Scripting (XSS) Attacks</h3>
<p>According to WhiteHat Security, over 65% of public websites are open to XSS attacks. That’s bad. By taking advantage of XSS holes in a website, a hacker can steal your credit cards, passwords, or bank account information.
<p>Any website that redisplays untrusted information is open to XSS attacks. Let me give you a simple example.
<p>Imagine that you want to display the name of the current user on a page. To do this, you create the following server-side ASP.NET page located at <a rel="nofollow" target="_blank" href="http://MajorBank.com/SomePage.aspx">http://MajorBank.com/SomePage.aspx</a>:
<pre>&lt;%@Page Language="C#"  %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Some Page&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

    Welcome &lt;%= Request["username"] %&gt;

&lt;/body&gt;
&lt;/html&gt;

</pre>
<p>Nothing fancy here. Notice that the page displays the current username by using Request[“username”]. Using Request[“username”] displays the username regardless of whether the username is present in a cookie, a form field, or a query string variable. </p>
<p>Unfortunately, by using Request[“username”] to redisplay untrusted information, you have now opened your website to XSS attacks. Here’s how. </p>
<p>Imagine that an evil hacker creates the following link on another website (hackers.com):
<pre>&lt;a href="/SomePage.aspx?username=&lt;script src=Evil.js&gt;&lt;/script&gt;"&gt;Visit MajorBank&lt;/a&gt;

</pre>
<p>Notice that the link includes a query string variable named username and the value of the username variable is an HTML &lt;SCRIPT&gt; tag which points to a JavaScript file named Evil.js. When anyone clicks on the link, the &lt;SCRIPT&gt; tag will be injected into SomePage.aspx and the Evil.js script will be loaded and executed. </p>
<p>What can a hacker do in the Evil.js script? Anything the hacker wants. For example, the hacker could display a popup dialog on the MajorBank.com site which asks the user to enter their password. The script could then post the password back to hackers.com and now the evil hacker has your secret password. </p>
<p>ASP.NET Web Forms and ASP.NET MVC have two automatic safeguards against this type of attack: Request Validation and Automatic HTML Encoding. </p>
<h4>Protecting Coming In (Request Validation)</h4>
<p>In a server-side ASP.NET app, you are protected against the XSS attack described above by a feature named Request Validation. If you attempt to submit “potentially dangerous” content &#8212; such as a JavaScript &lt;SCRIPT&gt; tag &#8212; in a form field or query string variable then you get an exception. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image002.jpg"><img title="clip_image002" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image002" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image002_thumb.jpg" width="644" height="172"></a> </p>
<p>Unfortunately, Request Validation only applies to server-side apps. Request Validation does not help in the case of a Single Page App. In particular, the ASP.NET Web API does not pay attention to Request Validation. You can post any content you want – including &lt;SCRIPT&gt; tags – to an ASP.NET Web API action. </p>
<p>For example, the following HTML page contains a form. When you submit the form, the form data is submitted to an ASP.NET Web API controller on the server using an Ajax request:
<pre>&lt;!DOCTYPE html&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
    &lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;form data-bind="submit:submit"&gt;
    &lt;div&gt;
        &lt;label&gt;
            User Name:
            &lt;input data-bind="value:user.userName" /&gt;
        &lt;/label&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;label&gt;
            Email:
            &lt;input data-bind="value:user.email" /&gt;
        &lt;/label&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;input type="submit" value="Submit" /&gt;
    &lt;/div&gt;
    &lt;/form&gt;

    &lt;script src="Scripts/jquery-1.7.1.js"&gt;&lt;/script&gt;
    &lt;script src="Scripts/knockout-2.1.0.js"&gt;&lt;/script&gt;

    &lt;script&gt;

        var viewModel = {

            user: {
                userName: ko.observable(),
                email: ko.observable()
            },

            submit: function () {
                $.post("/api/users", ko.toJS(this.user));
            }
        };

        ko.applyBindings(viewModel);

    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

</pre>
<p>The form above is using Knockout to bind the form fields to a view model. When you submit the form, the view model is submitted to an ASP.NET Web API action on the server. </p>
<p>Here’s the server-side ASP.NET Web API controller and model class:
<pre>public class UsersController : ApiController
{

    public HttpResponseMessage Post(UserViewModel user) {
        var userName = user.UserName;
        return Request.CreateResponse(HttpStatusCode.OK);
    }

}


public class UserViewModel {
    public string UserName { get; set; }
    public string Email { get; set; }
}

</pre>
<p>If you submit the HTML form, you don’t get an error. The “potentially dangerous” content is passed to the server without any exception being thrown. In the screenshot below, you can see that I was able to post a username form field with the value “&lt;script&gt;alert(‘boo’)&lt;/script”. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image004.jpg"><img title="clip_image004" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image004" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image004_thumb.jpg" width="644" height="201"></a> </p>
<p>So what this means is that you do not get automatic Request Validation in the case of a Single Page App. You need to be extra careful in a Single Page App about ensuring that you do not display untrusted content because you don’t have the Request Validation safety net which you have in a traditional server-side ASP.NET app. </p>
<h4>Protecting Going Out (Automatic HTML Encoding)</h4>
<p>Server-side ASP.NET also protects you from XSS attacks when you render content. By default, all content rendered by the razor view engine is HTML encoded. For example, the following razor view displays the text “&lt;b&gt;Hello!&lt;/b&gt;” instead of the text “Hello!” in bold:
<pre>@{
    var message = "&lt;b&gt;Hello!&lt;/b&gt;";
}

@message

</pre>
<p>&nbsp;
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image006.jpg"><img title="clip_image006" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image006" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image006_thumb.jpg" width="644" height="235"></a> </p>
<p>If you don’t want to render content as HTML encoded in razor then you need to take the extra step of using the @Html.Raw() helper. </p>
<p>In a Web Form page, if you use &lt;%: %&gt; instead of &lt;%= %&gt; then you get automatic HTML Encoding:
<pre>&lt;%@ Page Language="C#" %&gt; 

&lt;% 

var message = "&lt;b&gt;Hello!&lt;/b&gt;"; 

%&gt; 

&lt;%: message %&gt; 


</pre>
<p>This automatic HTML Encoding will prevent many types of XSS attacks. It prevents &lt;script&gt; tags from being rendered and only allows &amp;lt;script&amp;gt; tags to be rendered which are useless for executing JavaScript. </p>
<p>(This automatic HTML encoding does not protect you from all forms of XSS attacks. For example, you can assign the value “javascript:alert(‘evil’)” to the Hyperlink control’s NavigateUrl property and execute the JavaScript). </p>
<p>The situation with Knockout is more complicated. If you use the Knockout TEXT binding then you get HTML encoded content. On the other hand, if you use the HTML binding then you do not:
<pre>&lt;!-- This JavaScript DOES NOT execute --&gt;
&lt;div data-bind="text:someProp"&gt;&lt;/div&gt;

&lt;!-- This Javacript DOES execute --&gt;
&lt;div data-bind="html:someProp"&gt;&lt;/div&gt;


&lt;script src="Scripts/jquery-1.7.1.js"&gt;&lt;/script&gt;
&lt;script src="Scripts/knockout-2.1.0.js"&gt;&lt;/script&gt;

&lt;script&gt;    

    var viewModel = {
        someProp : "&lt;script&gt;alert('Evil!')&lt;" + "/script&gt;"
    };

    ko.applyBindings(viewModel);

&lt;/script&gt;

</pre>
<p>&nbsp;
<p>So, in the page above, the DIV element which uses the TEXT binding is safe from XSS attacks. According to the Knockout documentation: </p>
<p>“Since this binding sets your text value using a text node, it’s safe to set any string value without risking HTML or script injection.” </p>
<p>Just like server-side HTML encoding, Knockout does not protect you from all types of XSS attacks. For example, there is nothing in Knockout which prevents you from binding JavaScript to a hyperlink like this:
<pre>&lt;a data-bind="attr:{href:homePageUrl}"&gt;Go&lt;/a&gt;

&lt;script src="Scripts/jquery-1.7.1.min.js"&gt;&lt;/script&gt;
&lt;script src="Scripts/knockout-2.1.0.js"&gt;&lt;/script&gt;

&lt;script&gt;    

    var viewModel = {
        homePageUrl: "javascript:alert('evil!')"
    };


    ko.applyBindings(viewModel);

&lt;/script&gt;

</pre>
<p>In the page above, the value “javascript:alert(‘evil’)” is bound to the HREF attribute using Knockout. When you click the link, the JavaScript executes. </p>
<h3>Cross-Site Request Forgery (CSRF) Attacks</h3>
<p>Cross-Site Request Forgery (CSRF) attacks rely on the fact that a session cookie does not expire until you close your browser. In particular, if you visit and login to MajorBank.com and then you navigate to Hackers.com then you will still be authenticated against MajorBank.com even after you navigate to Hackers.com. </p>
<p>Because MajorBank.com cannot tell whether a request is coming from MajorBank.com or Hackers.com, Hackers.com can submit requests to MajorBank.com pretending to be you. For example, Hackers.com can post an HTML form from Hackers.com to MajorBank.com and change your email address at MajorBank.com. Hackers.com can post a form to MajorBank.com using your authentication cookie. </p>
<p>After your email address has been changed, by using a password reset page at MajorBank.com, a hacker can access your bank account. </p>
<p>To prevent CSRF attacks, you need some mechanism for detecting whether a request is coming from a page loaded from your website or whether the request is coming from some other website. The recommended way of preventing Cross-Site Request Forgery attacks is to use the “Synchronizer Token Pattern” as described here: </p>
<p><a rel="nofollow" target="_blank" href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet">https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet</a> </p>
<p>When using the Synchronizer Token Pattern, you include a hidden input field which contains a random token whenever you display an HTML form. When the user opens the form, you add a cookie to the user’s browser with the same random token. When the user posts the form, you verify that the hidden form token and the cookie token match. </p>
<h4>Preventing Cross-Site Request Forgery Attacks with ASP.NET MVC</h4>
<p>ASP.NET gives you a helper and an action filter which you can use to thwart Cross-Site Request Forgery attacks. For example, the following razor form for creating a product shows how you use the @Html.AntiForgeryToken() helper:
<pre>@model MvcApplication2.Models.Product

&lt;h2&gt;Create Product&lt;/h2&gt;

@using (Html.BeginForm()) {

    @Html.AntiForgeryToken();
    
    &lt;div&gt;
        @Html.LabelFor( p =&gt; p.Name, "Product Name:")
        @Html.TextBoxFor( p =&gt; p.Name)
    &lt;/div&gt;

    &lt;div&gt;
        @Html.LabelFor( p =&gt; p.Price, "Product Price:")
        @Html.TextBoxFor( p =&gt; p.Price)
    &lt;/div&gt;
    
    &lt;input type="submit" /&gt;

}

</pre>
<p>The @Html.AntiForgeryToken() helper generates a random token and assigns a serialized version of the same random token to both a cookie and a hidden form field. (Actually, if you dive into the source code, the AntiForgeryToken() does something a little more complex because it takes advantage of a user’s identity when generating the token). </p>
<p>Here’s what the hidden form field looks like: </p>
<p>&lt;input name=&#8221;__RequestVerificationToken&#8221; type=&#8221;hidden&#8221; value=&#8221;NqqZGAmlDHh6fPTNR_mti3nYGUDgpIkCiJHnEEL59S7FNToyyeSo7v4AfzF2i67Cv0qTB1TgmZcqiVtgdkW2NnXgEcBc-iBts0x6WAIShtM1&#8243; /&gt; </p>
<p>And here’s what the cookie looks like using the Google Chrome developer toolbar: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image008.jpg"><img title="clip_image008" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image008" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image008_thumb.jpg" width="644" height="138"></a> </p>
<p>You use the [ValidateAntiForgeryToken] action filter on the controller action which is the recipient of the form post to validate that the token in the hidden form field matches the token in the cookie. If the tokens don’t match then validation fails and you can’t post the form:
<pre>public ActionResult Create() {
    return View();
}

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult Create(Product productToCreate) {
    if (ModelState.IsValid) {
        // save product to db
        return RedirectToAction("Index");
    }
    return View();
}

</pre>
<p>How does this all work? Let’s imagine that a hacker has copied the Create Product page from MajorBank.com to Hackers.com – the hacker grabs the HTML source and places it at Hackers.com. Now, imagine that the hacker trick you into submitting the Create Product form from Hackers.com to MajorBank.com. You’ll get the following exception: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image010.jpg"><img title="clip_image010" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image010" src="http://stephenwalther.com/wp-content/uploads/2013/03/clip_image010_thumb.jpg" width="644" height="275"></a> </p>
<p>The Cross-Site Request Forgery attack is blocked because the anti-forgery token included in the Create Product form at Hackers.com won’t match the anti-forgery token stored in the cookie in your browser. The tokens were generated at different times for different users so the attack fails. </p>
<h4>Preventing Cross-Site Request Forgery Attacks with a Single Page App</h4>
<p>In a Single Page App, you can’t prevent Cross-Site Request Forgery attacks using the same method as a server-side ASP.NET MVC app. In a Single Page App, HTML forms are not generated on the server. Instead, in a Single Page App, forms are loaded dynamically in the browser. </p>
<p>Phil Haack has a blog post on this topic where he discusses passing the anti-forgery token in an Ajax header instead of a hidden form field. He also describes how you can create a custom anti-forgery token attribute to compare the token in the Ajax header and the token in the cookie. See: </p>
<p><a rel="nofollow" target="_blank" href="http://haacked.com/archive/2011/10/10/preventing-csrf-with-ajax.aspx">http://haacked.com/archive/2011/10/10/preventing-csrf-with-ajax.aspx</a> </p>
<p>Also, take a look at Johan’s update to Phil Haack’s original post: </p>
<p><a rel="nofollow" target="_blank" href="http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC">http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC</a> </p>
<p>(Other server frameworks such as Rails and Django do something similar. For example, Rails uses an X-CSRF-Token to prevent CSRF attacks which you generate on the server – see <a rel="nofollow" target="_blank" href="http://excid3.com/blog/rails-tip-2-include-csrf-token-with-every-ajax-request/#.UTFtgDDkvL8">http://excid3.com/blog/rails-tip-2-include-csrf-token-with-every-ajax-request/#.UTFtgDDkvL8</a> ). </p>
<p>For example, if you are creating a <a rel="nofollow" target="_blank" href="http://stephenwalther.com/archive/2013/02/08/using-durandal-to-create-single-page-apps.aspx">Durandal app</a>, then you can use the following razor view for your one and only server-side page:
<pre>@{
    Layout = null;
}
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Index&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

    @Html.AntiForgeryToken()

    &lt;div id="applicationHost"&gt;
        Loading app....
    &lt;/div&gt;
 
    @Scripts.Render("~/scripts/vendor")
    &lt;script type="text/javascript" src="~/App/durandal/amd/require.js"
        data-main="/App/main"&gt;&lt;/script&gt;
 
&lt;/body&gt;
&lt;/html&gt;

</pre>
<p>Notice that this page includes a call to @Html.AntiForgeryToken() to generate the anti-forgery token. </p>
<p>Then, whenever you make an Ajax request in the Durandal app, you can retrieve the anti-forgery token from the razor view and pass the token as a header:
<pre>var csrfToken = $("input[name='__RequestVerificationToken']").val(); 
$.ajax({
    headers: { __RequestVerificationToken: csrfToken },
    type: "POST",
    dataType: "json",
    contentType: 'application/json; charset=utf-8',
    url: "/api/products",
    data: JSON.stringify({ name: "Milk", price: 2.33 }),
    statusCode: {
        200: function () {
            alert("Success!");
        }
    }
});

</pre>
<p>Use the following code to create an action filter which you can use to match the header and cookie tokens:
<pre>using System.Linq;
using System.Net.Http;
using System.Web.Helpers;
using System.Web.Http.Controllers;

namespace MvcApplication2.Infrastructure {

    public class ValidateAjaxAntiForgeryToken : System.Web.Http.AuthorizeAttribute {

        protected override bool IsAuthorized(HttpActionContext actionContext) {

            var headerToken = actionContext
                .Request
                .Headers
                .GetValues("__RequestVerificationToken")
                .FirstOrDefault(); ;

            var cookieToken = actionContext
                .Request
                .Headers
                .GetCookies()
                .Select(c =&gt; c[AntiForgeryConfig.CookieName])
                .FirstOrDefault();

            // check for missing cookie or header
            if (cookieToken == null || headerToken == null) {
                return false;
            }

            // ensure that the cookie matches the header
            try {
                AntiForgery.Validate(cookieToken.Value, headerToken);
            } catch {
                return false;
            }
            
            return base.IsAuthorized(actionContext);
        }
 
    }
}

</pre>
<p>Notice that the action filter derives from the base AuthorizeAttribute. The ValidateAjaxAntiForgeryToken only works when the user is authenticated and it will not work for anonymous requests. </p>
<p>Add the action filter to your ASP.NET Web API controller actions like this:
<pre>[ValidateAjaxAntiForgeryToken]
public HttpResponseMessage PostProduct(Product productToCreate) {
    // add product to db
    return Request.CreateResponse(HttpStatusCode.OK);
}

</pre>
<p>After you complete these steps, it won’t be possible for a hacker to pretend to be you at Hackers.com and submit a form to MajorBank.com. The header token used in the Ajax request won’t travel to Hackers.com. </p>
<p>This approach works, but I am not entirely happy with it. The one thing that I don’t like about this approach is that it creates a hard dependency on using razor. Your single page in your Single Page App must be generated from a server-side razor view. A better solution would be to generate the anti-forgery token in JavaScript. </p>
<p>Unfortunately, until all browsers support a way to generate cryptographically strong random numbers – for example, by supporting the <a rel="nofollow" target="_blank" href="https://developer.mozilla.org/en-US/docs/DOM/window.crypto.getRandomValues">window.crypto.getRandomValues()</a> method &#8212; there is no good way to generate anti-forgery tokens in JavaScript. So, at least right now, the best solution for generating the tokens is the server-side solution with the (regrettable) dependency on razor. </p>
<h3>Conclusion</h3>
<p>The goal of this blog entry was to explore some ways in which you need to handle security differently in the case of a Single Page App than in the case of a traditional server app. In particular, I focused on how to prevent Cross-Site Scripting and Cross-Site Request Forgery attacks in the case of a Single Page App. </p>
<p>I want to emphasize that I am not suggesting that Single Page Apps are inherently less secure than server-side apps. Whatever type of web application you build – regardless of whether it is a Single Page App, an ASP.NET MVC app, an ASP.NET Web Forms app, or a Rails app – you must constantly guard against security vulnerabilities.</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=EnhVdcMbKpw:7qiNqbBZROI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/EnhVdcMbKpw" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/VEvjG7vxAyg" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/EnhVdcMbKpw/security-issues-with-single-page-apps.aspx</feedburner:origLink></item>
      <item>
         <title>Using Durandal to Create Single Page Apps</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/Lcl1udljj6E/using-durandal-to-create-single-page-apps.aspx</link>
         <description>A few days ago, I gave a talk on building Single Page Apps on the Microsoft Stack. In that talk, I recommended that people use Knockout, Sammy, and RequireJS to build their presentation layer and use the ASP.NET Web API to expose data from their server. After I gave the talk, several people contacted me [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=699</guid>
         <pubDate>Fri, 08 Feb 2013 19:15:57 +0000</pubDate>
         <content:encoded><![CDATA[<p>A few days ago, I gave a talk on building Single Page Apps on the Microsoft Stack. In that talk, I recommended that people use Knockout, Sammy, and RequireJS to build their presentation layer and use the ASP.NET Web API to expose data from their server.
<p>After I gave the talk, several people contacted me and suggested that I investigate a new open-source JavaScript library named Durandal. Durandal stitches together Knockout, Sammy, and RequireJS to make it easier to use these technologies together.
<p>In this blog entry, I want to provide a brief walkthrough of using Durandal to create a simple Single Page App. I am going to demonstrate how you can create a simple Movies App which contains (virtual) pages for viewing a list of movies, adding new movies, and viewing movie details. The goal of this blog entry is to give you a sense of what it is like to build apps with Durandal.<br />
<h3>Installing Durandal</h3>
<p>First things first. How do you get Durandal?
<p>The GitHub project for Durandal is located here:<br />
<blockquote>
<p>https://github.com/BlueSpire/Durandal </p>
</blockquote>
<p>The Wiki &#8212; located at the GitHub project &#8212; contains all of the current documentation for Durandal. Currently, the documentation is a little sparse, but it is enough to get you started.
<p>Instead of downloading the Durandal source from GitHub, a better option for getting started with Durandal is to install one of the Durandal NuGet packages.
<p>I built the Movies App described in this blog entry by first creating a new ASP.NET MVC 4 Web Application with the Basic Template. Next, I executed the following command from the Package Manager Console:<br />
<blockquote>
<p>Install-Package Durandal.StarterKit </p>
</blockquote>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image001.png"><img title="clip_image001" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image001" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image001_thumb.png" width="697" height="772"></a> </p>
<p>As you can see from the screenshot of the Package Manager Console above, the Durandal Starter Kit package has several dependencies including:
<p>· jQuery
<p>· Knockout
<p>· Sammy
<p>· Twitter Bootstrap
<p>The Durandal Starter Kit package includes a sample Durandal application. You can get to the Starter Kit app by navigating to the Durandal controller.
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image003.jpg"><img title="clip_image003" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image003" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image003_thumb.jpg" width="784" height="576"></a>
<p>Unfortunately, when I first tried to run the Starter Kit app, I got an error because the Starter Kit is hard-coded to use a particular version of jQuery which is already out of date. You can fix this issue by modifying the App_Start&#92;DurandalBundleConfig.cs file so it is jQuery version agnostic like this:
<pre>      bundles.Add(
        new ScriptBundle("~/scripts/vendor")
          .Include("~/Scripts/jquery-{version}.js")
          .Include("~/Scripts/knockout-{version}.js")
          .Include("~/Scripts/sammy-{version}.js")
//          .Include("~/Scripts/jquery-1.9.0.min.js")
//          .Include("~/Scripts/knockout-2.2.1.js")
//          .Include("~/Scripts/sammy-0.7.4.min.js")
          .Include("~/Scripts/bootstrap.min.js")
        );

</pre>
<p>The recommendation is that you create a Durandal app in a folder off your project root named App. The App folder in the Starter Kit contains the following subfolders and files: </p>
<p>· durandal – This folder contains the actual durandal JavaScript library. </p>
<p>· viewmodels – This folder contains all of your application’s view models. </p>
<p>· views – This folder contains all of your application’s views. </p>
<p>· main.js &#8212; This file contains all of the JavaScript startup code for your app including the client-side routing configuration. </p>
<p>· main-built.js – This file contains an optimized version of your application. You need to build this file by using the RequireJS optimizer (unfortunately, before you can run the optimizer, you must first install NodeJS). </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image004.png"><img title="clip_image004" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image004" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image004_thumb.png" width="439" height="610"></a> </p>
<p>For the purpose of this blog entry, I wanted to start from scratch when building the Movies app, so I deleted all of these files and folders except for the durandal folder which contains the durandal library. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image005.png"><img title="clip_image005" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image005" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image005_thumb.png" width="249" height="152"></a> </p>
<h3>Creating the ASP.NET MVC Controller and View</h3>
<p>A Durandal app is built using a single server-side ASP.NET MVC controller and ASP.NET MVC view. A Durandal app is a Single Page App. When you navigate between pages, you are not navigating to new pages on the server. Instead, you are loading new virtual pages into the one-and-only-one server-side view. </p>
<p>For the Movies app, I created the following ASP.NET MVC Home controller:
<pre>public class HomeController : Controller {

    public ActionResult Index() {
        return View();
    }

}

</pre>
<p>There is nothing special about the Home controller – it is as basic as it gets. </p>
<p>Next, I created the following server-side ASP.NET view. This is the one-and-only server-side view used by the Movies app:
<pre>@{
    Layout = null;
}
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Index&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id="applicationHost"&gt;
        Loading app....
    &lt;/div&gt;
        
    @Scripts.Render("~/scripts/vendor") 
    &lt;script type="text/javascript" src="~/App/durandal/amd/require.js" 
        data-main="/App/main"&gt;&lt;/script&gt;
        
&lt;/body&gt;
&lt;/html&gt;

</pre>
<p>Notice that I set the Layout property for the view to the value null. If you neglect to do this, then the default ASP.NET MVC layout will be applied to the view and you will get the &lt;!DOCTYPE&gt; and opening and closing &lt;html&gt; tags twice. </p>
<p>Next, notice that the view contains a DIV element with the Id applicationHost. This marks the area where virtual pages are loaded. When you navigate from page to page in a Durandal app, HTML page fragments are retrieved from the server and stuck in the applicationHost DIV element. </p>
<p>Inside the applicationHost element, you can place any content which you want to display when a Durandal app is starting up. For example, you can create a fancy splash screen. I opted for simply displaying the text “Loading app…”: </p>
<p>Next, notice the view above includes a call to the Scripts.Render() helper. This helper renders out all of the JavaScript files required by the Durandal library such as jQuery and Knockout. Remember to fix the App_Start&#92;DurandalBundleConfig.cs as described above or Durandal will attempt to load an old version of jQuery and throw a JavaScript exception and stop working. </p>
<p>Your application JavaScript code is not included in the scripts rendered by the Scripts.Render helper. Your application code is loaded dynamically by RequireJS with the help of the following SCRIPT element located at the bottom of the view:
<pre>&lt;script type="text/javascript" src="~/App/durandal/amd/require.js" 
     data-main="/App/main"&gt;&lt;/script&gt; 


</pre>
<p>The data-main attribute on the SCRIPT element causes RequireJS to load your /app/main.js JavaScript file to kick-off your Durandal app. </p>
<h3>Creating the Durandal Main.js File</h3>
<p>The Durandal Main.js JavaScript file, located in your App folder, contains all of the code required to configure the behavior of Durandal. Here’s what the Main.js file looks like in the case of the Movies app:
<pre>require.config({
    paths: {
        'text': 'durandal/amd/text'
    }
});

define(function (require) {
    var app = require('durandal/app'),
        viewLocator = require('durandal/viewLocator'),
        system = require('durandal/system'),
        router = require('durandal/plugins/router');

    //&gt;&gt;excludeStart("build", true);
    system.debug(true);
    //&gt;&gt;excludeEnd("build");

    app.start().then(function () {
        //Replace 'viewmodels' in the moduleId with 'views' to locate the view.
        //Look for partial views in a 'views' folder in the root.
        viewLocator.useConvention();

        //configure routing
        router.useConvention();
        router.mapNav("movies/show");
        router.mapNav("movies/add");
        router.mapNav("movies/details/:id");

        app.adaptToDevice();

        //Show the app by setting the root view model for our application with a transition.
        app.setRoot('viewmodels/shell', 'entrance');
    });
});

</pre>
<p>There are three important things to notice about the main.js file above. First, notice that it contains a section which enables debugging which looks like this: </p>
<p>//&gt;&gt;excludeStart(&#8220;build&#8221;, true); </p>
<p>system.debug(true); </p>
<p>//&gt;&gt;excludeEnd(&#8220;build&#8221;); </p>
<p>This code enables debugging for your Durandal app which is very useful when things go wrong. When you call system.debug(true), Durandal writes out debugging information to your browser JavaScript console. For example, you can use the debugging information to diagnose issues with your client-side routes: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image006.png"><img title="clip_image006" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image006" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image006_thumb.png" width="434" height="620"></a> </p>
<p>(The funny looking //&gt; symbols around the system.debug() call are RequireJS optimizer pragmas). </p>
<p>The main.js file is also the place where you configure your client-side routes. In the case of the Movies app, the main.js file is used to configure routes for three page: the movies show, add, and details pages.
<pre>//configure routing 

router.useConvention(); 

router.mapNav("movies/show"); 

router.mapNav("movies/add"); 

router.mapNav("movies/details/:id");

</pre>
<p>&nbsp;
<p>The route for movie details includes a route parameter named id. Later, we will use the id parameter to lookup and display the details for the right movie. </p>
<p>Finally, the main.js file above contains the following line of code:
<pre>//Show the app by setting the root view model for our application with a transition. 
app.setRoot('viewmodels/shell', 'entrance'); 



</pre>
<p>This line of code causes Durandal to load up a JavaScript file named shell.js and an HTML fragment named shell.html. I’ll discuss the shell in the next section. </p>
<h3>Creating the Durandal Shell</h3>
<p>You can think of the Durandal shell as the layout or master page for a Durandal app. The shell is where you put all of the content which you want to remain constant as a user navigates from virtual page to virtual page. For example, the shell is a great place to put your website logo and navigation links. </p>
<p>The Durandal shell is composed from two parts: a JavaScript file and an HTML file. Here’s what the HTML file looks like for the Movies app:
<pre>&lt;h1&gt;Movies App&lt;/h1&gt; 

&lt;div class="container-fluid page-host"&gt; 

&lt;!--ko compose: { 

model: router.activeItem, //wiring the router 

afterCompose: router.afterCompose, //wiring the router 

transition:'entrance', //use the 'entrance' transition when switching views 

cacheViews:true //telling composition to keep views in the dom, and reuse them (only a good idea with singleton view models) 

}--&gt;&lt;!--/ko--&gt; 

&lt;/div&gt;

</pre>
<p>And here is what the JavaScript file looks like:
<pre>define(function (require) {
    var router = require('durandal/plugins/router');

    return {
        router: router,
        activate: function () {
            return router.activate('movies/show');
        }
    };
});

</pre>
<p>The JavaScript file contains the view model for the shell. This view model returns the Durandal router so you can access the list of configured routes from your shell. </p>
<p>Notice that the JavaScript file includes a function named activate(). This function loads the movies/show page as the first page in the Movies app. If you want to create a different default Durandal page, then pass the name of a different age to the router.activate() method. </p>
<h3>Creating the Movies Show Page</h3>
<p>Durandal pages are created out of a view model and a view. The view model contains all of the data and view logic required for the view. The view contains all of the HTML markup for rendering the view model. </p>
<p>Let’s start with the movies show page. The movies show page displays a list of movies. The view model for the show page looks like this:
<pre>define(function (require) {

    var moviesRepository = require("repositories/moviesRepository");

    return {
        movies: ko.observable(),

        activate: function() {
            this.movies(moviesRepository.listMovies());
        }
    };
});

</pre>
<p>You create a view model by defining a new RequireJS module (see http://requirejs.org). You create a RequireJS module by placing all of your JavaScript code into an anonymous function passed to the RequireJS define() method. </p>
<p>A RequireJS module has two parts. You retrieve all of the modules which your module requires at the top of your module. The code above depends on another RequireJS module named repositories/moviesRepository. </p>
<p>Next, you return the implementation of your module. The code above returns a JavaScript object which contains a property named movies and a method named activate. </p>
<p>The activate() method is a magic method which Durandal calls whenever it activates your view model. Your view model is activated whenever you navigate to a page which uses it. In the code above, the activate() method is used to get the list of movies from the movies repository and assign the list to the view model movies property. </p>
<p>The HTML for the movies show page looks like this:
<pre>&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;Title&lt;/th&gt;&lt;th&gt;Director&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody data-bind="foreach:movies"&gt;
        &lt;tr&gt;
            &lt;td data-bind="text:title"&gt;&lt;/td&gt;
            &lt;td data-bind="text:director"&gt;&lt;/td&gt;
            &lt;td&gt;&lt;a data-bind="attr:{href:'#/movies/details/'+id}"&gt;Details&lt;/a&gt;&lt;/td&gt;
        &lt;/tr&gt;        
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;a href="#/movies/add"&gt;Add Movie&lt;/a&gt;

</pre>
<p>Notice that this is an HTML fragment. This fragment will be stuffed into the page-host DIV element in the shell.html file which is stuffed, in turn, into the applicationHost DIV element in the server-side MVC view. </p>
<p>The HTML markup above contains data-bind attributes used by Knockout to display the list of movies (To learn more about Knockout, visit http://knockoutjs.com). The list of movies from the view model is displayed in an HTML table. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image007.png"><img title="clip_image007" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image007" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image007_thumb.png" width="376" height="307"></a> </p>
<p>Notice that the page includes a link to a page for adding a new movie. The link uses the following URL which starts with a hash: #/movies/add. Because the link starts with a hash, clicking the link does not cause a request back to the server. Instead, you navigate to the movies/add page virtually. </p>
<h3>Creating the Movies Add Page</h3>
<p>The movies add page also consists of a view model and view. The add page enables you to add a new movie to the movie database. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image008.png"><img title="clip_image008" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image008" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image008_thumb.png" width="376" height="307"></a> </p>
<p>Here’s the view model for the add page:
<pre>define(function (require) {
    var app = require('durandal/app');
    var router = require('durandal/plugins/router');
    var moviesRepository = require("repositories/moviesRepository");

    return {
        movieToAdd: {
            title: ko.observable(),
            director: ko.observable()
        },
 
        activate: function () {
            this.movieToAdd.title("");
            this.movieToAdd.director("");
            this._movieAdded = false;
        },

        canDeactivate: function () {
            if (this._movieAdded == false) {
                return app.showMessage('Are you sure you want to leave this page?', 'Navigate', ['Yes', 'No']);
            } else {
                return true;
            }
        },

        addMovie: function () {
            // Add movie to db
            moviesRepository.addMovie(ko.toJS(this.movieToAdd));

            // flag new movie
            this._movieAdded = true;

            // return to list of movies
            router.navigateTo("#/movies/show");
        }
    };

});

</pre>
<p>The view model contains one property named movieToAdd which is bound to the add movie form. The view model also has the following three methods: </p>
<p>1. activate() – This method is called by Durandal when you navigate to the add movie page. The activate() method resets the add movie form by clearing out the movie title and director properties. </p>
<p>2. canDeactivate() – This method is called by Durandal when you attempt to navigate away from the add movie page. If you return false then navigation is cancelled. </p>
<p>3. addMovie() – This method executes when the add movie form is submitted. This code adds the new movie to the movie repository. </p>
<p>I really like the Durandal canDeactivate() method. In the code above, I use the canDeactivate() method to show a warning to a user if they navigate away from the add movie page – either by clicking the Cancel button or by hitting the browser back button – before submitting the add movie form: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image009.png"><img title="clip_image009" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image009" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image009_thumb.png" width="376" height="307"></a> </p>
<p>The view for the add movie page looks like this:
<pre>&lt;form data-bind="submit:addMovie"&gt;
&lt;fieldset&gt;
    &lt;legend&gt;Add Movie&lt;/legend&gt;
    &lt;div&gt;   
        &lt;label&gt;
            Title:
            &lt;input data-bind="value:movieToAdd.title" required /&gt;
        &lt;/label&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;label&gt;
            Director:
            &lt;input data-bind="value:movieToAdd.director" required /&gt;
        &lt;/label&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;input type="submit" value="Add" /&gt;
        &lt;a href="#/movies/show"&gt;Cancel&lt;/a&gt;
    &lt;/div&gt;
&lt;/fieldset&gt;
&lt;/form&gt;

</pre>
<p>I am using Knockout to bind the movieToAdd property from the view model to the INPUT elements of the HTML form. Notice that the FORM element includes a data-bind attribute which invokes the addMovie() method from the view model when the HTML form is submitted. </p>
<h3>Creating the Movies Details Page</h3>
<p>You navigate to the movies details Page by clicking the Details link which appears next to each movie in the movies show page: </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image0071.png"><img title="clip_image007[1]" style="border-left-width:0px;border-right-width:0px;border-bottom-width:0px;display:inline;border-top-width:0px;" border="0" alt="clip_image007[1]" src="http://stephenwalther.com/wp-content/uploads/2013/02/clip_image0071_thumb.png" width="376" height="307"></a> </p>
<p>The Details links pass the movie ids to the details page: </p>
<p>#/movies/details/0 </p>
<p>#/movies/details/1 </p>
<p>#/movies/details/2 </p>
<p>Here’s what the view model for the movies details page looks like:
<pre>define(function (require) {
    var router = require('durandal/plugins/router');
    var moviesRepository = require("repositories/moviesRepository");

    return {
        movieToShow: {
            title: ko.observable(),
            director: ko.observable()
        },

        activate: function (context) {
            // Grab movie from repository
            var movie = moviesRepository.getMovie(context.id);

            // Add to view model
            this.movieToShow.title(movie.title);
            this.movieToShow.director(movie.director);
        }
    };

});

</pre>
<p>Notice that the view model activate() method accepts a parameter named context. You can take advantage of the context parameter to retrieve route parameters such as the movie Id. </p>
<p>In the code above, the context.id property is used to retrieve the correct movie from the movie repository and the movie is assigned to a property named movieToShow exposed by the view model. </p>
<p>The movie details view displays the movieToShow property by taking advantage of Knockout bindings:
<pre>&lt;div&gt;
    &lt;h2 data-bind="text:movieToShow.title"&gt;&lt;/h2&gt;
    directed by &lt;span data-bind="text:movieToShow.director"&gt;&lt;/span&gt;
&lt;/div&gt;

</pre>
<h3>Summary</h3>
<p>The goal of this blog entry was to walkthrough building a simple Single Page App using Durandal and to get a feel for what it is like to use this library. I really like how Durandal stitches together Knockout, Sammy, and RequireJS and establishes patterns for using these libraries to build Single Page Apps. </p>
<p>Having a standard pattern which developers on a team can use to build new pages is super valuable. Once you get the hang of it, using Durandal to create new virtual pages is dead simple. Just define a new route, view model, and view and you are done. </p>
<p>I also appreciate the fact that Durandal did not attempt to re-invent the wheel and that Durandal leverages existing JavaScript libraries such as Knockout, RequireJS, and Sammy. These existing libraries are powerful libraries and I have already invested a considerable amount of time in learning how to use them. Durandal makes it easier to use these libraries together without losing any of their power. </p>
<p>Durandal has some additional interesting features which I have not had a chance to play with yet. For example, you can use the RequireJS optimizer to combine and minify all of a Durandal app’s code. Also, Durandal supports a way to create custom widgets (client-side controls) by composing widgets from a controller and view. </p>
<p>You can download the code for the Movies app by clicking the following link (this is a Visual Studio 2012 project): </p>
<p><a rel="nofollow">Durandal Movie App</a></p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=uA_cG0bY0nw:cyAYMJ58GXE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/uA_cG0bY0nw" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/Lcl1udljj6E" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/uA_cG0bY0nw/using-durandal-to-create-single-page-apps.aspx</feedburner:origLink></item>
      <item>
         <title>Building Single Page Apps on the Microsoft Stack</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/364mrucCOOg/building-single-page-apps-on-the-microsoft-stack.aspx</link>
         <description>Thank you everyone who came to my talk last night on Building Single Page Apps on the Microsoft Stack. I’ve attached the slides and code samples below. Here’s a quick summary of the talk. I argued that Single Page Apps are better than traditional Server Side Apps because: Single Page Apps are Stateful – In [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=677</guid>
         <pubDate>Wed, 06 Feb 2013 16:07:23 +0000</pubDate>
         <content:encoded><![CDATA[<p>Thank you everyone who came to my talk last night on <i>Building Single Page Apps on the Microsoft Stack</i>. I’ve attached the slides and code samples below.
<p>Here’s a quick summary of the talk. I argued that Single Page Apps are better than traditional Server Side Apps because:
<ol>
<li>
<p>Single Page Apps are Stateful – In a traditional server-side app, whenever you navigate to a new page, all of your previous state is lost. It is like rebooting your computer whenever you perform any action </p>
<li>
<p>In a Single Page App, Your Presentation Layer is Not Miles Away – In a traditional server-side app, because everything happens on the server, your presentation layer is separated from the user by space and time. In a Single Page App, the presentation layer is in the browser and not the server (which is the right place for a presentation layer). </p>
<li>
<p>A Single Page App Respects the Web – It is easier to take advantage of HTML5 and related standards when building a Single Page App. </p>
</li>
</ol>
<p>Next, I recommended using the following four technologies when building a web application:
<ol>
<li>
<p>Knockout – This is how you create your presentation layer.</p>
<li>
<p>ASP.NET Web API – This is how you expose JSON data from your web server and perform server-side validation. </p>
<li>
<p>HTML5 – This is how you implement client-side validation. </p>
<li>
<p>Sammy – This is how you implement client-side routing and create a Single Page App with multiple virtual pages. </p>
</li>
</ol>
<p>There are code samples in the download (look in the Samples folder) which demonstrate how all of these technologies work when building Single Page Apps.</p>

<ul>
<li><a rel="nofollow">Powerpoint</a>
<li><a rel="nofollow">Sample Code</a> </li>
</ul>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=KqqjLgo2dsA:lSfnmWsLzew:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/KqqjLgo2dsA" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/364mrucCOOg" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/KqqjLgo2dsA/building-single-page-apps-on-the-microsoft-stack.aspx</feedburner:origLink></item>
      <item>
         <title>New January 2013 Release of the Ajax Control Toolkit</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/x-GjvuJ_eFg/new-january-2013-release-of-the-ajax-control-toolkit.aspx</link>
         <description>I am super excited to announce the January 2013 release of the Ajax Control Toolkit! I have one word to describe this release and that word is “Charts” – we’ve added lots of great new chart controls to the Ajax Control Toolkit. You can download the new release directly from http://AjaxControlToolkit.CodePlex.com – or, just fire [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=674</guid>
         <pubDate>Thu, 24 Jan 2013 19:40:37 +0000</pubDate>
         <content:encoded><![CDATA[<p>I am super excited to announce the January 2013 release of the Ajax Control Toolkit! I have one word to describe this release and that word is “Charts” – we’ve added lots of great new chart controls to the Ajax Control Toolkit.
<p>You can download the new release directly from <a rel="nofollow" target="_blank" href="http://AjaxControlToolkit.CodePlex.com">http://AjaxControlToolkit.CodePlex.com</a> – or, just fire the following command from the Visual Studio Library Package Manager Console Window (NuGet):
<div style="margin:30px;">Install-Package AjaxControlToolkit </div>
<p>You also can view the new chart controls by visiting the “live” <a rel="nofollow" target="_blank" href="http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/Default.aspx">Ajax Control Toolkit Sample Site</a>.<br />
<h3>5 New Ajax Control Toolkit Chart Controls</h3>
<p>The Ajax Control Toolkit contains five new chart controls: the AreaChart, BarChart, BubbleChart, LineChart, and PieChart controls.
<p>Here is a sample of each of the controls:
<p><b>AreaChart:</b>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image002.jpg"><img title="clip_image002" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="clip_image002" src="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image002_thumb.jpg" width="244" height="167"></a>
<p><b>BarChart:</b>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image004.jpg"><img title="clip_image004" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="clip_image004" src="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image004_thumb.jpg" width="244" height="167"></a>
<p><b>BubbleChart:</b>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image006.jpg"><img title="clip_image006" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;margin:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="clip_image006" src="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image006_thumb.jpg" width="244" height="164"></a>
<p><b>LineChart:</b>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image008.jpg"><img title="clip_image008" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;margin:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="clip_image008" src="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image008_thumb.jpg" width="244" height="172"></a>
<p><b>PieChart:</b>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image010.jpg"><img title="clip_image010" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="clip_image010" src="http://stephenwalther.com/wp-content/uploads/2013/01/clip_image010_thumb.jpg" width="244" height="170"></a>
<p>We realize that people love to customize the appearance of their charts so all of the chart controls include properties such as color properties.
<p>The chart controls render the chart on the browser using SVG. The chart controls are compatible with any browser which supports SVG including Internet Explorer 9 and new and recent versions of Google Chrome, Mozilla Firefox, and Apple Safari. (If you attempt to display a chart on a browser which does not support SVG then you won’t get an error – you just won’t get anything).<br />
<h3>Updates to the HTML Sanitizer</h3>
<p>If you are using the HtmlEditorExtender on a public-facing website then it is really important that you enable the HTML Sanitizer to prevent Cross-Site Scripting (XSS) attacks. The HtmlEditorExtender uses the HTML Sanitizer by default.
<p>The HTML Sanitizer strips out any suspicious content (like JavaScript code and CSS expressions) from the HTML submitted with the HtmlEditorExtender. We followed the recommendations of <a rel="nofollow" target="_blank" href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet">OWASP</a> and <a rel="nofollow" target="_blank" href="http://ha.ckers.org/">ha.ckers.org</a> to identify suspicious content.
<p>We updated the HTML Sanitizer with this release to protect against new types of XSS attacks. <b><i>The HTML Sanitizer now has over 220 unit tests.</i></b> The Ajax Control Toolkit team would like to thank Gil Cohen who helped us identify and block additional XSS attacks.<br />
<h3>Change in Ajax Control Toolkit Version Format</h3>
<p>We ran out of numbers. The Ajax Control Toolkit was first released way back in 2006. In previous releases, the version of the Ajax Control Toolkit followed the format: Release Year + Date. So, the previous release was 60919 where 6 represented the 6<sup>th</sup> release year and 0919 represent September 19.
<p>Unfortunately, the AssembyVersion attribute uses a UInt16 data type which has a maximum size of 65,534. The number 70123 is bigger than 65,534 so we had to change our version format with this release.
<p>Fortunately, the AssemblyVersion attribute actually accepts four UInt16 numbers so we used another one. This release of the Ajax Control Toolkit is officially version 7.0123. This new version format should work for another 65,000 years.
<p>And yes, I realize that 7.0123 is less than 60,919, but we ran out of numbers.<br />
<h3>Summary</h3>
<p>I hope that you find the chart controls included with this latest release of the Ajax Control Toolkit useful. Let me know if you use them in applications that you build. And, let me know if you run into any issues using the new chart controls. Next month, back to improving the File Upload control – more exciting stuff.</p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=epp5454LYA4:BvOxR0v2qCs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/epp5454LYA4" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/x-GjvuJ_eFg" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/epp5454LYA4/new-january-2013-release-of-the-ajax-control-toolkit.aspx</feedburner:origLink></item>
      <item>
         <title>Windows 8 Apps Unleashed Now in Bookstores!</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/FtHaIeQmb4Q/windows-8-apps-unleashed-now-in-bookstores.aspx</link>
         <description>My book Windows 8 Apps with HTML5 and JavaScript Unleashed is now in bookstores! Learn how to create Metro apps Windows 8 apps with JavaScript. And the book is in color! All of the code listings and illustrations are in color. Why build Windows 8 apps? When you create a Windows 8 app, you can [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=657</guid>
         <pubDate>Tue, 04 Dec 2012 15:20:22 +0000</pubDate>
         <content:encoded><![CDATA[<p>My book <strong>Windows 8 Apps with HTML5 and JavaScript Unleashed</strong> is now in bookstores! Learn how to create <strike>Metro apps</strike> Windows 8 apps with JavaScript. And the book is in color! All of the code listings and illustrations are in color. </p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2012/12/Windows8Unleashed.jpg"><img title="Windows8Unleashed" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="Windows8Unleashed" src="http://stephenwalther.com/wp-content/uploads/2012/12/Windows8Unleashed_thumb.jpg" width="371" height="484"></a></p>
<p>Why build Windows 8 apps? When you create a Windows 8 app, you can put your app in the Windows 8 Store. In other words, customers can buy your app directly from Windows. Think iPhone apps, but for a much larger market. </p>
<p>In my book, I explain how you can create both game apps and simple productivity apps by creating Windows 8 apps with JavaScript. The book is a short read and I include plenty of code samples that have been tested against the final release of Windows 8. </p>
<p>You can buy the book by going to your local Barnes &amp; Noble bookstore or you can buy the book through Amazon by using the following link: </p>
<p> 
<p>It looks like the book is also available for the Kindle: </p>
<p><a rel="nofollow" target="_blank" href="http://www.amazon.com/gp/product/B00AAXNPTK/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B00AAXNPTK&amp;linkCode=as2&amp;tag=superexpertco-20">Kindle: Windows 8 Apps with HTML5 and JavaScript Unleashed</a><img style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;margin:0px;" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=superexpertco-20&amp;l=as2&amp;o=1&amp;a=B00AAXNPTK" width="1" height="1"></p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=YwTvXMWbjs8:gvRqMzvFax4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/YwTvXMWbjs8" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/FtHaIeQmb4Q" height="1" width="1"/>]]></content:encoded>
         <category>Windows 8 Apps</category>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/YwTvXMWbjs8/windows-8-apps-unleashed-now-in-bookstores.aspx</feedburner:origLink></item>
      <item>
         <title>My Windows 8 App in Windows Store</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/3OTCrA2rZ34/my-windows-8-app-in-windows-store.aspx</link>
         <description>Finally, you have a good reason to upgrade to Windows 8! My Brain Eaters app was just accepted into the Windows Store. Just in time for Halloween! The Brain Eaters app is a sample app from my soon to be released book Windows 8 Apps with HTML5 and JavaScript. The game illustrates several important programming [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=655</guid>
         <pubDate>Tue, 30 Oct 2012 16:18:03 +0000</pubDate>
         <content:encoded><![CDATA[<p>Finally, you have a good reason to upgrade to Windows 8! My Brain Eaters app was just accepted into the Windows Store. Just in time for Halloween!
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2012/10/clip_image002.jpg"><img title="clip_image002" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="clip_image002" src="http://stephenwalther.com/wp-content/uploads/2012/10/clip_image002_thumb.jpg" width="599" height="292"></a>
<p>The Brain Eaters app is a sample app from my soon to be released book <a rel="nofollow" target="_blank" href="http://www.amazon.com/gp/product/0672336057/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0672336057&amp;linkCode=as2&amp;tag=superexpertco-20">Windows 8 Apps with HTML5 and JavaScript</a>. The game illustrates several important programming concepts which you need when building Windows 8 games with JavaScript such as using HTML5 Canvas and the new requestAnimationFrame() method.
<p>If you are looking for Halo or Call of Duty then you will be disappointed. If you are looking for PAC-MAN then you will be disappointed. I created the simplest arcade game that I could imagine so I could explain it in the book. All of the code for the game is included with the book.
<p>The goal of the game is to eat the food pellets while avoiding the zombies while running around a maze. Every time you get eaten by a zombie, you can hear my six year old son saying “Oh No!”.
<p>Here’s the link to the game:
<p><a rel="nofollow" target="_blank" href="http://apps.microsoft.com/webpdp/app/brain-eaters/e283c8d0-1fed-4b26-a8bf-464584c9de6d">http://apps.microsoft.com/webpdp/app/brain-eaters/e283c8d0-1fed-4b26-a8bf-464584c9de6d</a></p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=-o0VbXGhi7U:caWEm5GVPMg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/-o0VbXGhi7U" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/3OTCrA2rZ34" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/-o0VbXGhi7U/my-windows-8-app-in-windows-store.aspx</feedburner:origLink></item>
      <item>
         <title>Windows 8 Apps with HTML5 and JavaScript</title>
         <link>http://feedproxy.google.com/~r/Superexpert/~3/8Hvm5L15nl8/windows-8-apps-with-html5-and-javascript.aspx</link>
         <description>Last week, I finished writing Windows 8 Apps with HTML5 and JavaScript – Yikes! That is a long title. This book is all about writing apps for Windows 8 which can be added to the Windows Store. The book focuses on building apps using HTML5 and JavaScript. If you are already comfortable building websites, then [...]</description>
         <guid isPermaLink="false">http://StephenWalther.com/?p=650</guid>
         <pubDate>Fri, 26 Oct 2012 16:20:07 +0000</pubDate>
         <content:encoded><![CDATA[<p>Last week, I finished writing <strong>Windows 8 Apps with HTML5 and JavaScript</strong> – Yikes! That is a long title. This book is all about writing apps for Windows 8 which can be added to the Windows Store.</p>
<p>The book focuses on building apps using HTML5 and JavaScript. If you are already comfortable building websites, then building Windows Store apps is not a huge leap.&nbsp; I explain how you can create productivity apps, like a Task List app, and games, like a simple arcade game. I also explain how you can publish your app to the Windows Store and make money.</p>
<p>To celebrate the release of Windows 8, my publisher is offering a huge 40% discount on the book until November 30, 2012. If you want to take advantage of this discount, follow the link below and enter the discount code <strong>WINDEV40</strong> during checkout.</p>
<p><a rel="nofollow" target="_blank" href="http://www.informit.com/promotions/promotion.aspx?promo=139036&amp;walther">http://www.informit.com/promotions/promotion.aspx?promo=139036&amp;walther</a></p>
<p><a rel="nofollow" target="_blank" href="http://stephenwalther.com/wp-content/uploads/2012/10/ShowCover.jpg"><img title="ShowCover" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;float:right;padding-top:0px;padding-left:0px;margin:0px 0px 0px 15px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="ShowCover" align="right" src="http://stephenwalther.com/wp-content/uploads/2012/10/ShowCover_thumb.jpg" width="500" height="652"></a></p>
<p>So what’s in the book?&nbsp; Here’s an overview of each of the chapters:</p>
<p><strong>Chapter 1 &#8211; Building Windows Store Apps</strong>
<p>Contains a walkthrough of creating a super simple Windows app for taking pictures from your webcam. Explains how to publish your app to the Windows Store.
<p><strong>Chapter 2 &#8211; WinJS Fundamentals</strong>
<p>Provides an overview of the Windows Library for JavaScript which is the Microsoft library for creating Windows Store apps with JavaScript.
<p><strong>Chapter 3 &#8211; Observables, Bindings, and Templates</strong>
<p>You learn how to display a list of items using a template. For example, you learn how to create a template which can be used to display a list of products.
<p><strong>Chapter 4 &#8211; Using WinJS Controls</strong>
<p>Overview of the core set of JavaScript controls included with the WinJS library. You learn how to use the Tooltip, ToggleSwitch, Rating, DatePicker, TimePicker, and FlipView controls.
<p><strong>Chapter 5 &#8211; Creating Forms</strong>
<p>This chapter explains how to take advantage of HTML5 forms to display specialized keyboards and perform form validation.
<p><strong>Chapter 6 &#8211; Menus and Flyouts</strong>
<p>You learn how to display popups, menus, and toolbars using the JavaScript controls included with the WinJS library.
<p><strong>Chapter 7 &#8211; Using the ListView Control</strong>
<p>This entire chapter is devoted to the ListView control which is the most important control in the WinJS library. You can use the ListView control to display, sort, filter, and edit a list of items.
<p><strong>Chapter 8 &#8211; Creating Data Sources</strong>
<p>Learn how to use a ListView control to display data from the file system, a web service, and IndexedDB.
<p><strong>Chapter 9 &#8211; App Events and States</strong>
<p>This chapter explains the standard application events which are raised in a Windows Store app such as the activated and checkpoint events. You also learn how to build apps which adapt automatically to different view states such as portrait and landscape.
<p><strong>Chapter 10 &#8211; Page Fragments and Navigation</strong>
<p>This chapter discusses two subjects: You learn how to create custom WinJS controls with Page Controls and you learn how to build apps with multiple pages.&nbsp;
<p><strong>Chapter 11 &#8211; Using the Live Connect API</strong>
<p>Learn how to use Windows Live Services to authenticate users, interact with SkyDrive, and retrieve user profile information (such as a user’s birthday or profile picture).
<p><strong>Chapter 12 &#8211; Graphics and Games </strong>
<p>This chapter is devoted to building the <em>Brain Eaters</em> app which is a simple arcade game. Navigate a maze and eat all of the food pellets while avoiding the brain-eating zombies to win the game. Learn how to create the game using HTML5 Canvas.</p>
<p>&nbsp;</p>
<p>If you want to buy the book, remember to use the magic discount code <strong>WINDEV40</strong> and visit the following link:</p>
<p><a rel="nofollow" target="_blank" href="http://www.informit.com/promotions/promotion.aspx?promo=139036&amp;walther">http://www.informit.com/promotions/promotion.aspx?promo=139036&amp;walther</a></p>
<div class="feedflare">
<a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/StephenWalther?a=7sMT3q7AOZQ:_tA8Zme0LfY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/StephenWalther?d=yIl2AUoC8zA" border="0"></a>
</div><img src="http://feeds.feedburner.com/~r/StephenWalther/~4/7sMT3q7AOZQ" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/Superexpert/~4/8Hvm5L15nl8" height="1" width="1"/>]]></content:encoded>
         <category>Windows 8 Apps</category>
      <feedburner:origLink>http://feedproxy.google.com/~r/StephenWalther/~3/7sMT3q7AOZQ/windows-8-apps-with-html5-and-javascript.aspx</feedburner:origLink></item>
   </channel>
</rss><!-- fe4.yql.bf1.yahoo.com compressed/chunked Fri May 24 04:57:58 UTC 2013 -->
