Thursday 22 December 2011

The Definitive Guide To HTML5: 14 Predictions For 2012

HTML5in2012
 
 Guest contributor Ben Savage is the founder of Spaceport.io, a native Javascript and HTML5 platform for mobile game developers.
From tech titans like Zynga, Facebook, Microsoft, Google and Apple, to startups just launching, the battle lines of 2012 will be drawn across the landscape of HTML5. Below are 14 bold predictions for how HTML5 will evolve in 2012.

Welcome to a more interconnected web:
In 2012, HTML5 will be adding support for some really useful and cool APIs that allow one
website to connect to another.


For example, Zynga games on Facebook run inside of iframes. Using the new postMessage API these games will be able to communicate within the containing Facebook frame directly. Before HTML5, inter-window communication had to rely on a remote server – or use unreliable hacks.
Another exciting addition is CORS (Cross Origin Resource Sharing). This will make it much easier for different websites to share information with one another. For example, CORS will enable startups to create photo-editing services that download your photos from Facebook, let you modify them, and then re-upload them – again without having to resort to ugly hacks.

With all of the new semantic information (see Semantics and Microdata) available with HTML5, it will become much easier to create web tools that extract information from web pages. As a result, you can expect to see a plethora of new mashup services, as well as better browser modes (like readers and translators).

Web browsers will look more like iPhones
Everyone loves Apple’s iOS. Now it’s coming to the HTML5 web. In 2012 your browsers will start
sporting
push notifications, geolocation, and offline capable applications. Some browsers will likely adopt a more iOS-like user interface that will make the comparison all the more apt.

More and more applications will just be built in HTML5 instead of downloadable apps
If you’re like me, you already use web apps for email, calendars, and photo-sharing, but in 2012 more classes of applications will be HTML5 enabled. Next up, you can expect to see content creation apps like Inkscape and Illustrator emerge for HTML5 and start to catch on.

Internet Explorer & Microsoft will dramatically improve in coolness.
Internet explorer’s reputation will stop being “the browser where nothing works right” and start being “the fast browser”. Microsoft has made major investments into improving HTML5 performance that will give IE 10 a huge performance lead over competing browsers. Its hardware accelerated “canvas” will blow away all the other browsers in any speed test. Microsoft is also adding interesting ways for the HTML5 web and the desktop to work together that will really spice up its operating system. Having good support from IE will be the impetus that will really turn the tide in favor of authoring HTML5 applications.

Browser manufacturers will get into the App Store business
Taking a cue from Apple, browser manufacturers will start to realize that they are missing out by not being in the app store business. Google Chrome already has an integrated app-store as its splash page. Expect many other browsers to follow. This is actually a good thing for HTML5 application developers – it means more distribution opportunities for apps, although platform specific payment systems and platform revenue-shares will follow later on.
At least one major console game released or re-released using WebGL
In 2012, at least one AAA console game company is going to make the leap and decide to launch a 3D title on the web using WebGL instead of (or in addition to) creating a downloadable client. It might be a re-release of a well-known title (Like “Team Fortress 2″ or “Assassins Creed”), or another way to play a popular MMO (like “Eve Online” or “World of Warcraft”), or it may be an entirely new title launching for the first time.

Many more applications will use offline cache and will work offline
The offline application cache will dramatically improve the usability and speed of HTML5 apps. Querying a local database will allow applications to avoid a round-trip to the server, eliminating that laggy web-app feel that makes us all prefer native apps today.

In 2012, expect to see a few issues arise from this extended usage. You’ll lose your work by clearing your cache at least once or twice. Also expect security vulnerabilities to keep showing up that allow malicious applications to access private files stored on your computer by another
website.


HTML5 ads will become prevalent and overtake Flash ads
Website owners keen to monetize the increasingly large amount of traffic coming from iOS devices will demand HTML5 ads (rather than Flash ads). Startups will emerge to serve this market. These startups will solve the sand boxing, security, and authoring tools issues that this new market will face. Now that HTML5 is capable of doing everything that flash ads commonly do, it’s just a matter of time before they take over.

JavaScript will get a lot faster with better memory management and typed arrays
JavaScript has gotten really, really fast – it’s already among the world’s fastest scripting languages – but there is room for improvement. Google Chrome has started pushing the envelope on better memory management and garbage collection algorithms. This, combined with typed arrays, will bring JavaScript performance closer to more mature languages like Java.

Canvas will get hardware acceleration in more browsers (but no major mobile browsers)
Other browser makers will follow Internet Explorer’s lead and add hardware acceleration to their canvas implementations. Those that don’t will suffer a severe loss in mind-share. Firefox is most at-risk in this regard. If Mozilla fails to accelerate their canvas it risks being portrayed as the new IE — slow and bloated and burdened down with legacy code.

However, in 2012, no major mobile browsers will successfully roll out a hardware-accelerated canvas. We will have to wait until 2013 to start seeing that catch on.

People will play popular HTML5 games on their mobile devices from Zynga and others, but they will be very simple games
You can expect to see your friends playing games like Zynga Poker, Words with Friends, and Mafia Wars on their mobile phones, running purely in HTML5. These games will be played on both destination websites and within native applications (like the Facebook app).

However, successful HTML5 games on mobile devices will be limited to menu-based games, card games, board games, turn-based multiplayer games, and avatar customizer games. More complex and visually intensive Zynga “Ville” style games with isometric worlds or hundreds of animating sprites will not yet strike gold in 2012.

Facebook will release improved HTML5-based APIs that allow for more seamless integration with external websites
In its continued quest to be the de facto social-graph of the web, Facebook Connect will grow and expand to take advantage of new HTML5 features. This will allow even deeper and richer integration of Facebook connect with external websites and services.

Facebook will get a lot more seamlessly integrated with your desktop
Think drag-and-drop, file system access, photo synching, and widgets on your desktop. All of these features (and more) will start to blur the line between desktop and browser, bringing your social graph more closely into contact with your traditional desktop experience.

Apple will NOT fix HTML5 sound in mobile Safari
HTML5 sound used to work well in mobile Safari, back in the days iOS3. However, Apple disabled most of the API in iOS 4 and 5. It just introduces competition for iTunes — both the music store, and the App Store. In its continued fight to maintain total control over the Apple ecosystem, they will refrain from fixing HTML5 sound in 2012.

Wednesday 21 December 2011

Microsoft updates Windows Azure cloud platform

Microsoft has released new features of its Windows Azure cloud development platform, including open source capabilities and simplified billing and management.

Developers partial to open source development will benefit from the first Windows Azure software development kit (SDK) that includes language libraries for Node.JS, with support for hosting, storage and service bus.
Microsoft is delivering an Apache Hadoop-based service for Windows Azure to bolster the platform’s big data functionality, helping customers take advantage of advanced data analytics.
“These changes will help developers build applications on Windows Azure using the languages and frameworks they already know,” said Microsoft in a blog post.

As part of efforts to make it easier to get started and manage applications on Windows Azure, the update offers a free 90-day trial and spending caps that simplify the sign-up process.

Managing cloud costs

The new Windows Azure Management Portal enables customers to view real-time usage and billing details so they can more easily control how much they use and spend on the cloud platform.Microsoft said the update offers customers greater flexibility for scaling and managing databases by increasing the maximum database size for SQL Azure from 50GB to 150GB and introducing a price cap which lowers the effective cost per gigabyte for customers with large databases.

“This change allows customers with 50GB databases and larger to continue to grow without additional costs,” said Microsoft.

Securing applications against hackers

In October, Adrienne Hall, general manager of Microsoft's Trustworthy Computing group, told Computer Weekly that Azure customers are showing that cloud implementations are moving from collaboration applications only to include mission-critical applications as well.

With less than 1% of security exploits in the first half of 2011 being against zero-day or unpatched vulnerabilities, organisations can guard against most attacks by getting the basics right, she said.
This also means that by switching to cloud-based managed services, organisations have the opportunity to transfer some of the risk of common threats to service providers, said Hall.

"Most risks are manageable, but many organisations are not doing all they can to reduce attacks. Cloud-based managed services could help with that," she said.Cloud providers, such as Microsoft, are resourced to focus on security, said Hall, and in moving the management of a portion of security functions, resources are freed up to focus on other areas of security or on different IT projects altogether.

Wednesday 14 December 2011

Working with Media in HTML5

Unless you have been living on a remote island for the past year or so, you have probably heard the buzz and hype around HTML5. No, HTML5 will not cure most illnesses, nor will it end world hunger, but it is poised to reshape the rich Internet application landscape. With all the hype over the new HTML standard, it's important to bring the discussion back down to earth. Here are the important facts you need to know about this new HTML specification:
  • HTML5 is the first new version of the specification since 1999—the Web has changed a lot since then.
  • HTML5 will be the new standard for HTML, XHTML and the HTML DOM.
  • HTML5 provides a standard way of playing media—a key benefit  because there was no standard for playing media in a Web page without a browser plug-in, and no guarantee that every browser would support the plug-in.
  • HTML5 is still a work in progress, but most modern browsers have some HTML5 tag support.
When Silverlight 1.0 shipped in 2007, Microsoft touted its video and audio playback as primary features, and a prime reason to see Silverlight as an alternative to Flash—which is supported in one version or another on 95 percent of browsers worldwide. As of this writing, Silverlight is supported on around 75 percent of browsers worldwide, or about three of every four computers. But if you’re looking to play media and you don’t want to the hassle or the dependency of a plug-in, HTML5 is the answer.
To see the difference between using the HTML5 video tag and the traditional object tag to play media, consider the example in Figure 1.
Figure 1  The HTML Video Tag vs. the Object Tag to Play Media
  1. <section>
  2.     <h1>Using the HTML5 Video tag to play video</h1>
  3.     <video src="video1.mp4" >
  4.     </video>
  5. </section>
  6. <section>
  7.     <h1>Using the Object tag to play media using the Flash plug-in</h1> 
  8.     <object type="application/x-shockwave-flash"
  9.                data="player.swf" width="290" height="24">
  10.         <param name="movie" value="player.swf">
  11.     </object>
  12. </section>
So what’s the big deal? Both examples are simple and easy to implement. But the important point here is that because the <video> tag is a standard, there will be no question that it should be used to play media. You don’t have to guess if a browser has a certain version of a particular plug-in installed to play your media. The standard part is what’s been missing from HTML.

Supported Media Formats in HTML5

To use media in your next HTML5 application, you need to know what formats are supported. HTML5 supports AAC, MP3 and Ogg Vorbis for audio and Ogg Theora, WebM and MPEG-4 for video.
Even though HTML5 supports these media formats, however, not every browser supports every format. Figure 2 shows current browsers and the media formats they support.
Figure 2 Media Support in Current Browsers

BrowserVideo FormatsAudio Formats
 Ogg TheoraH.264VP8 (WebM)Ogg VorbisMP3Wav
Internet ExplorerManual install9.0Manual installNoYesNo
Mozilla Firefox3.5No4.0YesNoYes
Google Chrome3.0No6.0YesYesYes
SafariManual install3Manual installNoYesYes
Opera10.50No10.60YesNoYes

Using the Video Tag

To play a video in an HTML5 page, just use the <video> tag, as shown here:
  1. <video src="video.mp4" controls />
The src attribute (http://www.w3.org/TR/html5/video.html#the-source-element) sets the name or names of the video to play, and the control’s Boolean switch dictates whether the default playback controls displays. You can also use two other Boolean properties—autoplay and loop—when setting up the video tag. Figure 3 lists each property attribute and its value.
Figure 3 Video Tag Properties

AttributeValueDescription
 AudioMutedDefines the default state of the audio. Currently, only muted is allowed.
 AutoplayAutoplayIf present, the video starts playing as soon as it’s ready.
 ControlsControlsAdds Play, Pause and Volume controls.
 HeightPixelsSets the height of the video player.
 LoopLoopIf present, the video will start over again every time it finishes.
 PosterurlSpecifies the URL of an image representing the video.
 PreloadPreloadIf present, the video is loaded at page load and is ready to run. It is ignored if Autoplay is present.
 SrcurlThe URL of the video to play.
 WidthPixelsSets the width of the video player.

The following code shows a few of the key properties on the video player in a common scenario that includes setting the height and width, autoplay, loop and controls properties, which will display the play, pause and volume controls as well as a fallback error message.
  1. <video src="video.mp4" width="320" height="240" autoplay controls loop>
  2.     Your browser does not support the video tag.
  3. </video>
You can also set the specific MIME typeusing the type attribute and codec in the source element. These examples use the type attribute to set the MIME type and the encoding of the media:
  1. <!-- H.264 Constrained baseline profile video (main and extended video compatible)
  2.   level 3 and Low-Complexity AAC audio in MP4 container -->
  3. <source src='video.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
  4. <!-- H.264 Extended profile video (baseline-compatible) level 3 and Low-Complexity
  5.   AAC audio in MP4 container -->
  6. <source src='video.mp4' type='video/mp4; codecs="avc1.58A01E, mp4a.40.2"'>
You can set properties in either HTML or JavaScript. The following code shows how to set the Boolean controls property in HTML and JavaScript.
<!-- 3 ways to show the controls -->
<video controls>
<video controls="">
<video controls="controls">
// 2 ways to show controls in JavaScript
video.controls = true;
video.setAttribute
       ('controls',
        'controls');
When you don’t know whether a browser will render the page, you need a fallback mechanism to play your media. All you do is list the video formats you have rendered your video in, and the browser plays the first one it supports. You can also add text as a last resort to let the user know that the browser being used doesn’t support native HTML5 playback of video. The following code includes multiple video sources as well as a fallback message indicating no HTML5 support.
  1. <video controls>
  2.     <source src="video1.mp4" />
  3.     <source src="video1.ogv" />
  4.     <source src="video1.webm" />
  5.     <p>This browser does not support HTML5 video</p>
  6. </video>
If you want to make sure your video plays, you can include the object tag to play a Flash version as well, like so:
  1. <video controls>
  2.     <source src="video1.mp4" />
  3.     <source src="video1.ogv" />
  4.     <source src="video1.webm" />
  5.     <object data="videoplayer.swf">
  6.         <param name="flashvars" value="video1.mp4">
  7.         HTML5 Video and Flash are not supported
  8.     </object>
  9. </video>
You can also use JavaScript to check if a video format is supported by checking the canPlayType property, as follows:
  1. var video = document.getElementsByTagName('video')[0];
  2. if (video.canPlayType)
  3.    { // video tag supported
  4. if (video.canPlayType('video/ogg; codecs="theora, vorbis"'))
  5.       { // it may be able to play}
  6.         else
  7.       {// the codecs or container are not supported
  8.         fallback(video);
  9.   }
  10. }
If you want to do something more expressive than the simple fallback text, you can use the onerror event listener to pass the error to:
  1. <video src="video.mp4"
  2.        onerror="fallback(this)">
  3.        video not supported
  4. </video>
Using the poster property, you can specify the URL of an image to show in place of the video on the form. Usually you’re showing either a list of videos or a single video on a form, so having an easy way to show a preview of the video in the form of an image delivers a better user experience. Here is the poster property in action:
  1. <video src="video1.mp4" poster="preview.jpg" </video>
Finally, by using a bit of JavaScript and basic HTML, you can create a more interactive video player. Figure 4 shows how to add a video player to a form with JavaScript and how to respond to user input to the control.
Figure 4  Interacting with Video in JavaScript
  1. var video = document.createElement('video');
  2. video.src = 'video1.mp4';
  3. video.controls = true;
  4. document.body.appendChild(video);
  5. var video = new Video();
  6. video.src = 'video1.mp4';
  7. var video = new Video('video1.mp4')
  8. <script>
  9.     var video = document.getElementsByTagName('video')[0];
  10. </script>
  11. <input type="button" value="Play" onclick="video.play()">
  12. <input type="button" value="Pause" onclick="video.pause()">
For a complete list of events and capabilities for playing video, check out this section of the spec at http://www.w3.org/TR/html5/video.html#playing-the-media-resource.

Using the Audio Tag

Using the audio tag is much like using the video tag: you pass one or more audio files to the control, and the first one the browser supports is played.
  1. <audio src="audio.ogg" controls>
  2.  Your browser does not support the audio element.
  3. </audio>
Figure 5 lists the properties available in the audio tag. The control doesn’t need to display like a video player, so properties like height, width and poster are not included.
Figure 5 Audio Tag Properties

AttributeValueDescription
 AutoplayautoplayIf present, the audio starts playing as soon as it’s ready.
 ControlscontrolsControls, such as a play button, are displayed.
 LooploopIf present, the audio starts playing again (looping) when it reaches the end.
 PreloadpreloadIf present, the audio is loaded at page load, and is ready to run. It’s ignored if autoplay is present.
 SrcurlThe URL of the audio to play.

As with the video tag, you can pass multiple files to the audio tag and the first one that is supported will play. You can also use a fallback message when the browser doesn’t support the audio tag, like this:
  1. <audio controls autoplay>
  2.    <source src="audio1.ogg" type="audio/ogg" />
  3.    <source src="audio1.mp3" type="audio/mpeg" />
  4.     Your browser does not support the audio element.
  5. </audio>

Summary

HTML5 is the next standard for the Web, and depending on the browsers you’re targeting, you can start using some of the new tags, such as audio and video, right now. Be cautious when using HTML5, however, because not every browser supports the new tags, and even if one does, it might not support every media format. If you’re using a modern browser that does support HTML5, you still need to do the extra work to process your media in all formats to ensure user success. Here are some great Web resources that provide browser support information as well as all the other information you need to ensure HTML5 media success:

Tuesday 6 December 2011

Flash and Silverlight R.I.P.? The Wonderful World of HTML5

Say it isn’t so!

HTML5 is predicted to kill Flash and Silverlight, as well as destined to help resolve fragmentation in the mobile market! Is this good or bad? The following infographic provides information related to the wonderful world of HTML5.

HTML5 and the Death of Flash and Silverlight

Tuesday 29 November 2011

Microsoft must hit 4 Azure milestones ASAP

Next year could be a very big year for Windows Azure, Microsoft’s nearly two-year-old Platform-as-a-Service (PaaS). And, it better be, given the investment in man-power and dollars Microsoft poured into the effort which has not been as widely adopted as the company must have hoped. (Publicly, company execs are very happy with Azure’s traction, of course.)



The ambitious Azure platform launched in February 2010 with a lot of fanfare and expectations. A year later Microsoft claimed 31,000 subscribers although it was unclear how many of them paid.  But since then Azure lost steam and unlike Amazon, Heroku, VMware and other big names in the cloud, it just doesn’t get much love from the web developers it needs to woo.

All that can change if Microsoft delivers on promises to open up deployment options for Azure and to offer more bite-sized chunks of Azure services in Infrastructure-as-a-Service (IaaS) form. If it does that well and in a reasonable amount of time, Microsoft — which has always been chronically late  – will be tardy to the party but will get there in time to make an impression. After all, we are still relatively early in the cloud era.Here’s what Microsoft needs to do for Azure in the next few months:
Azure must run outside Microsoft data centers.
The company has to make Azure available outside its own four walls. Right now if you want to run apps on Windows Azure, they run in Microsoft data centers (or, since August in Fujitsu data centers.) Fujitsu also recently launched a hybrid option that allows it to run brand-new apps in Azure and connect them to legacy apps on its other cloud platform. We’re still waiting for Hewlett-Packard and Dell Azure implementations. (HP could announce this at its HP Discovershow this week.)  Down the road, all this work by hardware makers should result in an “Azure Appliance” architecture that would enable other data centers to run the PaaS.
Microsoft must offer VM Roles and Server AppV for IaaS fans.
Microsoft needs to offer  more bare-bones chunks of Azure services– akin to Amazon’s EC2.  That’s why Microsoft needs to get VM Roles in production mode as soon as possible.  VM Roles, in beta for a year, allows organizations to host their own virtual machines in the Azure cloud. Also coming is Microsoft Server AppV which should make it easier for businesses to move server-side applications from on-premises servers to Azure. “VM roles and Server AppV are the two IaaS components that Microsoft has not yet pushed into production. It still seems that Microsoft has not really focused on the IaaS aspect of Azure,” said Rob Sanfilippo, research vice president with Directions on Microsoft. Microsoft that focus now. As Microsoft adds IaaS capabilities to Azure, Amazon is also adding PaaS perks like Elastic Beanstalk, to its portfolio, so these companies are on a collision course.
System Center 2012 has to ease app migration and management.
Microsoft needs to make it easier for customers wanting to run private and public cloud implementations to manage both centrally. That’s the promise of Microsoft System Center 2012, due in the first half of 2012. With this release, customers that now must use System Center Virtual Machine Manager for private cloud and the Windows Azure interface for Azure will be able to manage both from the proverbial  ”one pane of glass.”  That’s a good thing, but not good enough. “It’s nice that System Center will be able to monitor stuff in both places, but what we need to be able to run stuff in either place,” said a .NET developer who tried Azure but moved to AWS.
 Microsoft must eat its own Azure “dog food.”
Right now precious few Microsoft applications run on Azure — there even seems to be confusion at Microsoft about this. One executive said that Xbox Live,  parts of CRM Online and Office 365 run on Azure only to be contradicted by a spokesperson who came back to say none of them actually do. Bing Games, however, do run on Azure. No matter: this is a schedule issue as almost all these applications predate Azure.  The next release of Dynamics NAV ERPapplication  will be the first Microsoft business application to run fully on Azure. There is no official due date, but Dynamics partners expect it next year. Three other Dynamics ERP products will follow. Directionally, Azure is where all Microsoft apps are going. “Our goal, of course, is that everything will be running on Azure,” said Amy Barzdukas, general manager of Microsoft’s server and tools unit.
In summary:  it’s not too late for Azure, but …
Microsoft has to get these things done — and soon — to counter AWS momentum and also that of rival PaaS offerings like Salesforce.com’s Heroku and Red Hat’s OpenShift which draw new-age, non-.NET oriented Web developers. Recent Gartner research shows PaaS will be a hot segment going forward. The researcher expects PaaS revenue to hit the $707 million by the end of this year, up from $512 million for 2010.  And it expects PaaS revenue to reach $1.8 billion in 2015. That’s good growth, but here will be more of the aforementioned players fighting for that pie. This is going to get good as younger cloud-era rivals are fighting to make Microsoft — the on-premises software giant —  irrelevant in this new arena. But one thing rivals in other eras have learned: It’s idiotic to underestimate this company.

Wednesday 23 November 2011

Embedding RavenDB into an ASP.NET MVC 3 Application

Attention to the NoSQL movement is growing within the Microsoft .NET Framework community as we continue to hear of companies sharing their implementation experiences of it in applications that we know and use. With this heightened awareness comes the curiosity to dig in and identify how a NoSQL data store could provide benefits or other potential solutions to the software that developers are currently crafting. But where do you start, and how hard is the learning curve? Maybe an even more relevant concern: How much time and effort are required to fire up a new data storage solution and start writing code against it? After all, you have the setup process of SQL Server for a new application down to a science, right?
Word has reached the .NET community on the wings of a raven about a new option for a NoSQL-type data-layer implementation. RavenDB (ravendb.net) is a document database designed for the .NET/Windows platform, packaged with everything you need to start working with a nonrelational data store. RavenDB stores documents as schema-less JSON. A RESTful API exists for direct interaction with the data store, but the real advantage lies within the .NET client API that comes bundled with the install. It implements the Unit of Work pattern and leverages LINQ syntax to work with documents and queries. If you’ve worked with an object-relational mapper (ORM)—such as the Entity Framework (EF) or NHibernate—or consumed a WCF Data Service, you’ll feel right at home with the API architecture for working with documents in RavenDB.
The learning curve for getting up and running with an instance of RavenDB is short and sweet. In fact, the piece that may require the most planning is the licensing strategy (but even that’s minimal). RavenDB offers an open source license for projects that are also open source, but a commercial license is required for closed source commercial projects. Details of the license and the pricing can be found at ravendb.net/licensing. The site states that free licensing is available for startup companies or those looking to use it in a noncommercial, closed source project. Either way, it’s worthwhile to quickly review the options to understand the long-term implementation potential before any prototyping or sandbox development.

RavenDB Embedded and MVC

RavenDB can be run in three different modes:
  1. As a Windows service
  2. As an IIS application
  3. Embedded in a .NET application
The first two have a fairly simple setup process, but come with some implementation strategy overhead. The third option, embedded, is extremely easy to get up and running. In fact, there’s a NuGet package available for it. A call to the following command in the Package Manager Console in Visual Studio 2010 (or a search for the term “ravendb” in the Manage NuGet Packages dialog) will deliver all of the references needed to start working with the embedded version of RavenDB:
Install-Package RavenDB-Embedded
Details of the package can be found on the NuGet gallery site at bit.ly/ns64W1.
Adding the embedded version of RavenDB to an ASP.NET MVC 3 application is as simple as adding the package via NuGet and giving the data store files a directory location. Because ASP.NET applications have a known data directory in the framework named App_Data, and most hosting companies provide read/write access to that directory with little or no configuration required, it’s a good place to store the data files. When RavenDB creates its file storage, it builds a handful of directories and files in the directory path provided to it. It won’t create a top-level directory to store everything. Knowing that, it’s worthwhile to add the ASP.NET folder named App_Data via the Project context menu in Visual Studio 2010 and then create a subdirectory in the App_Data directory for the RavenDB data (see Figure 1).
App_Data Directory Structure
Figure 1 App_Data Directory Structure
A document data store is schema-less by nature, hence there’s no need to create an instance of a database or set up any tables. Once the first call to initialize the data store is made in code, the files required to maintain the data state will be created.
Working with the RavenDB Client API to interface with the data store requires an instance of an object that implements the Raven.Client.IDocumentStore interface to be created and initialized. The API has two classes, DocumentStore and EmbeddedDocumentStore, that implement the interface and can be used depending on the mode in which RavenDB is running. There should only be one instance per data store during the lifecycle of an application. I can create a class to manage a single connection to my document store that will let me access the instance of the IDocumentStore object via a static property and have a static method to initialize the instance (see Figure 2).
Figure 2 Class for DocumentStore
public class DataDocumentStore
{
  private static IDocumentStore instance;
 
  public static IDocumentStore Instance
  {
    get
    {
      if(instance == null)
        throw new InvalidOperationException(
          "IDocumentStore has not been initialized.");
      return instance;
    }
  }
 
  public static IDocumentStore Initialize()
  {
    instance = new EmbeddableDocumentStore { ConnectionStringName = "RavenDB" };
    instance.Conventions.IdentityPartsSeparator = "-";
    instance.Initialize();
    return instance;
  }
}
The static property getter checks a private static backing field for a null object and, if null, it throws an InvalidOperationException. I throw an exception here, rather than calling the Initialize method, to keep the code thread-safe. If the Instance property were allowed to make that call and the application relied upon referencing the property to do the initialization, then there would be a chance that more than one user could hit the application at the same time, resulting in simultaneous calls to the Initialize method. Within the Initialize method logic, I create a new instance of the Raven.Client.Embedded.EmbeddableDocumentStore and set the ConnectionStringName property to the name of a connection string that was added to the web.config file by the install of the RavenDB NuGet package. In the web.config, I set the value of the connection string to a syntax that RavenDB understands in order to configure it to use the embedded local version of the data store. I also map the file directory to the Database directory I created in the App_Data directory of the MVC project:
<connectionStrings>
  <add name="RavenDB " connectionString="DataDir = ~\App_Data\Database" />
</connectionStrings>
The IDocumentStore interface contains all of the methods for working with the data store. I return and store the EmbeddableDocumentStore object as an instance of the interface type IDocumentStore so I have the flexibility of changing the instantiation of the EmbeddedDocumentStore object to the server version (DocumentStore) if I want to move away from the embedded version. This way, all of my logic code that will handle my document object management will be decoupled from the knowledge of the mode in which RavenDB is running.
RavenDB will create document ID keys in a REST-like format by default. An “Item” object would get a key in the format “items/104.” The object model name is converted to lowercase and is pluralized, and a unique tracking identity number is appended after a forward slash with each new document creation. This can be problematic in an MVC application, as the forward slash will cause a new route parameter to be parsed. The RavenDB Client API provides a way to change the forward slash by setting the IdentityPartsSeparator value. In my DataDocumentStore.Initialize method, I’m setting the IdentityPartsSeparator value to a dash before I call the Initialize method on the EmbeddableDocumentStore object, to avoid the routing issue.
Adding a call to the DataDocumentStore.Initialize static method from the Application_Start method in the Global.asax.cs file of my MVC application will establish the IDocumentStore instance at the first run of the application, which looks like this:
protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);
 
  DataDocumentStore.Initialize();
}
From here I can make use of the IDocumentStore object with a static call to the DataDocumentStore.Instance property to work on document objects from my embedded data store within my MVC application.

RavenDB Objects

To get a better understanding of RavenDB in action, I’ll create a prototype application to store and manage bookmarks. RavenDB is designed to work with Plain Old CLR Objects (POCOs), so there’s no need to add property attributes to guide serialization. Creating a class to represent a bookmark is pretty straightforward. Figure 3 shows the Bookmark class.
Figure 3 Bookmark Class
public class Bookmark
{
  public string Id { get; set; }
  public string Title { get; set; }
  public string Url { get; set; }
  public string Description { get; set; }
  public List<string> Tags { get; set; }
  public DateTime DateCreated { get; set; }
 
  public Bookmark()
  {
    this.Tags = new List<string>();
  }
}
RavenDB will serialize the object data into a JSON structure when it goes to store the document. The well-known “Id” named property will be used to handle the document ID key. RavenDB will create that value—provided the Id property is empty or null when making the call to create the new document—and will store it in a @metadata element for the document (which is used to handle the document key at the data-store level). When requesting a document, the RavenDB Client API code will set the document ID key to the Id property when it loads the document object.
The JSON serialization of a sample Bookmark document is represented in the following structure:
{
  "Title": "The RavenDB site",
  "Url": "http://www.ravendb.net",
  "Description": "A test bookmark",
  "Tags": ["mvc","ravendb"],
  "DateCreated": "2011-08-04T00:50:40.3207693Z"
}
The Bookmark class is primed to work well with the document store, but the Tags property is going to pose a challenge in the UI layer. I’d like to let the user enter a list of tags separated by commas in a single text box input field and have the MVC model binder map all of the data fields without any logic code seeping into my views or controller actions. I can tackle this by using a custom model binder for mapping a form field named “TagsAsString” to the Bookmark.Tags field. First, I create the custom model binder class (see Figure 4).
Figure 4 BookmarkModelBinder.cs
public class BookmarkModelBinder : DefaultModelBinder
{
  protected override void OnModelUpdated(ControllerContext controllerContext,
    ModelBindingContext bindingContext)
  {
    var form = controllerContext.HttpContext.Request.Form;
    var tagsAsString = form["TagsAsString"];
    var bookmark = bindingContext.Model as Bookmark;
    bookmark.Tags = string.IsNullOrEmpty(tagsAsString)
      ? new List<string>()
      : tagsAsString.Split(',').Select(i => i.Trim()).ToList();
  }
}
Then I update the Globals.asax.cs file to add the BookmarkModelBinder to the model binders at application startup:
protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);
 
  ModelBinders.Binders.Add(typeof(Bookmark), new BookmarkModelBinder());
  DataDocumentStore.Initialize();
}
To handle populating an HTML text box with the current tags in the model, I’ll add an extension method to convert a List<string> object to a comma-separated string:
public static string ToCommaSeparatedString(this List<string> list)
{
  return list == null ? string.Empty : string.Join(", ", list);
}

Unit of Work

The RavenDB Client API is based on the Unit of Work pattern. To work on documents from the document store, a new session needs to be opened; work needs to be done and saved; and the session needs to close. The session handles change tracking and operates in a manner that’s similar to a data context in the EF. Here’s an example of creating a new document:
using (var session = documentStore.OpenSession())
{
  session.Store(bookmark);
  session.SaveChanges();
}
It’s optimal to have the session live throughout the HTTP request so it can track changes, use the first-level cache and so on. I’ll create a base controller that will use the DocumentDataStore.Instance to open a new session on action executing, and on action executed will save changes and then dispose of the session object (see Figure 5). This allows me to do all of the work desired during the execution of my action code with a single open session instance.
Figure 5 BaseDocumentStoreController
public class BaseDocumentStoreController : Controller
{
  public IDocumentSession DocumentSession { get; set; }
 
  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    if (filterContext.IsChildAction)
      return;
    this.DocumentSession = DataDocumentStore.Instance.OpenSession();
    base.OnActionExecuting(filterContext);
  }
 
  protected override void OnActionExecuted(ActionExecutedContext filterContext)
  {
    if (filterContext.IsChildAction)
      return;
    if (this.DocumentSession != null && filterContext.Exception == null)
      this.DocumentSession.SaveChanges();
    this.DocumentSession.Dispose();
    base.OnActionExecuted(filterContext);
  }
}

MVC Controller and View Implementation

The BookmarksController actions will work directly with the IDocumentSession object from the base class and manage all of the Create, Read, Update and Delete (CRUD) operations for the documents. Figure 6 shows the code for the bookmarks controller.
Figure 6 BookmarksController Class
public class BookmarksController : BaseDocumentStoreController
{
  public ViewResult Index()
  {
    var model = this.DocumentSession.Query<Bookmark>()
      .OrderByDescending(i => i.DateCreated)
      .ToList();
    return View(model);
  }
 
  public ViewResult Details(string id)
  {
    var model = this.DocumentSession.Load<Bookmark>(id);
    return View(model);
  }
 
  public ActionResult Create()
  {
    var model = new Bookmark();
    return View(model);
  }
 
  [HttpPost]
  public ActionResult Create(Bookmark bookmark)
  {
    bookmark.DateCreated = DateTime.UtcNow;
    this.DocumentSession.Store(bookmark);
    return RedirectToAction("Index");
  }
   
  public ActionResult Edit(string id)
  {
    var model = this.DocumentSession.Load<Bookmark>(id);
    return View(model);
  }
 
  [HttpPost]
  public ActionResult Edit(Bookmark bookmark)
  {
    this.DocumentSession.Store(bookmark);
    return RedirectToAction("Index");
  }
 
  public ActionResult Delete(string id)
  {
    var model = this.DocumentSession.Load<Bookmark>(id);
    return View(model);
  }
 
  [HttpPost, ActionName("Delete")]
  public ActionResult DeleteConfirmed(string id)
  {
    this.DocumentSession.Advanced.DatabaseCommands.Delete(id, null);
    return RedirectToAction("Index");
  }
}
The IDocumentSession.Query<T> method in the Index action returns a result object that implements the IEnumerable interface, so I can use the OrderByDescending LINQ expression to sort the items and call the ToList method to capture the data to my return object. The IDocumentSession.Load method in the Details action takes in a document ID key value and de-serializes the matching document to an object of type Bookmark.
The Create method with the HttpPost verb attribute sets the CreateDate property on the bookmark item and calls the IDocumentSession.Store method off of the session object to add a new document record to the document store. The Update method with the HttpPost verb can call the IDocumentSession.Store method as well, because the Bookmark object will have the Id value already set. RavenDB will recognize that Id and update the existing document with the matching key instead of creating a new one. The DeleteConfirmed action calls a Delete method off of the IDocumentSession.Advanced.DatabaseCommands object, which provides a way to delete a document by key without having to load the object first. I don’t need to call the IDocumentSession.SaveChanges method from within any of these actions, because I have the base controller making that call on action executed.
All of the views are pretty straightforward. They can be strongly typed to the Bookmark class in the Create, Edit and Delete markups, and to a list of bookmarks in the Index markup. Each view can directly reference the model properties for display and input fields. The one place where I’ll need to vary on object property reference is with the input field for the tags. I’ll use the ToCommaSeparatedString extension method in the Create and Edit views with the following code:
@Html.TextBox("TagsAsString", Model.Tags.ToCommaSeparatedString())
This will allow the user to input and edit the tags associated with the bookmark in a comma-delimited format within a single text box.

Searching Objects

With all of my CRUD operations in place, I can turn my attention to adding one last bit of functionality: the ability to filter the bookmark list by tags. In addition to implementing the IEnumerable interface, the return object from the IDocumentSession.Query method also implements the IOrderedQueryable and IQueryable interfaces from the .NET Framework. This allows me to use LINQ to filter and sort my queries. For example, here’s a query of the bookmarks created in the past five days:
var bookmarks = session.Query<Bookmark>()
  .Where( i=> i.DateCreated >= DateTime.UtcNow.AddDays(-5))
  .OrderByDescending(i => i.DateCreated)
  .ToList();
Here’s one to page through the full list of bookmarks:
var bookmarks = session.Query<Bookmark>()
  .OrderByDescending(i => i.DateCreated)
  .Skip(pageCount * (pageNumber – 1))
  .Take(pageCount)
  .ToList();
RavenDB will build dynamic indexes based on the execution of these queries that will persist for “some amount of time” before being disposed of. When a similar query is rerun with the same parameter structure, the temporary dynamic index will be used. If the index is used enough within a given period, the index will be made permanent. These will persist beyond the application lifecycle.
I can add the following action method to my BookmarksController class to handle getting bookmarks by tag:
public ViewResult Tag(string tag)
{
  var model = new BookmarksByTagViewModel { Tag = tag };
  model.Bookmarks = this.DocumentSession.Query<Bookmark>()
    .Where(i => i.Tags.Any(t => t == tag))
    .OrderByDescending(i => i.DateCreated)
    .ToList();
  return View(model);
}
I expect this action to be hit on a regular basis by users of my application. If that’s indeed the case, this dynamic query will get turned into a permanent index by RavenDB with no additional work needed on my part.

A Raven Sent to Awaken Us

With the emergence of RavenDB, the .NET community appears to finally have a NoSQL document store-type solution catered toward it, allowing Microsoft-centric shops and developers to glide through the nonrelational world that so many other frameworks and languages have been navigating for the past few years. Nevermore shall we hear the cries of a lack of nonrelational love for the Microsoft stack. RavenDB is making it easy for .NET developers to start playing and prototyping with a nonrelational data store by bundling the install with a clean client API that mimics data-management techniques that developers are already employing. While the perennial argument between relational and nonrelational surely won’t die out, the ease of trying out something “new” should help lead to a better understanding of how and where a nonrelational solution can fit within an application architecture.