April 2012 - Posts
Advanced HTML5 and JavaScript APIs Slide Deck and Demos
Today I delivered a MSDN session at Microsoft Ra’anana about “Advanced HTML5 and JavaScript API’s”.
First of all, I want to thank all the session attendees!
In the session, I talked about the following HTML5 JavaScript APIs:
- Web Storage API
- AppCache API
- IndexedDB API
- File and FileSystem API
- CORS
- EventSource API
- Web Sockets API
I also introduced story.js, the JavaScript library that I’m writing which handle storage APIs. You can read about story.js here. I published the session slide deck and demos in my SkyDrive.
Enjoy!
JavaScript Minify Tools and the objectStore delete Function
One of the good practices when deploying web sites or applications is to minify your JavaScript/Css files. Minifying the files can help to improve a little the performance of your site or application since it will minimize the impact on the network.
In most of my web projects, I add a MSBuild task to minify the JavaScript/Css files using one of the following tools: Microsoft Ajax Minifier or YUICompressor for .Net. Both of them are good enough for my needs and very easy to set in Visual Studio environment.
Lately, I needed to minify JavaScript code that includes the use of IndexedDB. I have added the minifying tool as always and minification failed. The reason for that is the use of objectStore delete function. delete is a reserved word in JavaScript and it is main purpose is to remove properties from JavaScript objects. In most of the IDEs you will see that the IDE will mark it as a reserved word and sometimes nag you with warnings such as “Expected identifier” when you use IndexedDB. Trying to minify JavaScript code with a call to the delete function such as:
var request = store.delete(key);
will fail in most of the minifying tools. In order to succeed in the minification process, I needed to “uglify” my code and to turn the previous JavaScript statement to the following valid JavaScript statement:
var request = store["delete"](key);
You can use this form of code since in JavaScript you can call an object property/function in both of the ways – using the dot notation or using square brackets.
This is the case were using a reserved word can bite you. I would have expected one of two things:
- W3C would be aware of that and maybe call the objectStore’s function remove in the specifications. This won’t break very necessary tools.
- The tool writers will be aware of this problem and fix it in the minification process.
I hope you won’t be forced to use the “uglify” alternative in the future but who knows.
Generating ASP.NET MVC View Controls According to Xml Configurations
Last week I was consulting about ASP.NET MVC at a customer. One of the customer project requirements is to generate forms according to Xml configuration files. In this post I’ll offer an end-to-end solution to this requirement. This solution can be rafactored to use databases or any other data sources in order to achieve the same results.
Setting The Environment
Create a new default internet ASP.NET MVC 3 web application:

Pay attention to the folders I added such as Classes and ViewModels. The Classes folder will be used to store classes that I use in the application. The ViewModels folder will be used to store the view models that I’ll use in the solution.
The Xml File
Here is an example for the Xml file I’m going to use in the solution:
<?xml version="1.0" encoding="utf-8" ?>
<views>
<view id="home">
<controls>
<control>
<type name="Label">
<property name="ID" value="lbl1"/>
<property name="Value" value="lbl1"/>
</type>
</control>
<control>
<type name="TextBox">
<property name="ID" value="txt1"/>
<property name="Value" value="txt1"/>
</type>
</control>
</controls>
</view>
</views>
The Xml will be located in the App_Data directory. In the Xml, a view node represents a single view that holds some controls to render. Every control has a type (for example Label) and each type has properties that define the type. As you can understand this data structure can also be implemented inside a database or other storage types. Since the customer needed Xml representation I use an Xml file.
First Step – Creating the ViewModels for the Controls
The first thing to do is to create a base class to represent a control inside a view.
public abstract class ControlViewModel
{
public abstract string Type { get; }
public string Label { get; set; }
public string ID { get; set; }
public string Name { get; set; }
}
The ControlViewModel include the control type, the control id, the control name and a label string associated with the control. If you need other properties which are repeated in all your controls you can add them.
After we have the base class lets implement some concrete classes such as TextBox and Label:
public class TextBoxViewModel : ControlViewModel
{
public override string Type
{
get
{
return "TextBox";
}
}
public string Value { get; set; }
}
public class LabelViewModel : ControlViewModel
{
public override string Type
{
get
{
return "Label";
}
}
public string Value { get; set; }
}
In the concrete classes, I implemented the control type and added more properties that are used in that control.
Now that we have the concrete classes we can add a ViewModel that will hold all the list of controls for a view:
public class DefaultControlsViewModel
{
public List<ControlViewModel> Controls { get; set; }
public DefaultControlsViewModel()
{
Controls = new List<ControlViewModel>();
}
}
The DefaultControlsViewModel includes a list of all the controls to render. If you like to add more model properties to the ViewModel you can inherit from this class and add them.
Second Step – Creating the ControlsContext to Read the Xml File
After we have the ViewModels, we will create a class to read the Xml file (or read from your data source if you have chosen another data source). I have created a ControlsContext class to read the Xml file and to store a DefaultControlsViewModel for each view in the Xml. Here is the ControlsContext implementation:
public class ControlsContext
{
private static Dictionary<string, DefaultControlsViewModel> _dynamicViewModel;
public Dictionary<string, DefaultControlsViewModel> DynamicViewModel
{
get
{
return _dynamicViewModel;
}
}
static ControlsContext()
{
Init();
}
private static void Init()
{
_dynamicViewModel = new Dictionary<string, DefaultControlsViewModel>();
XDocument doc = GetXmlDocument();
CreateDynamicViewModel(doc);
}
private static void CreateDynamicViewModel(XDocument doc)
{
var viewNodes = from node in doc.Document.Descendants()
where node.Name == "view"
select node;
foreach (var element in viewNodes)
{
AddControlType(element);
}
}
private static void AddControlType(XElement element)
{
var controlTypes = from node in element.Descendants()
where node.Name == "type"
select node;
DefaultControlsViewModel viewModel = new DefaultControlsViewModel();
foreach (var type in controlTypes)
{
var id = (from idNode in type.Descendants("property")
where idNode.Attribute("name").Value == "ID"
select idNode.Attribute("value").Value).FirstOrDefault();
var value = (from valueNode in type.Descendants("property")
where valueNode.Attribute("name").Value == "Value"
select valueNode.Attribute("value").Value).FirstOrDefault();
var obj = Activator.CreateInstance("DynamicControlsCreation", "DynamicControlsCreation.ViewModels." + type.FirstAttribute.Value + "ViewModel").Unwrap();
var control = (ControlViewModel)obj;
control.ID = id;
control.Name = id;
control.GetType().GetProperty("Value").SetValue(control, value, null);
viewModel.Controls.Add(control);
}
_dynamicViewModel.Add(element.FirstAttribute.Value, viewModel);
}
private static XDocument GetXmlDocument()
{
string path = HttpContext.Current.Server.MapPath("~/App_Data/Controls.xml");
XDocument doc = XDocument.Load(path);
return doc;
}
}
Some things to notice:
- You can create this class as singleton since we will want only one instance for it.
- I use the HttpContext.Current.Server.MapPath("~/App_Data/Controls.xml") statement to get the path for the App_Data folder.
- I use LINQ to Xml to read the Xml file content.
- In order to create and fill the control view models I use the Activator.CreateInstance("DynamicControlsCreation", "DynamicControlsCreation.ViewModels." + type.FirstAttribute.Value + "ViewModel")
statement.
Third Step – Implement the HomeController Functionality
Now that we have the ControlsContext and the control ViewModel classes we can implement the controller functionality.
public class HomeController : Controller
{
public ActionResult Index()
{
ControlsContext context = new ControlsContext();
var model = context.DynamicViewModel["home"];
return View(model);
}
[HttpPost]
public ActionResult Index(DefaultControlsViewModel model)
{
return RedirectToAction("Submitted");
}
public ActionResult Submitted()
{
return View();
}
public ActionResult About()
{
return View();
}
}
As you can see, I use the default generated ASP.NET MVC HomeController and implement the Index method and an Index method to handle HTTP posts. The reason for the second method will be explained in the last step.
Forth Step – Creating the Views and the Template Views for Each Control
We set all the environment but now we want to create our dynamic generated views. Here is the Index view:
@{
ViewBag.Title = "Home Page";
}
@model DynamicControlsCreation.ViewModels.DefaultControlsViewModel
<p>
@using (Html.BeginForm())
{
for (int i = 0; i < Model.Controls.Count; i++)
{
<div>
@Html.HiddenFor(x => x.Controls[i].Type)
@Html.HiddenFor(x => x.Controls[i].Name)
@Html.EditorFor(x => x.Controls[i])
</div>
}
<input type="submit" value="Submit" />
}
</p>
As you can see, I iterate on all the controls in the DefaultControlsViewModel and write the relevant controls in the view. I use the HTML.EditorFor method to render the relevant view for the relevant control.
In the Views –> Shared folder, I added an EditorTemplates folder and put the relevant view templates for the controls view model (which will be used we you call the HTML.EditorFor method):
@model DynamicControlsCreation.ViewModels.LabelViewModel
<div>
@Html.LabelFor(x => x.Value, Model.Label)
@Html.LabelFor(x => x.Value)
</div>
and
@model DynamicControlsCreation.ViewModels.TextBoxViewModel
<div>
@Html.LabelFor(x => x.Value, Model.Label)
@Html.TextBoxFor(x => x.Value)
</div>
The last view that I added is the Submitted view:
@{
ViewBag.Title = "Submitted";
}
<h2>Submitted</h2>
The Views folder will look like:

Last Step – Create the ControlsModelBinder
If you’ll try to run the application everything will work except for the post to the Index method which is created when you click the submit button. The reason it won’t work is that ASP.NET MVC doesn’t know how to create the instances for the concrete control classes. This error can be solved by using a a model binder. If you aren’t familiar with ASP.NET MVC model binders you can read the following post. Here is the model binder to instantiate the relevant ControlViewModel class:
public class ControlsModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var type = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Type");
object model = Activator.CreateInstance("DynamicControlsCreation", "DynamicControlsCreation.ViewModels." + type.AttemptedValue + "ViewModel").Unwrap();
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
return model;
}
}
You will have to register that binder in the Global.asax file in the Application_Start event:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(ControlViewModel), new ControlsModelBinder());
}
This is it.
Now you can run the application and see it working including the submit button in the homepage.
You can download the full code example from here.
Summary
In the post, I’ve created an end-to-end solution to handle dynamic controls creation in a view according to an Xml configuration file.
The story Begins
Lately, I’ve decided to write my own JavaScript library for educational and experimental purposes. The idea came to me while I was creating a demo to a session that I will deliver in the near future. In the session, I wanted to show how to use different JavaScript storage types and didn’t wanted to change my code every time for every storage type.
So I’ve created a library to handle client-side data storages in simple and consistent way. The library is called story.js and its first bits are hosted in GitHub. Right now the library includes the following storage types:
- Web Storage
- IndexedDB
- Cookies
- In-memory
In the future expect more features. I’ve also convince my managers at Sela Group to help in this initiative and other Sela experts (Noam and Sebastian) agreed to contribute to the library. You can join us too – just let me know through the Blog’s contact form.
Here are simple code snippets that show how to use story.js with Web Storage:
/// <reference path="story.js" />
var storage = story.storage(story.StorageTypes.WEB_STORAGE);
storage.add("key", "value").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.get("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.update("key", "value1").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.remove("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.clear().then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
with in-memory:
/// <reference path="story.js" />
var storage = story.storage(story.StorageTypes.IN_MEMORY);
storage.add("key", "value").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.get("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.update("key", "value1").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.remove("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.clear().then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
with cookies:
/// <reference path="story.js" />
var storage = story.storage(story.StorageTypes.COOKIE);
storage.add("key", "value").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.get("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.update("key", "value1").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.remove("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.clear().then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
and with IndexedDB:
/// <reference path="story.js" />
var factory = story.storage(story.StorageTypes.INDEXEDDB);
factory.createStore({
name: "people",
keyPath: undefined,
autoInc: false,
names: ["name", "email"],
values: ["name", "email"],
unique: [false, true]
}).then(function (storage) {
console.log(storage);
storage.add("key", "value").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.get("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.update("key", "value1").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.remove("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.contains("key").then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
storage.clear().then(function (data) {
console.log(data);
}, function (error) {
console.log(error);
});
}, function (error) {
console.log(error);
});
Pay attention that this is an experimental library and there might be bugs.
Expect more story versions in the future.
I’ll appreciate any feedback about this initiative.
Getting All Stored Items in an IndexedDB objectStore
One of the things that I found very common to do when you use IndexedDB is retrieving all the stored items in an objectStore. This post will show you how to implement such a function.
Getting All Stored Items in an IndexedDB objectStore
When dealing with databases there are a lot of times that you find yourself retrieving all the stored items in a database table. When using IndexedDB, which is an index database, the retrieve all items operation is also vital.
Here is an example of how to retrieve all the stored items in an objectStore:
function getAllItems(callback) {
var trans = db.transaction(storeName, IDBTransaction.READ_ONLY);
var store = trans.objectStore(storeName);
var items = [];
trans.oncomplete = function(evt) {
callback(items);
};
var cursorRequest = store.openCursor();
cursorRequest.onerror = function(error) {
console.log(error);
};
cursorRequest.onsuccess = function(evt) {
var cursor = evt.target.result;
if (cursor) {
items.push(cursor.value);
cursor.continue();
}
};
}
At first, you will create the transaction and store objects. Pay attention that the storeName is a variable that holds a string with the objectStore name and the db variable is the opened IndexedDB database. Later on, a JavaScript array with the name items is created. This array will hold all the items in the objectStore and will be used by the callback function that is passed to the getAllItems function. After the array’s creation, the transaction’s oncomplete event handler is wired and its job is to call the callback function with the array of items. In order to retrieve all the items, a cursor is opened against the objectStore and in its success handler all the items are inserted into the items array.
In order to use the getAllItems function just call it with the relevant callback function. Here is an example for calling the function:
getAllItems(function (items) {
var len = items.length;
for (var i = 0; i < len; i += 1) {
console.log(items[i]);
}
});
In the example, after the items retrieval you iterate them and output them to the console’s log.
Other Retrieval Options
There are other options to retrieve all the stored items in an objectStore. In FireFox you can use the getAll function which is not a part of the HTML5 IndexedDB specifications (and therefore I suggest not to use it at all):
var request = store.getAll();
request.onsuccess = function(evt) {
// Extract all the objects from the event.target.result
};
Summary
This post showed you how to get all the stored items in an objectStore. This operation is very common and therefore I hope it will be added to the specifications as an API function.
New Speaking Engagement – Visual Studio Live

Lately, I have been chosen to speak at the Visual Studio Live (VSLive) conference. The conference will take place in August 6-10 at Microsoft headquarters in Redmond, WA, USA. I’m going to have a ~16 hours flight to go there, but I’m not flying alone. Ido Flatow, one of my Sela Group colleagues which is a “veteran” VSLive speaker, is going to the conference also and will have two sessions (one about ASP.NET Web APIs and the other about Windows Azure).
I’ll have two sessions:
- Working with Client-Side HTML5 Storages
HTML is the markup language that every web developer uses in order to structure and present content in the Internet. HTML5 is the standard that is being shaped and developed currently. It extends and improves the last HTML4 standard and takes it to the next level with support for multimedia, communication, semantics and more. In this session we will discuss the new storage options that HTML5 brings and how to use them. - Not Just a Designer: Code First and Entity Framework
Entity Framework 4 brought many new opportunities for building complex data driven applications. Code First is a new Entity Framework capability that provides a code-centric experience for interacting with models and databases. This session will cover several Entity Framework features such as Code First, and provide an overview for what to expect from Entity Framework vNext.
See you there!
Using HTML5 Server-Sent Events with JSON and ASP.NET MVC
I’m getting ready for a session that I’m delivering at the end of this month. I wanted to create a sample for using HTML5 Server-Sent Events and decided to share that sample with my Blog’s readers. But before I write about the sample, lets get to know the Server-Sent Events HTML5 API.
Server-Sent Events
Server-Sent Events is an acronym to the HTML5 EventSource JavaScript API. The Server-Sent Events enable servers to push data over HTTP using push protocols. The data that is sent to the client-side must have the text/event-stream MIME type and must be sent in the following form:
data: This is the first message.
Pay attention that the format has to include the data: prefix and end with line break to end the message.
Another way to send data is using a dedicated event by using the event type format. The following example shows two different events that the client-side can listen for:
event: event1
data: event1 data
event: event2
data: event2 data
In order to listen to an event in the client-side all you have to do is to create an EventSource object and give it a URL to listen. Also, you need to wire the message event handler in order to handle the data arriving from the server. Here is a simple example of creating an EventSource object:
var source = new EventSource(url);
source.onmessage = function (e) {
console.log(e.data);
}
The default event source is the message event as shown in the previous example. If you want to listen for a specific event type you will need to wire a handler for that event type like in the following example which listen on the event1 event:
var source = new EventSource(url);
source.addEventListener('event1', function (e) {
console.log(e.data);
}, false);
Server-Sent Events Using JSON and ASP.NET MVC
After we learned what are Server-Sent Events lets dive into a much more robust example. In the example, I use ASP.NET MVC as my server side technology.
The Client-Side
We start in the client-side implementation. In the Index view of the Home controller I’ll add an messages unordered list and the script that creates the EventSource object.
@{
ViewBag.Title = "Home Page";
}
<script> 1:
2: function contentLoaded() { 3: var source = new EventSource('home/message'); 4: var ul = document.getElementById("messages"); 5: source.onmessage = function (e) { 6: var li = document.createElement("li"); 7: var returnedItem = JSON.parse(e.data)
8: li.textContent = returnedItem.message + ' ' + returnedItem.item;
9: ul.appendChild(li);
10: }
11: }
12:
13: window.addEventListener("DOMContentLoaded", contentLoaded, false);</script>
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
http://asp.net/mvc</a>.
</p>
<ul id="messages">
</ul>
As you can see I use the DOMContentLoaded event to start the script when all the DOM content finished to load. I’m creating an EventSource with the name source to listen to the home/message endpoint. Since I expect that the data returned from the server is in JSON format, I parse it using the JSON.parse function and use its content to create a new list item.
The Server-Side
Writing the client-side was easy. The server side is also easy but there are some things to notice. First of all, I use a BlockingCollection object which is a wrapper on top of a IProducerConsumerCollection collection. Another object that I use is the JavaScriptSerializer that will serialize an object on the server to JSON representation.
Here is the HomeController code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Collections.Concurrent;
using System.Text;
using System.Threading;
using System.Web.Script.Serialization;
namespace ServerSentEvents.Controllers
{
public class HomeController : Controller
{
private static BlockingCollection<string> _data = new BlockingCollection<string>();
static HomeController()
{
_data.Add("started");
for (int i = 0; i < 10; i++)
{
_data.Add("item" + i.ToString());
}
_data.Add("ended");
}
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Message()
{
var result = string.Empty;
var sb = new StringBuilder();
if (_data.TryTake(out result, TimeSpan.FromMilliseconds(1000)))
{
JavaScriptSerializer ser = new JavaScriptSerializer();
var serializedObject = ser.Serialize(new { item = result, message = "hello" });
sb.AppendFormat("data: {0}\n\n", serializedObject);
}
return Content(sb.ToString(), "text/event-stream");
}
}
}
Pay attention that in the
Message action I’m returning the
text/event-stream content type.
The following figure shows the output of running the above code:

Summary
Server-Sent Events is a good mechanism to push data from the server to the client without the need server polling. The API handles only one side communication (server to client). If you want to use a bidirectional communication channel you should look at the HTML5 Web Sockets API. Using Server-Sent Events is appropriate for listening for changes in feeds such as stocks feed or RSS feed as long as they implement the push protocol.
Writing Your Own JavaScript Library – Enums
Continuing the post series about writing a JavaScript library, in this post I’m going to show how to create enums in JavaScript.
JavaScript Enums
If you use an object oriented language you probably used enums in your code. Enums are strongly typed constants that assign meaningful names to integer values. Then, instead of using magical integers all over your code you will use an enum instead. When writing an API or a library (not necessary in JavaScript), it is very helpful to create enums to express your integer constants. Using enums can help making your code more expressive to its users and more maintainable to you (you don’t need to remember what you meant when you used some integer value in your code).
JavaScript doesn’t include implementation for enums out of the box. On the other hand, JavaScript is a dynamic language and therefore you can mimic enums behavior by using an object literal. Here is an example of creating a JavaScript enum:
var enumExample = {
Value1: 0,
Value2: 1,
Value3: 2
};
In the example, an enum is created with the name enumExample. It is assigning three values with the constants of 0, 1 and 2. In order to use the previously created enum you can write code such as:
var someValue = enumExample.Value1;
// this code can appear later in the code
if (someValue === enumExample.Value1) {
// do something
}
switch (somevalue) {
case enumExample.Value1:
// do something
break;
case enumExample.Value2:
// do something else
break;
default:
break;
}
Writing an Enum in JavaScript Library
Here is an example of adding an enum to the library from the previous post:
(function (ns) {
ns.enumExample = {
Value1: 0,
Value2: 1,
Value3: 2
};
}(this.ns = this.ns || {}));
In the example an enum is added to the library’s namespace and will be exposed to the library’s users.
Summary
In the post I explained how to create a JavaScript enum and how to expose it through the JavaScript library. Using enums can help to create a much more expressive and meaningful API. Creating meaningful code might help the library users to adopt the library much faster.