Showing posts with label MSDN Magazine. Show all posts
Showing posts with label MSDN Magazine. Show all posts

11/06/2011

HTML5 Offline Applications: ‘Donut Hole’ Caching

Craig Shoemaker

HTML Offline Applications allow you to create applications that work without an Internet connection using technologies native to the Web browser. Pages included in an offline application are listed in the application manifest and thus are served from the application cache whether a connection to the Internet is present or not. Sometimes, however, if an Internet connection is available, you may want to display some data from the server without requiring the user to change pages.
Scott Guthrie introduced the concept of “donut hole” caching in ASP.NET, where a cached page may include small windows of content that are updated independently of the cached page. This tutorial demonstrates how to implement an offline page that makes an AJAX call when connected to the Web in order to display live data to the user. When offline, the page simply renders default data in the page.
There are a number of practical reasons to implement an offline application. While most developers first think of the mobile context when considering who might use an offline application, almost any Web site can benefit from having some availability regardless of connection status. A site’s Home and Contact Us pages are excellent candidates for offline availability so users can get some basic information about the organization, even when disconnected.

Building the Application

The example in this tutorial demonstrates how to cache a “Contact Us” page that displays notifications of upcoming events to users. When a user is connected to the Web, live event listings are displayed; otherwise, a telephone number prompts the user to call for event information. This approach keeps the user informed and connected with or without access to the public Web.
Figure 1 depicts how the page is rendered for offline viewing, while Figure 2 shows how the page looks when served from the application cache but the computer is connected to the Web.
When the User Is Working Offline, the Application Prompts Him to Call for Event Information
Figure 1 When the User Is Working Offline, the Application Prompts Him to Call for Event Information

When the User Is Connected to the Internet, the Application Shows Event Information from the Server
Figure 2 When the User Is Connected to the Internet, the Application Shows Event Information from the Server

The Manifest

The application manifest acts as the master list of resources included in the offline application. Figure 3 shows the full manifest file for this example.
Figure 3 Manifest File (manifest.aspx)
CACHE MANIFEST
# version 1
CACHE:
contact.htm
style.css
jquery-1.6.3.min.js
map.png
NETWORK:
events.htm
<%@Page
    ContentType="text/cache-manifest"
    ResponseEncoding = "utf-8"
    Language="C#" AutoEventWireup="true"
    CodeBehind="manifest.aspx.cs"
    Inherits="ConditionalCaching.manifest" %>
<script language="CS" runat="server">
  void Page_Load(object sender, System.EventArgs e)
    {
      Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
</script>
The file begins with the requisite CACHE MANIFEST header and includes a versioning comment to allow changes in listed files to propagate to the client.
Next, the CACHE section references the contact page intended to be available to users regardless of connection status. The contact page references a style sheet, jQuery and a map image indicating the physical office location.
Finally, the NETWORK section is needed in this instance to ensure access to the events.htm page (shown in Figure 4). The reason this page isn’t included in the CACHE section is because in the real world the events page would be built dynamically as a server-generated page. Caching a page like this would defeat the purpose of making live event data available to the user when connected to the Web. With the events page listed in the NETWORK section rather than the CACHE section, the Application Cache API won’t attempt to cancel the request to the page. Ultimately, the page’s inclusion in the NETWORK section tells the browser to always attempt to fetch the page from the Web regardless of connection state.
Figure 4 Events Page (events.htm)
<table border="1" cellpadding="2" cellspacing="0">
  <tr>
    <td>Aug 15</td>
    <td><a href="/events/anaheim">Anahiem Convention Center</a></td>
  </tr>
  <tr>
    <td>Sept 5</td>
    <td><a href="/events/los-angeles">Los Angeles Convention Center</a></td>
  </tr>
  <tr>
    <td>Oct 3</td>
    <td><a href="/events/las-vegas">Las Vegas Convention Center</a></td>
  </tr>
  <tr>
    <td>Nov 14</td>
    <td><a href="/events/denver">Colorado Convention Center</a></td>
  </tr>
</table>
Note that the manifest is implemented as an ASPX file in order to disable browser caching of the file. You may prefer to disable caching on the Web server via configuration settings, but this approach is used here to make the sample code more portable for demonstration purposes.

The Contact Us Page

The contact page HTML, shown in Figure 5, is implemented as you might expect regardless of whether the page is being optimized for offline access. The most important detail to note in the HTML for the page is the contents of the paragraph with the ID of localMessage. This container holds the content that’s displayed when the user is working offline; that content is replaced on-the-fly when a connection to the Internet is available.
Figure 5 Contact Page (contact.htm)
<!DOCTYPE html>
<html manifest="manifest.aspx">
<head>
  <title></title>
  <link rel="Stylesheet" href="style.css" type="text/css" />
  <script src="jquery-1.6.3.min.js" type="text/javascript"></script>
  <script>
    $(function () {
      window.applicationCache.onupdateready = function (e) {
        applicationCache.swapCache();
        window.location.reload();
      }
      function isOnLine() {
        //return false;
        return navigator.onLine;
      }
      function showEventInfo() {
        if (isOnLine()) {
            $("#localMessage").hide();
            $.get("/events.htm", function (data) {
                $("#eventList").html(data);
                $("#eventList table tr:odd").addClass("alt");
            });
        }
        else {
          $("#localMessage").show();
        }
      }
      showEventInfo();
    });
  </script>
</head>
<body>
  <div id="container">
    <h1>Awesome Company</h1>
    <h2>Contact Us</h2>
    <p>
      Awesome Company<br />
      1800 Main Street<br />
      Anytown, CA 90210<br />
      (800) 555-5555<br />
      <a href="mailto:awesome@company.com">awesome@company.com</a>
    </p>
    <img src="map.png" />
    <div id="events">
      <h2>Events</h2>
      <p>We are coming to a city near you!</p>
      <p id="localMessage">Give us a call at (800) 555-5555
        to hear about our upcoming conference dates.</p>
      <div id="eventList"></div>
    </div>
    <div id="version">Version 1</div>
  </div>
</body>
</html>
Note that in the script section of the page, all functions are defined and run nested in the jQuery document-ready handler:
$(function () {
    ...
});
The first order of business is to process any updates to the page loaded in the application cache by handling the updateready events. If the application manifest changes, all the files listed in its CACHE section are copied to the client. When new versions of the files are available, the updateready event fires and the page can load the latest version of the contact page from the cache by calling applicationCache.swapCache. Finally, once the latest version is loaded into memory, the page is reloaded in order to display the changes to the user:
window.applicationCache.onupdateready = function (e) {
  applicationCache.swapCache();
  window.location.reload();
}
Next, the page needs a mechanism to detect whether the computer is working in a connected or disconnected state. The isOnLine function simply wraps up a call to the read-only navigator.onLine Boolean property. This encapsulation is handy because, should you want to override the value for testing purposes, you can un-comment the return false line and test the page’s offline behavior without having to actually disconnect from the Web:
function isOnLine() {
  //return false;
  return navigator.onLine;
}
By the way, using navigator.onLine as the sole mechanism for detecting online status is a bit rudimentary. For a more robust way to detect online status, please read the tutorial, “Working Off the Grid with HTML5 Offline,” by Paul Kinlan.
The showEvent function is responsible for implementing the “donut hole caching” functionality for the HTML offline application. The function first detects the connection status of the computer and then either fetches and renders live event data or just shows the event information that already exists in the page.
If the isOnLine function returns true, the local message is hidden from the user and an AJAX call to the events page is initiated. When a response from the asynchronous call is recognized, the resulting HTML is fed to the eventList container and the table is styled with zebra striping.
If, on the other hand, the computer is working offline, the local message is displayed to the user like so:
function showEventInfo() {
  if (isOnLine()) {
      $("#localMessage").hide();
      $.get("/events.htm", function (data) {
        $("#eventList").html(data);
        $("#eventList table tr:odd").addClass("alt");
      });
  }
  else {
    $("#localMessage").show();
  }
}
Finally, the manifest file is referenced at the top of the HTML page by populating the manifest attribute of the html element pointing to the manifest file:
<html manifest="manifest.aspx">
Figure 6 shows the style.css file that’s listed in the manifest and referenced by the contact page.
Figure 6 Style Sheet (style.css)
body
{
  font-family:Segoe UI, Arial, Helvetica, Sans-Serif;
  background-color:#eee;
}
h1
{
  text-transform:uppercase;
  letter-spacing:-2px;
  width:400px;
  margin-top:0px;
}
#container
{
  position:relative;
  margin-left:auto;
  margin-right:auto;
  padding:20px;
  width:700px;
  -webkit-box-shadow: 3px 3px 7px #999;
  box-shadow: 6px 6px 24px #999;
  -moz-border-radius: 10px; 
  -webkit-border-radius: 10px;
  border-radius: 10px;
  margin-top:20px;
  background-color:#fff;
}
#events
{
  position:absolute;
  width:210px;
  right:20px;
  top:255px;
  border:1px solid #ccc;
  padding:10px;
  font-size:.7em;
  background-color:#eee;
}
#events h2
{
  margin:0px;
}
#version
{
  font-size:.7em;
  color:#ccc;
}
table
{
  border-collapse:collapse;
}
table, tr, td
{
  border:1px solid #999;
}
.alt
{
  background-color:#ccc;
}

Wrapping Up

Even though pages loaded into the application cache are served from the cache whether the computer is connected to the Internet or not, you can construct your pages to take advantage of online resources when they’re available. “Donut hole caching” works by making an AJAX call to the server when a connection is available and then rendering the results to the user. If the page is in a disconnected state, the application quietly renders data already available on the page—it’s the best of both worlds!

 

Better Web Forms with HTML5 Forms

Brandon Satrom

Download the Code Sample
If you’re a Web developer, you’ve probably created an HTML Form before. In fact, you may have created more of them than you care to remember. You’re no doubt familiar with classic input types like text, password, file, hidden, checkbox, radio, submit and button, and you’ve probably used most or all of these at various times.
If I were to ask you what type of input—from the previous list—you use more than any other, you’d probably say “text,” as would most of us. The text input type is the multitool of classic HTML Forms development. On the one hand, it’s able to adapt to nearly any job you give it, but on the other, it’s semantically neutral, so the browser offers no help in turning this element into something practical. To compensate, developers and designers have added their own semantics to these elements (via IDs and class names) and have relied on server frameworks and JavaScript to handle validation and add rich interactions.
A classic example is collecting dates in text fields. Most of the time, you want to enhance a date field with a date picker of some kind. This is often done with hand-rolled JavaScript or a framework like jQuery UI, which adds an interaction behavior that allows the user to select a date from a widget and have that date populated into the original field.
As useful as that pattern is—and we’ve become quite adept as developers with patterns like this—it’s repeated so often that you can’t help but ask, “Why can’t the browser just do it?”
The good news is that, with HTML5 Forms, the browser can—and will. In addition to text and the handful of existing types we’ve had for years, HTML5 adds 13 new values for the input type attribute, as well as a host of other attributes that will speed up your forms development. This month, I’ll share some of the new input types and attributes coming with HTML5 Forms, as well as their implementation status in various browsers. Next, I’ll present a quick overview of new client validation features for HTML5 Forms. 
Finally, I’ll take a look at how recent updates to Visual Studio 2010 and the Microsoft .NET Framework 4 enable HTML5 Forms and ASP.NET Web Forms to play well together. Throughout, I’ll discuss how you can embrace HTML5 Forms in your applications today, while providing fallback solutions for older browsers. All of the demos for this article—which are available online—were built using WebMatrix, a free, lightweight Web development tool from Microsoft. You can try WebMatrix out for yourself at aka.ms/webm.

New Input Types in HTML5

What we know today as HTML5 Forms or HTML5 Web Forms started as Web Forms 2.0, a pre-HTML5 specification authored by a group known as the Web Hypertext Applications Technology Working Group, or WHATWG. Much of the initial work by WHATWG became the starting point for what we now call HTML5, and the Web Forms 2.0 effort is now part of the official HTML5 specification, which you can read at bit.ly/njrWvZ. A significant portion of the specification is dedicated to new types and content attributes for the input element, which you’ll find at bit.ly/pEdWFs.
As I mentioned, the specification introduces 13 new input types for use in forms: search, tel, url, email, datetime, date, month, week, time, datetime-local, number, range, color.
Using these new types is simple. Say I want to put a new e-mail field on an order form. As you can see in Figure 1, I’ve modified the WebMatrix Bakery Template Web site’s Order page with some additional fields, including e-mail.
A Sample Order Form
Figure 1 A Sample Order Form
For this form, the e-mail field is marked up like so:
<input type="email" id="orderEmail" />
Notice that the type attribute is equal to “email” instead of “text.” The best part about the new HTML input types is that you can use them today and they work, at some level, in every single browser. When a browser encounters one of these new types, one of two things will happen.
If the browser doesn’t support the new input types, the type declaration won’t be recognized. In this case, the browser will gracefully degrade and treat the element as type=“text.” You can try this by putting this element on a form and typing “document.getElementById(‘orderEmail’).type” in the Internet Explorer 9 F12 Tools Console. So, you can use these new types today, and if the browser doesn’t support a given field, it will continue to work just like a regular text field.
If the browser does recognize a type, however, you’ll gain some immediate benefits by using it. For recognized types, the browser adds some type-specific built-in behavior. In the case of the email type, Internet Explorer 10 Platform Preview 2 (PP2) and later will automatically validate any input, and present the user with an error message if the provided value isn’t a valid e-mail address, as shown in Figure 2.
Automatic Browser Validation of the Email Input Type
Figure 2 Automatic Browser Validation of the Email Input Type
It’s easy to infer the purpose and behavior of each element by its type, so we readily gain another level of semantic richness in our forms. Moreover, some of these new input types let the browser provide richer interactions to users out of the box. For example, if I place the following element on a form and then open that form in a browser that fully supports the date input type, the default interaction is much richer than a plain old text box:
<input type="date" id="deliveryDate" />
Figure 3 shows what the date type can provide in Opera 11.5. The best part is that all I had to do to get this interaction was specify type=“date” and the browser took care of all the manual work I previously had to do in JavaScript to offer this level of functionality.
The Date Input Type in Opera 11.5
Figure 3 The Date Input Type in Opera 11.5
It’s important to note that the HTML5 specification doesn’t dictate how browsers should present these new input types, or how they should present validation errors, so you can expect to see subtle to major differences among browsers. For example, Chrome 13 presents a spinner control for the date rather than a date picker, as shown in Figure 4 (which, of course, may have changed by the time you read this). You should also know that there’s ongoing discussion in the World Wide Web Consortium, or W3C, around browser styling and localization of elements like datetime, date and color. The browsers don’t all agree, at present, on how to implement these types, and there’s no current customization mechanism within 
existing implementations that’s similar to what you’d find with jQuery UI. Should you choose to implement or experiment with these new types, always be sure to provide a thorough fallback solution. In addition, if consistency of presentation and behavior is important to your users, you may need to apply custom styles, override default behaviors on these controls or use a script-based solution.
The Date Input Type in Chrome 13
Figure 4 The Date Input Type in Chrome 13
Earlier I stated that these fields will still behave as regular text fields, which is a nice piece of graceful degradation the browsers provide for us. But a date field implemented as a plain text box is clunky, and widely considered a poor user experience. With a little help from Modernizr and jQuery UI, however, you can provide a solution that mixes the best of HTML5 Forms with a nice fallback solution.
You’ll recall from my last article (msdn.microsoft.com/magazine/hh394148) that Modernizr (modernizr.com) is a JavaScript library that can help you detect support for HTML5 features in the browser. For this example, I want to use Modernizr to help detect support for the HTML5 date input type and, if it’s not supported, use the jQuery UI (jqueryui.com) datepicker widget to provide a similar user experience. Once I’ve downloaded and added references for Modernizr, jQuery and jQuery UI, I can add fallback support for my date elements with just a few lines of code:
if (!Modernizr.inputtypes.date) {
  $("input[type=date]").datepicker();
}
The result, as seen in Internet Explorer 10 PP2, is depicted in Figure 5.
Date Field Support with jQuery UI
Figure 5 Date Field Support with jQuery UI

New Input Content Attributes in HTML5

In addition to the new input types, HTML5 provides some handy new content attributes that can be used on input fields to supply validation support and enhanced functionality. One of those new attributes is “placeholder,” which, according to the specification, “…represents a short hint (a word or short phrase) intended to aid the user with data entry” (emphasis theirs). For example, I can take a couple of the fields from our order form and add placeholder=“some text” to each field, with the result shown in Figure 6:
<input type="email" id="orderEmail" placeholder="ex. name@domain.com" />
<input type="url" id="orderWebsite" placeholder="ex. http://www.domain.com" />
Using the Placeholder Attribute with Input Fields
Figure 6 Using the Placeholder Attribute with Input Fields
The placeholder text is lighter in color than normal text, and if I place focus on each field, the text disappears, enabling me to 
enter my own value.
As with the new input types, the placeholder attribute isn’t supported in older browsers. Nothing bad will happen if a user visits a page with them, though, so consider using them today, even if you don’t plan to add support for older browsers. If you do want to “polyfill” placeholder support, Modernizr can help. As I mentioned in my last article, the good folks at Modernizr try to keep a running list of every polyfill and fallback you could possibly want for a given HTML5 feature. You can check that list out at bit.ly/nZW85d.
For this example, let’s use the jQuery HTML5 Placeholder created by Mike Taylor, which you can download from bit.ly/pp9V4s. Once you have it, add the following to a script block referenced by your page:
Modernizr.load({
    test: Modernizr.input.placeholder,
    nope: "../js/html5placeholder.jquery.min.js",
    callback: function() {
      $('input[placeholder]').placeholder();
    }
  });
Here, Modernizr tests whether the placeholder attribute is supported and if it’s not, loads html5placeholder.jquery.min.js. jQuery then selects every element with a placeholder attribute and adds plug-in support to each. If you try this out in Internet Explorer 9, you’ll notice that the end result looks very similar to the native browser support provided in Internet Explorer 10 PP2.
Another interesting new attribute is “autofocus,” which, as it sounds, lets you specify a single form field to automatically receive focus when a page loads. Only one field per page should hold this attribute; if multiple elements are marked up with autofocus, the first one with that declaration receives focus on page load. For my order form, I want the Name field to receive focus, so I add the attribute like so:
<input type="text" class="field" id="orderName" autofocus />
The autofocus attribute can be used on any form control, and is an excellent alternative to the script-based, form-focused strategies many Web developers have fought with in the past.

HTML5 Form Validation

I don’t have the space to cover all the interesting new form-related attributes here, but I’ll spend a few moments talking about “required,” “pattern,” “novalidate” and “formnovalidate,” all of which make client-side form validation a snap.
For browsers that support it, the “required” attribute tells the browser that this form can’t be submitted without a value. For example, I add “required” to the Name field of my order form:
<input type="text" class="field" id="orderName" required />
When I visit this page in the Internet Explorer 10 PP2 and attempt to submit the form, I see something like what’s shown in Figure 7. With a single attribute, the browser knows enough to style the element with a red border and display a message to the user indicating that the field is required.
Using the Required Attribute on a Form Field
Figure 7 Using the Required Attribute on a Form Field
Earlier, Figure 2 showed how the browser can automatically validate certain types, such as “email” and “url,” without additional input from the user. With the “pattern” attribute, you can provide your own validation test for input types. According to the HTML5 specification, “pattern” expects a regular expression, which the browser uses to validate the owning field.
My order form contains a telephone (type=“tel”) field and I can specify a validation pattern like this:
<input type="tel" id="orderTelephone" pattern="\(\d\d\d\) \d\d\d\-\d\d\d\d" title="(xxx) xxx-xxxx" />
This (not very complex) regular expression tells the browser to expect a seven-digit number with parentheses around the area code and a dash in the local number. Entering anything else results in the message shown in Figure 8. Notice that the message contains instructions to the user on how to format input: “(xxx) xxx-xxxx.” This part of the message is taken from the title attribute of the same element, so it’s possible to control at least part of the validation message via your markup. There’s one thing to note when using title to aid in validation, though. According to the spec, the browser may choose to show the title in other, non-error cases, so don’t count on this attribute as a place for error-sounding text.
Using the Pattern Attribute to Specify a Validation Expression
Figure 8 Using the Pattern Attribute to Specify a Validation Expression
Automating validation by the browser is nice, but two immediate questions come to mind. First, what about server validation or client validation scripts generated by my server framework (ASP.NET MVC, for example)? And second, what about cases where I want the user to be able to save the form as a work in progress, without validation? The first is, unfortunately, outside the scope of this article, but I’ve written a blog post about this very subject in ASP.NET MVC, which you can find at bit.ly/HTML5FormsAndMVC.
The second question, on the other hand, is easy. Let’s assume you have a form that users will spend quite a bit of time on before submitting, perhaps even saving multiple times before finally posting it to your server. For such cases, where you’ll want to allow a user to submit a form without validation, there are two attributes you can use: “formnovalidate,” which is placed on input fields of type “submit,” and “novalidate,” which is placed on an opening form tag. Here I’ll place two submit fields on my form, like so:
<input type="submit" value="Place Order" />
<input type="submit" formnovalidate value="Save for Later" id="saveForLater" />
The “formnovalidate” attribute on the second button will turn off validation and submit the form, allowing the user’s work in progress to be saved in my database, or even on the client side using a new HTML5 storage technology like localStorage or IndexedDB.

HTML5 Forms and ASP.NET Web Forms

Before I wrap up this article, I want to share a few additional bits of information related to HTML5 Forms for ASP.NET Web Forms developers. If you’re planning to do HTML5 Forms development with ASP.NET Web Forms, there’s good news: Many HTML5-related updates to .NET and Visual Studio are being released out-of-band, so you don’t have to wait for the next framework version to use these features today.
To get started with HTML5 Forms and ASP.NET Web Forms, you’ll need to grab a couple of updates. First, make sure you have Visual Studio 2010 SP1 (bit.ly/nQzsld). In addition to adding support for new HTML5 input types and attributes, the service pack also provides some updates that enable you to use the new HTML5 input types on the TextBox server control. Without this update, you’d see compile-time errors when using the new types.
You’ll also want to grab the Microsoft .NET Framework 4 Reliability Update 1 (bit.ly/qOG7Ni). This update is designed to fix a handful of problems related to using the new HTML5 input types with ASP.NET Web Forms. Scott Hunter covers a few of those—UpdatePanel, Validation Controls and Callbacks—in a blog post from early August that you can check out at bit.ly/qE7jLz.
The addition of Web Forms support to browsers with HTML5 is good news for Web developers everywhere. Not only do we have a set of semantic input types to leverage in our applications, but we can also use these input types today with no ill effects in older browsers, while getting enhanced functionality—including automatic client validation—in newer ones. Using these new fields right away has immediate benefits in the mobile application space as well, where using types like “url” and “email” will prompt mobile devices to present the user with soft keyboard options tuned for that input type. When you combine these new features with Modernizr and one of the great polyfilling options, you have all the tools you need to adopt HTML5 Forms in your applications right now.
For more information on HTML5 Forms support in Internet Explorer 10 PP2, go to ietestdrive.com, and be sure to check out the developer’s guide at the Internet Explorer Developer Center (bit.ly/r5xKhN). For a deeper dive into HTML5 Forms in general, I recommend “A Form of Madness,” from Mark Pilgrim’s book “HTML5: Up and Running” (O’Reilly Media, 2010), as well as the Forms section of the W3C HTML5 specification (bit.ly/nIKxfE).    

 

Working with Media in HTML5

Jason Beres

 

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
<section>
    <h1>Using the HTML5 Video tag to play video</h1>
    <video src="video1.mp4" >
    </video>
</section>
<section>
    <h1>Using the Object tag to play media using the Flash plug-in</h1> 
    <object type="application/x-shockwave-flash"
               data="player.swf" width="290" height="24">
        <param name="movie" value="player.swf">
    </object>
</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:
<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.
<video src="video.mp4" width="320" height="240" autoplay controls loop>
    Your browser does not support the video tag.
</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:
<!-- H.264 Constrained baseline profile video (main and extended video compatible)
  level 3 and Low-Complexity AAC audio in MP4 container -->
<source src='video.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<!-- H.264 Extended profile video (baseline-compatible) level 3 and Low-Complexity
  AAC audio in MP4 container -->
<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.
<video controls>
    <source src="video1.mp4" />
    <source src="video1.ogv" />
    <source src="video1.webm" />
    <p>This browser does not support HTML5 video</p>
</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:
<video controls>
    <source src="video1.mp4" />
    <source src="video1.ogv" />
    <source src="video1.webm" />
    <object data="videoplayer.swf">
        <param name="flashvars" value="video1.mp4">
        HTML5 Video and Flash are not supported
    </object>
</video>
You can also use JavaScript to check if a video format is supported by checking the canPlayType property, as follows:
var video = document.getElementsByTagName('video')[0];
if (video.canPlayType)
   { // video tag supported
if (video.canPlayType('video/ogg; codecs="theora, vorbis"'))
      { // it may be able to play}
        else
      {// the codecs or container are not supported
        fallback(video);
  }
}
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:
<video src="video.mp4"
       onerror="fallback(this)">
       video not supported
</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:
<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
var video = document.createElement('video');
video.src = 'video1.mp4';
video.controls = true;
document.body.appendChild(video);
var video = new Video();
video.src = 'video1.mp4';
var video = new Video('video1.mp4')
<script>
    var video = document.getElementsByTagName('video')[0];
</script>
<input type="button" value="Play" onclick="video.play()">
<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.
<audio src="audio.ogg" controls>
 Your browser does not support the audio element.
</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:
<audio controls autoplay>
   <source src="audio1.ogg" type="audio/ogg" />
   <source src="audio1.mp3" type="audio/mpeg" />
    Your browser does not support the audio element.
</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:

10/16/2011

The 'Juneau' Database Project

Jamie Laflen
Barlay Hill

SQL Server Developer Tools, or SSDT (code-named “Juneau”), represents Microsoft’s continued commitment to providing integrated tools for developers targeting Microsoft SQL Server. Those familiar with the previous versions of the Database Project in Visual Studio will find that Juneau is an evolution of those tools for SQL Server, plus many new capabilities and improvements. Juneau provides a unified toolset that combines the projects found in SQL Server Business Intelligence Design Studio (BIDS)—including Reporting, Analysis and Integration Services projects—with the SQL Server Database Project.
While you can install Juneau independently and have everything you need to develop databases for SQL Server, it’s also an integral part of Visual Studio, meaning you can now perform your database development in the same environment as your application development. Juneau is available as part of the SQL Server 2011 release (code-named “Denali”), but will also be available with future versions of Visual Studio.
This article focuses on the Juneau Database Project. This project system and its related features provide the tools to edit, compile, refactor and publish databases to specific versions of SQL Server and SQL Azure. In Juneau, there’s one database project for all versions of SQL Server, and it can include both Transact-SQL (T-SQL) scripts and code that defines SQL CLR objects. Let’s start by taking a look at setting up a database project.

The Database Project

The Database Project is a Visual Studio project enabling offline development of SQL Server databases. A database development team would move to project-based development to enjoy the benefits that this type of development affords the team over developing against a shared live database, including:
  • Isolation of developer changes
  • Rich T-SQL editing support
  • Verification of source prior to deployment and enforcement of team coding standards through code analysis rules
  • Automated migration-script generation
The core project system is very similar to its Visual Studio Database Project (.dbproj) predecessor, in which developers express objects declaratively as CREATE statements. For some additional background regarding offline schema development, see bit.ly/raDMNx.

Setting Up a Project

When you first create a database project, it appears empty, like most other projects created by Visual Studio. This means you can add source code and then build and debug prior to checking it into source code control. Unlike most other projects where you must start from source code, a database project can be created from an existing SQL Server database. There are several ways to populate a project with source code, depending on the level of control you want:
  • Import a complete database
  • Import scripts
  • Import a database package (.dacpac)
  • Write updates for specific objects from a comparison of a project with a database
  • Drag and drop from Server Explorer
  • Convert an existing Visual Studio 2010 Project (Database/SQL CLR) into SQL Server Database Project
The project you create models a database; the database properties (for example, collation) are stored within the project’s properties and user objects are stored as source within the project. The database project is the offline representation of your database in source code form.
To introduce the database project, let’s start with a new empty database project and walk through its various features. There are several ways to create a database project. Because we’ll start with an empty project, just click File | New | Project and then select the SQL Server Database Project, as shown in Figure 1.
Creating a New SQL Server Database Project
Figure 1 Creating a New SQL Server Database Project

Adding Source to Your Project

Most databases have at least one table, so let’s add one now. SQL Server Database Project provides default T-SQL templates for many of the commonly used SQL objects. To create a new object, right-click the project node and select Add | Table, then specify the name of the table in the dialog; we’ll use “Customer.”
Figure 2 shows what a new table looks like in the new table designer.
The New Table Designer
Figure 2 The New Table Designer
Like the HTML designer, the table designer defaults to a split-pane view. The designer window contains a graphical representation of the table as well as the table’s script definition. No matter which view you choose to work in, your changes will be synchronized with the other view.
Often, direct access to a table is restricted and you’ll want to write a stored procedure to give an application programmatic access to the table’s data. With this in mind, we’ll add a stored procedure called “CreateCustomer” the same way we added the Customer table. The editor opens and you’re presented with a default procedure skeleton to populate. This might seem a little daunting because, for many developers, you develop your stored procedures against a live database so you can execute and validate your code as you write it. But don’t worry; the database project creates a new debug database to make project-based development much more productive. Within the editor you can select some text and right-click to get the context menu shown in Figure 3.
Executing Project Source Code Against the Debug Database
Figure 3 Executing Project Source Code Against the Debug Database
How does executing the text using Execute Query, without having configured a connection string, work? When any source code is opened, the editor is configured to execute against the debug database when asked to execute the script or selected text. In addition, the debug database is updated when you start debugging (for example, by hitting F5 or Ctrl+F5) to match the source of your database project. Juneau leverages a new feature in Denali called the SQL Server Express LocalDB to provide an instance and databases automatically to develop and debug against. For more information, see “Introducing SQL Server Express LocalDB” below.

Developing Your Source

Once you’ve looked at LocalDB and have seen how you can develop stored procedures within your source code, you’ll want to know about some other cool features available in the Database Project. A typically unsung hero, IntelliSense inside the project system has been improved based on both SQL Server Management Studio (SSMS) and the Database Project feedback. Many of the changes just smoothed out previous rough edges, but a few are significant:
  • Preview mode: One of the biggest complaints about T-SQL IntelliSense centered on unintended completions when referencing yet-to-be-defined types. For example, you may have wanted to type: 
select t.id from Table1 as t
But pressing a period after you typed:
select t
would have resulted in:
select Table1.
This problem has been fixed by adding “preview mode” to IntelliSense. With preview mode, users will see a set of completions, but they won’t get auto-complete behavior until they “activate” the completions (via either the down-arrow or up-arrow key).
  • IntelliSense with unsaved files: In earlier database projects, you needed to save a file before the objects defined within were available to IntelliSense. For example, previously a newly added table would not appear in IntelliSense until the table’s file was saved. Now, the table will appear in IntelliSense even if the file is not saved.
When planning Juneau, the team felt it was important to elevate the T-SQL development experience to the level enjoyed by developers in other managed languages. As part of this goal, the editor inside the project system has been enhanced to provide common language features like GOTO definition, find all references, and refactoring directly from the editor by right-clicking on an object definition or reference.
As you know, refactoring databases is a lot harder than refactoring application code because databases have data and a seemingly innocuous name change can amount to many additional changes due to dependencies from other objects—or, worse still, data loss can occur when these changes are deployed. Juneau tracks refactor operations performed inside the project by tracking the changes in the MsdnDemo.refactorlog (in our case) so that it can take those operations into account and generate the appropriate sp_rename or ALTER SCHEMA statements.
In other managed languages, the act of building your project is the final step before running the new code. In database development, the analog would be creating all the database objects in your project within a running instance. To bring full database verification to a database project’s build, Juneau leverages another new feature in SQL Server Denali called SQL Server T-SQL Compiler Services. This component provides complete verification of your source code without the need to execute that source against a live SQL Server. To see this in action, add the following code after the CreateCustomer procedure:
go
create table dbo.ExtendedVerificationDemo
(
  c1 int null,
  c2 as c2 + 5
)
When the project is built, you’ll see the following error in the error list and output window:
E:\projects\MsdnDemo\MsdnDemo\CreateCustomer.sql(12,1): Error:  SQL01759: Computed column 'c2' in table 'ExtendedVerificationDemo' is not allowed to be used in another computed-column definition.
As you can see, this error message is exactly what you’d see reported by the SQL Server engine—in this case because a computed column can’t reference itself. As valuable as this feature is, there are situations where you might need to disable it, for example:
  • The verification engine is built based on the SQL Server Denali engine and it enforces rules based on that engine. If your project uses deprecated syntax that has been removed in SQL Server Denali, it will fail verification.
  • The verification engine does not understand objects referenced by a fully qualified three- or four-part name. The engine will flag a warning or error based on the SQL Server deferred name resolution rules, which you can read more about at bit.ly/pDStXE.
If you run into this type of limitation you can turn off extended verification at the file or project level.
After all the build-time warnings and errors have been addressed, verify that your code actually works.

Verifying Your Source

Once you’ve built your project, you need to run (and possibly debug) your code before you check it into source code control. You have several options depending on where you are in the development cycle and what you want to do, as indicated in Figure 4.
Figure 4 Options for Verifying Your Code
If You Are Here …Do the Following ...
You’ve made several changes and want to debug.
  1. Set the database project to be the startup project.
  2. Add a script to the project and write the test case that you want to debug.
  3. Open the project properties, go to the debug tab and select the script as the Startup script.
  4. Hit F5 to push your changes to your debug database (default LocalDB) and start the debugger.
  5. The debugger will break on the first line of the Startup script.
You have an application project (Web application or .exe) that uses stored procedures that you’ve changed (and may want to debug).
  1. Set the application project to be the startup project.
  2. Modify the application’s configuration file (web.config or app.config) to point to the debug database (by default Data Source=(localdb)\<SolutionName>; Initial Catalog=<Project Name>).
  3. Hit F5 to run the application and update the debug database.
  4. Interact with the application to test.
  5. Put a breakpoint in the stored procedure you want to debug.
You want to debug your database using an application that accesses your debug database.
  1. Set the database project to be the startup project.
  2. Modify the application’s configuration file to point to the debug database.
  3. In the database project’s properties Debug tab, specify to run the application as an external program.
  4. Hit F5.
  5. Put a breakpoint in the stored procedure you want to debug.
  6. Interact with the application that was started when you hit F5.
You’ve made several changes and you want to test (and possibly debug) the changes.
  1. Add a script (not in build) to the project and write the tests you want to perform.
  2. Hit Ctrl-F5 to push your changes to your debug database (default LocalDB).
  3. Highlight each test and right-click execute (or execute with debug) to verify that the results are what you expect.

Migrating Changes

When your code reaches a stable point, it’s time to migrate it to an instance to be tested and eventually used by your customers. Juneau has an incremental update engine that will generate an update script based on the difference between your source and the target database. Although there’s one underlying engine, it’s exposed in three different ways within Juneau to support migration of your changes, as Figure 5 describes.
Figure 5 Options for Migrating Your Code
Migration ScenarioDescription
Promote changes to debug database
  • Quick update of your debug database with changes from your project
  • Uses settings from the Database Project Debug tab
  • Executed when user hits F5/Ctrl+F5
  • Exposed as an MSBuild target
Publish changes to a separate database
  • Formal update of a database from a project
  • Meant to migrate or update an environment
  • Executed by clicking on the project’s Publish menu
  • Exposed as an MSBuild target and through the command-line tool (sqlx.exe)
  • Exposed as a Web Deploy provider (bit.ly/qBX0LK)
Compare schema and move changes between databases
  • Visual differencing and update tool
  • Allows individual selection of objects to be updated
  • Takes project’s refactor log into account when displaying differences
  • Executed by selecting context menus on a project or database in the new SQL Server node of Server Explorer
To support these three different scenarios, the incremental update engine exposes a number of different options to control behavior. You can expect the defaults for these settings to change over time as the team tunes each scenario. For example, in the design-time case it might make sense for the engine to be more aggressive about ensuring the change is made, and to care less about data loss because it’s a debug database. Although there are many options, I’d like to call out a few behaviors and their corresponding options, as shown in Figure 6.
Figure 6 Options for Controlling Updating Behavior
BehaviorOptionResult
Data lossBlock incremental deployment if data loss might occurThe incremental update engine will halt execution if a table has data and the script later makes a destructive change. A destructive change would include dropping a column or making a type change (bigint to int).
Back up database before deploymentThe engine will script a backup of the database prior to performing any changes.
Generating dropsAlways recreate databaseThe update script will be written to detect if the database exists and, if it does, to set it into single-user mode and drop it.
Drop objects in target but not in sourceThis option is a “hammer” that drops all objects in the target database that are not also in the source. This option overrides any data-loss options.
Drop constraints, indexes, dml triggersTreats constraints, indexes and dml triggers as if they’re part of the table or view; thus, removal of these objects from the project causes a drop of the corresponding object in the target.
Drop permissions, extended propertiesSimilar to the previous option, treats these objects as if they’re part of their parent; thus, absence in the source causes target-only objects to be dropped.
Verifying new constraintsCheck new constraintsWhen new foreign key and check constraints are created, they can “check” that existing data conforms to the constraint. The data check for new constraints is deferred to the end of the deployment script so that a constraint violation doesn’t cause an error in the middle of the deployment.
TransactionsInclude transactional scriptsWhen this option is enabled, the engine attempts to wrap the generated script within a transaction. Because some objects can’t be managed within a transaction, it’s possible that a portion of the script will not be within a transaction.
Being able to create an incremental update script is very helpful when migrating changes from a source to a target database. However, as precise as the incremental update script is, sometimes it’s challenging to determine exactly what’s occurring in the script or to summarize what the script is doing. As an aid to summarizing and understanding what the incremental script will perform, Juneau creates a preview report that highlights potential issues with the actions taken by the script, as well as summarizes the actions taken if the script is executed. For example, you can publish your project to the default LocalDB instance like this:
  1. Open the background activity window by clicking on View | Other Windows | Database Activity Monitor.
  2. Right-click on the project and select Publish.
  3. Populate the Publish dialog, as shown in Figure 7.
  4. Click Publish.
Publish Database Dialog
Figure 7 Publish Database Dialog
When publishing has completed, open the publish step and click on the View Plan link. A report like the one in Figure 8 will be displayed.
The Deployment Preview Report
Figure 8 The Deployment Preview Report
As you can see, the report indicates that the two tables (we fixed the bug in the ExtendedVerificationDemo table) and procedure we wrote earlier will be created when the script is executed. The highlights section is empty, but you can see that the report will highlight actions that could cause a significant performance impact or data loss. If we had only generated a script rather than publishing, we could use this report to help verify the script prior to execution.

Connected Development

So far, we’ve talked about ways to use the Database Project to develop our code declaratively outside the context of a running database. All this technology is extremely useful when working in team environments, but sometimes you just want to interact with a live server! Microsoft knows that live servers are important to developers, and it has invested in a rich, developer-oriented, connected experience. To demonstrate, let’s open the database to which we just published. To connect to that database:
  1. Click on the View menu.
  2. Select Server Explorer.
  3. Right-click on the SQL Server node.
  4. Select Add SQL Server.
  5. Populate the connection dialog with (localdb)\v11.0.
  6. Navigate to the just-published MsdnDemo database, as shown in Figure 9.
MsdnDemo Database in the New SQL Server Node in Server Explorer
Figure 9 MsdnDemo Database in the New SQL Server Node in Server Explorer
The first thing you might notice is that the tree looks very similar to the tree in SSMS. It should; the team wanted to limit the amount of relearning necessary when moving to Juneau. You can open a T-SQL Query editor right from the tree and begin writing code as you normally would; this editor is the same enhanced editor we talked about earlier. Unlike some of the SSMS capabilities, the Juneau tree is expressly meant for developer-oriented actions. For instance, if you right-click the table Customer and select Delete, you’ll see a dialog that presents the same preview report you saw earlier. However, in this case there’s a warning that the procedure dbo.CreateCustomer will be broken if the drop is executed, as shown in Figure 10.
Figure 10 Update Database Preview Dialog
** Warnings
     The object [dbo].[CreateCustomer] will be broken if the
       change is executed.
 
** Highlights
     Tables that will be rebuilt
       None
     Clustered indexes that will be dropped
       None
     Clustered indexes that will be created
       None
     Possible data issues
       None
 
** User actions
     Drop
       [dbo].[Customer] (Table)
 
** Supporting actions
A similar report is created if the table is renamed. In both these cases, before actions are executed, you’re informed of the impact of the change; this report allows you to see what your changes will do to the database and what might need to be fixed (or deleted) should you apply the changes.
If you cancel the delete and then right-click on the Customer table and select View Designer, you’ll see the same table designer you became familiar with in the project system—except this time it’s hosted over the definition of the table retrieved from the server. As you might expect, the designer has a CREATE table statement using the same declarative programming model as the project system. In the designer, rename the Id column to CustomerId and add a second int column called Age. Now if you look in the error list, you’ll see a warning that CreateCustomer has been broken by the column rename, as shown in Figure 11.
Error Resulting from Column Rename
Figure 11 Error Resulting from Column Rename
To fix this error you can either View Code on the CreateCustomer procedure or just double-click the warning and modify the insert statement to update the column names and supply @param2 as the value for the Age column. At this point, you have two windows (one source, one designer) with declarative object definitions  retrieved from the database defining a set of changes to the objects on the server. If you click on the Update Database button, you’ll see the now-familiar report that will tell you that the column will be renamed and both the table and procedure will be altered. Execute the script by clicking on Update Database and then navigate to the Customer table in Server Explorer. You’ll see the tree update to include the CustomerId and Age columns.
The connected development experience in Server Explorer provides a great deal of power to you by supporting the same declarative programming model and enhancing online changes with real-time warning and error support as you make changes.

Getting the Bits

Juneau is available in the SQL Server Denali CTP3 release. It will also be available as a standalone Web download, and will integrate into existing installations of Visual Studio 2010 and the next version of Visual Studio. Moreover, Juneau has a separate command-line tools installer for publishing databases without requiring Visual Studio to be installed, and for Team Foundation Server automated-build scenarios.

Introducing SQL Server Express LocalDB

SQL Server Express LocalDB (or LocalDB for short) is basically the next generation of SQL Express User Instances, but without the need to explicitly manage a SQL Express instance on your desktop. LocalDB doesn’t have a background service hosting a named instance; rather, it provides a way for developers to define custom named instances and then interact with them. When a LocalDB instance is started, it runs as a process under the credentials 
of the user who started it. For example, if you start a LocalDB instance, in Task Manager you’ll see a sqlservr.exe process running under your own credentials. This by itself is cool because it means no setup to debug your T-SQL code! Once the instance is started, it’s just like a SQL Express instance. When the instance isn’t used for a period of time, it will shut down so that an idle SQL Server instance doesn’t consume resources on your machine.
A LocalDB installation comes with a command-line tool that can be used to manage the LocalDB instances you’ve created. For example, you can create a new LocalDB instance called LocalDBDemo by executing the following:
C:\Program Files\Microsoft SQL Server\110\Tools\Binn>SqlLocalDB.exe create LocalDBDemo
Local Database instance "LocalDBDemo" created with version 11.0.
Once the instance has been created, you can start it using the command-line tool or you can just attempt to connect to the instance through Juneau, SQL Server Management Studio (SSMS) or your application. Because LocalDB instances aren’t resident instances, they can’t be accessed using the (local) prefix used to address instances on the local machine. Instead, use (localdb); in this example you’d type (localdb)\LocalDBDemo into Juneau to connect to and manage the instance.
When you create a new instance, a new directory is created within your user profile and the four built-in databases (master, tempdb, msdb and model) are placed within this directory. By default, any new databases will go in the instance’s directory as the default data path. In our example, the directory is:
C:\Users\user1\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\LocalDBDemo
If you don’t want to create a custom instance, you can use the LocalDB built-in default instance named v11.0. To access the instance just register a connection to “(localdb)\v11.0” in Juneau, and the instance will be automatically created for you by LocalDB.
Because LocalDB is new, a patch to the Microsoft .NET Framework 4 is required to use the (LocalDB) prefix when accessing an instance through SSMS or managed application code. Installing Juneau will include this patch. Support for the prefix will be built into the next version of the .NET Framework.
Database developers face a problem similar to what Web developers faced (and which IISExpress solved for them): how to develop and debug code that requires a server to execute without needing to run a full server product locally on the development machine. LocalDB provides a solution for database developers. Because LocalDB is a crucial part of database development, it’s installed on your desktop when you install Juneau. When a database project is added to a solution, Juneau creates a new LocalDB instance named after the solution and creates a database within that instance for each database project. Juneau creates the data and log file for each database project in a directory within the project’s directory. For more information about LocalDB, see go.microsoft.com/fwlink/?LinkId=221201.

Build Great Experiences on Any Device with OData

Shayne Burgess

In this article, I’ll show you what I believe is a serious data challenge facing many organizations today, and then I’ll show you how the Open Data Protocol (OData) and its ecosystem can help to alleviate that challenge. I’ll then go further and show how OData can be used to build a great experience on Windows Phone 7 using the new OData library for Windows Phone 7.1 beta (code-named “Mango”).

The Data Reach Challenge

An interesting thing happened at the end of 2010: for the first time in history, the number of smartphone shipments surpassed the number of PC shipments. A key thing to note is that this isn’t a one-horse race. There are many players (Apple Inc., Google Inc., Microsoft, Research In Motion Ltd. and so on) and platforms (desktop, Web, phones, tablets and more coming all the time). Many organizations want to target client experiences on all or most of these devices. And many organizations also have a variety of data and services that they want to make available to client devices. These may be on-premises, available through traditional Web services or built in the cloud.
The combination of a large and ever-expanding variety of client platforms with a large and ever-expanding variety of services creates a significant cost and complexity problem. When support for a new client platform is added, the data and services often have to be updated and modified to support that platform. And when a new service is added, all of the existing client platforms need to be modified to support that service. This is what I consider to be the data reach problem. How can we define a service that’s flexible enough to suit the needs of all the existing client experiences—and new client experiences that haven’t been invented yet? How can we define client libraries and applications that can work with a variety of services and data sources? These are some of the key questions that I hope to show can be partly addressed with OData.

The Open Data Protocol

OData is a Web protocol for querying and updating data that provides a uniform way to unlock your data. Simply put, OData provides a standard format for transferring data and a uniform interface for accessing that data. It’s based on ATOM and JSON feeds and the interface uses standard HTTP (REST) interfaces for exposing querying and updating capabilities. OData is a key component in bridging the data reach problem because, being a uniform, flexible interface, the API can be created once and used from a variety of client experiences.

The OData Ecosystem

The flexible OData interface that can be used from a variety of clients is most powerful when there are a variety of client experiences that can be built using existing OData-enabled clients. The OData client ecosystem has evolved over the last few years to the point where there are client libraries for the majority of client devices and platforms, with more coming all the time. Figure 1 lists just a sampling of the client and server platforms available at the time this article was written (a much more complete list of existing OData services is at odata.org/producers).
Figure 1 A Sampling of the OData Ecosystem
Clients
.NET
Silverlight
Windows Phone
WebOS
iPhone
DataJS
Excel
Tableau
Services
Windows Azure
SQL Azure
DataMarket
SharePoint
SAP
Netflix
eBay
Facebook
Wine.com
I can generally target any of the listed services in Figure 1 with any client. To help demonstrate this in practice, I’ll give examples of OData flexibility using a couple of different clients.
I’ll use the Northwind OData (read-only) sample service available on odata.org at http://services.odata.org/Northwind/Northwind.svc/. If you’re familiar with the Northwind database, the Northwind service shown in Figure 2 simply exposes the Northwind model as an OData service directly. Figure 2 shows the service document in the Northwind service from the browser; the service document exposes the entity sets in the service that are basically just the tables from the Northwind database.
The Northwind Service
Figure 2 The Northwind Service
Let’s look at a couple of examples of using the client libraries to consume and build experiences using the Northwind OData service. For the first example, let’s consider a client experience that doesn’t require any code to build. The PowerPivot add-in for Excel provides an in-memory analysis engine that can be used directly from within the Excel interface and supports importing data directly from an OData feed. The PowerPivot add-in also includes support for importing data directly from the Windows Azure Marketplace DataMarket, as well as a number of other data sources.
Figure 3 shows a pivot chart created by importing the Products and Orders data from the Northwind OData service and joining the result. The price-per-unit and quantity fields of the order details are combined to produce a total value for each order, and then the average total value for each order is shown, grouped by product and then displayed on a simple pivot chart for analysis. All of this is done using the built-in interface and tools in PowerPivot and Excel.
PowerPivot Add-In
Figure 3 PowerPivot Add-In
Let’s look next at another example of how to build an OData client experience on a different platform: iOS. The OData client library for iOS lets you build apps on that platform (such as for the iPad and iPhone) that consume existing OData services. The iOS library for OData includes a code-generation tool, odatagen, which will generate a set of proxy classes from the metadata on the service. The proxy classes provide facilities for generating OData URIs, deserializing a response into client-side objects and issuing create, read, update and delete (CRUD) operations against the service. The following code snippet shows an example of executing a request for the set of customers from the OData service:
// Create the client side proxy and specify the service URL.
 NorthwindCatalog *proxy =
  [[NorthwindCatalog alloc]initWithUri:@http://host/Northwind.svc];
 
// Create a query.
DataServiceQuery *query = [proxy Customers];
 
QueryOperationResponse *response = [query execute];
customers = [query getResults];
The DataServiceQuery and QueryOperationResponse are used to execute a query by generating a URI and executing it against the service.

The Windows Phone 7 Library

Next, I’ll demonstrate another example of an OData library on a third platform. I did a quick overview of building on OData on other platforms, but for this one I’ll do a detailed walk-through to give insight into what it takes to build an app. To do this, I’ll show you the basic steps needed to write a data-driven experience on Windows Phone 7 using the new Windows Phone 7.1 (Mango) tools. For the rest of the article, I’ll walk through the key considerations when building a Windows Phone 7 app and show how the OData library is used. The app I build will target the same Northwind sample I used in the previous two examples (the Excel PowerPivot add-in and the iOS library).
The latest release of the Windows Phone 7.1 (Mango) beta tools features a significant upgrade in the SDK support for OData. The new library supports a set of new features that makes creating OData-enabled Windows Phone 7 apps easier. The Visual Studio Tools for Windows Phone 7 were updated to support the generation of a custom client proxy based on a target OData service. For those familiar with the existing Microsoft .NET Framework and Silverlight OData clients, this, too, will be familiar. To use the Visual Studio tools to automatically generate the proxy in a Windows Phone 7 project, right-click the Service References node in the project tree and select Add Service Reference (note that this is only available if the new Mango tools are installed). Once the Add Service Reference dialog appears, enter the URI of the OData service you’re targeting and select Go. The dialog will display the entity sets exposed by the service; you can then enter a namespace for the service and select OK. The first time the code generation is performed using Add Service Reference, it will use default options, but it’s possible to further configure the code generation by clicking the Show All Files option in the solution explorer, opening the .datasvcmap file in the service reference and configuring the parameters. Figure 4 shows the completed Add Service Reference dialog with the list of entity sets available.
Using the Add Service Reference Dialog
Figure 4 Using the Add Service Reference Dialog
A command-line tool is also included in the Visual Studio Tools for Windows Phone 7 that’s able to perform the same code-generation step. In either case, the code generation will create a client proxy class (DataServiceContext) for interacting with the service, and a set of proxy classes that reflect the shape of the service.

LINQ Support

The client LINQ support in the latest version of the Windows Phone 7 tools—similar to the LINQ support currently available in the .NET client—allows you to write complex LINQ queries and have those LINQ queries translated into a request to the OData service via a URI. The library also supports executing pre-built URIs to an OData service directly, but the LINQ syntax provides a much cleaner experience and hides the complexity of building valid OData URIs. Figure 5 shows an example of using the LINQ support to create a LINQ expression that will query for all products in the Northwind database that have units in stock.
Figure 5 Executing a LINQ Query
public void LoadData()
{
  // Create a Northind Entities context and set the URL of the service.
  NorthwindEntities svcContext = new NorthwindEntities(
    new Uri("http://services.odata.org/Northwind/Northwind.svc")
  );
            
  // Create a DataServiceCollection to hold the results of the query.
  // This collection implements INotifyCollectionChanged and can be bound in XAML.
  DataServiceCollection<Product> ProductsCollection =
    new DataServiceCollection<Product>( svcContext );
           
  // Execute a LINQ query for all products with some units in stock and
  // include the supplier.
  var q = from p in svcContext.Products.Expand("Supplier")
    where p.UnitsInStock > 0
    select p;
 
  // Asynchronously execute the query and load the results.
  ProductsCollection.LoadAsync(q);
}
If you use the Add Service Reference tool described previously, a client proxy context will be generated for you that supports building LINQ queries.
The OData library includes an OData-specific Collection type, DataServiceCollection<T>, which implements INotifyCollectionChanged. If a DataServiceCollection is used to store entities on the client, the entities can be bound to UI elements in XAML and will automatically be change-tracked. Any updates to those tracked entities can be pushed to the service via a call to SaveChanges on the client context. Figure 6 shows some basic XAML binding using the DataServiceCollection class—the proxy classes generated using the tools implement INotifyPropertyChanged and will reflect the changes made in the UI.
Figure 6 XAML Binding
<ListBox x:Name="ProductListBox" Margin="0,0,-12,0"
  ItemsSource="{Binding Products}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Margin="0,0,0,17" Width="432" Height="78">
        <TextBlock Text="{Binding ProductName}" TextWrapping="NoWrap"
          Style="{StaticResource PhoneTextExtraLargeStyle}"/>
        <TextBlock Text="{Binding Supplier.CompanyName}"
          TextWrapping="Wrap" Margin="12,-6,12,0"
          Style="{StaticResource PhoneTextSubtleStyle}"/>
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
It’s possible to turn off the use of the DataServiceCollection in the code generation if you’re planning to manage the change tracking manually. This may slightly increase the performance of your app because the notification events won’t be raised if this feature isn’t used.
The process of executing a query against an OData service and materializing the results involves a call to the network stack on Windows Phone 7, which must always be an asynchronous call. Methods on the DataServiceContext, BeginExecute and EndExecute, asynchronously execute a request to the service using the IAsyncResult pattern. The IAsyncResult pattern can sometimes be cumbersome to use, so a method on the DataServiceCollection called LoadAsync hides most of the details of the asynchronous execution. The LoadAsync method will asynchronously add the result of the query to the DataServiceCollection and raise INotifyCollectionChanged events for the UI to repopulate itself. The collection also has a LoadCompleted event that can be subscribed to, which would be called when the data is done asynchronously loading.

Tombstoning

A Windows Phone 7 app will sometimes get a notification from the OS that it needs to deactivate so that the OS can activate another app. This can happen, for example, if the user selects the Home button on the phone or if the user gets an incoming call. The app won’t always be deactivated in the Mango beta release of Windows Phone 7 because the fast application-switching feature will often allow the OS to switch to another application without having to deactivate the current one first. When the app is told by the OS to deactivate, the app has the option to store its current state locally so that if it’s activated again—which can happen if the user subsequently selects the Back button, for example—the app can restore its previous state and the user can resume what he was doing before the app was deactivated. This is called tombstoning. This can be particularly useful in an app that consumes data from an external data source, because tombstoning saves the app from having to go to the network and use bandwidth to download the data from the external data source again.
Tombstoning in Windows Phone 7 is accomplished by serializing the state of the app into a set of strings in a dictionary. The OData client library for Windows Phone 7 has utilities to aid in serializing the current state by providing methods that can serialize or deserialize a DataServiceContext and a set of DataServiceCollections. The sample code in Figure 7 shows an example of using these methods to build a string that represents the current state. Windows Phone 7 applications must implement the Application_Activated and Application_Deactivated methods that are used by the OS to indicate when the app should activate or deactivate. The serialize and deserialize methods on the DataServiceContext can be used from these methods.
Figure 7 Serialization/Deserialization of DataServiceContext
// This method will serialize the local state to be stored
// when the app is deactivated.
public string Serialize()
{
  var saveItems = new Dictionary<string, object>();
  saveItems.Add("Products", ProductsCollection);
  return DataServiceState.Serialize(svcContext, saveItems);
}
 
// This method will deserialize the local state to be restored
// when the app is reactivated.
public void Deserialize (string state)
{
  DataServiceState dsState= DataServiceState.Deserialize(state);
  svcContext = dsState.Context as NorthwindEntities;
  if (dsState.RootCollections.ContainsKey("Products"))
  {
    ProductsCollection = dsState.RootCollections["Products"] as
     DataServiceCollection<Product>;
  }
}

Credentials

I’ll cover one final but important part of building an OData app on Windows Phone 7.1 (Mango): providing credentials to the OData service. In many cases, the service in question is behind an authorization scheme to protect the data from unauthorized use. Support has been added in the Mango tools to set the Credentials property on the HTTP stack when making calls to the OData service using the client library. The property takes an implementation of the ICredentials interface and passes that interface directly to the HTTP stack. The following code snippet shows the basics of creating the DataServiceContext and setting the Credentials property using a username, password and domain name:

// This method will serialize the local state to be stored
// when the app is deactivated.
public MainViewModel()
{
  // Create the data service context.
  NorthwindEntities serviceContext = new NorthwindEntities(
    new Uri("http://services.odata.org/Northwind/Northwind.svc"));
 
  // Specify the basic auth credentials.
  serviceContext.Credentials = new NetworkCredential(Username, Password, Domain);
}

Learning More

This article gives a summary of OData, the ecosystem that has been built around it and a walk-through using the OData client for Windows Phone 7.1 (Mango) beta to build great mobile app experiences. For more information on OData, visit odata.org. To get more information on WCF Data Services, see bit.ly/pX86x6 or the WCF Data Services blog at blogs.msdn.com/astoriateam.