Add HTML5 Geolocation plus Bing Maps into ASP.NET MVC views

The Bing Maps API is a free, easy to use API, that allows you to incorporate mapping features into your ASP.NET MVC or application by using Web standards such as JavaScript, and the now supported HTML5 Geolocation.

Bing Maps and ASP.NET MVC

A Bing maps API key is required when using the API. The Bing Maps key allows you to access Geolocation data, and to manipulate an in-view Map object with JavaScript via the Bing Maps API. The Bing Maps Developer Portal is where you can get a key by registering with your Windows Live ID.

Once you’re set with a key, you’ll need these files in your MVC project to develop with Bing Maps:

\Scripts\YourBingMapsScript.js – This file contains your script that works with Bing Maps & Geolocation.

\Content\Site.css – A small bit of CSS is required to style the Map

\Views\BingMaps\Index.cshtml – The MVC view that contains the Bing Map HTML

Since the code is HTML &CSS that conform to Web standards, the bulk of the lives is in the .js file and/or the view. Although using MVC, the model and controller are not necessary for manipulating maps with client side script, but don’t throw out the model and controller yet, as you will need them to work with other data.

The Bing Maps Interactive SDK

If you’re writing code that uses Bing Maps, the Interactive Bing Maps SDK is a “must visit” Web site. By choosing the options on the left of the page, the Bing Maps Interactive SDK creates usable JavaScript, and a “View HTML ” button that exposes the page source.

 

image_2

The Bing Maps API & SDK contain more than an interactive website. Bing Maps development gives you access to many productive development tools such as:

  • The Bing Maps AJAX Control (multiple versions)
  • The Bing Maps iOS Control
  • A Bing Maps Silverlight Control
  • SOAP and REST services
  • More…

You can use the Bing Maps Interactive API to create the equivalent code as the samples shown in this post.

Render Bing Maps in MVC views with the Bing Maps AJAX control.

While it’s called the Bing Maps AJAX control, it’s not a control at all, but a JavaScript library instead. HTML and client side script (JavaScript, jQuery, etc…) are the enabling technologies for Bing Maps on the ASP.NET (or any Web) platform. To reference the Bing Maps AJAX Control, your view needs the <script> reference below.

<script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0" type="text/javascript"></script>

If you plan to use the Bing Maps AJAX control in multiple views, the <script> reference can go in the _Layout.cshtml file, otherwise you can add it to the required views or a different layout page. Inside a view, a <div> element should contain and display the map, and is also the DOM object that you manipulate in code, so it needs an id attribute.

<div id="map"></div>
Since the browser renders a tiny <div> by default, some CSS is necessary, such as the position, width, and height, in which to create a suitable DOM shape for maps. You can save the CSS in the \Content\Site.css file, or its own file, for reusability across views.  
<style>
#map
{
    position:relative; 
    width: 500px; 
    height: 500px; 
    border:0px
}
</style>

After the HTML is in place, you can write code to capture the user's positional data to display a Bing map showing the location, nearby restaurants, or other information requested by the user. 

Display a Bing Map with a Pushpin.

You first need positional data from the user before displaying the map. Once you have the positional data points, i.e., latitude and longitude, you can add a Bing Map to any MVC view. To learn how to obtain positional data for your Web site or app, see this post on creating location aware Web sites with the HTML5 Geolocation.

The code below retrieves the latitude and longitude coordinates from the position argument of a showMap method, then creates an instance of a Map object the position, credentials, center, map type, and zoom level. The code continues on by centering the Pushpin to represent the user’s location in the map.

function showMap(position) {
 
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;
 
    var map = new Microsoft.Maps.Map($("#map")[0],
    { 
        credentials: "Your Bing Maps API Key",
        center: new Microsoft.Maps.Location(latitude, longitude),
        mapTypeId:   Microsoft.Maps.MapTypeId.road,
        zoom:        10
    });   
 
    var center = map.getCenter();
    var pin = new Microsoft.Maps.Pushpin(center, { width: 50, height: 50, draggable: false });
    map.entities.push(pin);
}

The result should look something like this (but with your coordinates):

SNAGHTML1015b426

Should you want to customize the Pushpin icon, just change the Pushpin construction arguments, and pass in the path and name of the graphics file (.png, .jpg., and standard Web formats).

var pin = new Microsoft.Maps.Pushpin(center, {icon: 'CustomPushpin.png', width: 50, height: 50, draggable: true}); 

Customizing the map further by adding an Infobox, which is a small rectangle with information about a particular location, takes only a few lines of code. Make sure the clear method is run before pushing an Infobox onto a map or the latest Infobox, Pushpin, or other object will overlay the previous.

 map.entities.clear(); 
 var infoboxOptions = {title:'Bing Maps Rock!', description:'Add an Infobox to a map with very little JavaScript!'}; 
 var defaultInfobox = new Microsoft.Maps.Infobox(map.getCenter(), infoboxOptions );    
 map.entities.push(defaultInfobox);

The above code creates an Infobox on the map similar to the one shown here:

SNAGHTML101866d1 

These are just a few simple, but core examples, of what you can do with Bing Maps. For more information on developing for Bing Maps, see below in the Summary & Resources.

Summary & Resources

The Bing Maps AJAX control is a handy library you can use to add geo-interactivity to your Web sites with little code. Additionally, you can incorporate other APIs to make full featured location aware mapping apps.

Use the W3C Geolocation API to create location aware Web sites

The Bings Map control (Bing Maps API)

Bing Maps Articles

Customizing Bing Maps Pushpins

G. Andrew Duthie demonstrates bing maps in action with CommunityMegaphone.com

ASP.NET MVC ActionResults explained

Action results are an important part of the ASP.NET MVC controller system, and definitely worth taking a good look at. Understanding how they work gives you many more choices in MVC and that will certainly help make your code better.

What is an ActionResult?

An ActionResult is a return type of a controller method, also called an action method, and serves as the base class for *Result classes. Action methods return models to views, file streams, redirect to other controllers, or whatever is necessary for the task at hand. The controller takes on this responsibility to connect system components, acting as a traffic cop.

There are many derived ActionResult types you can use to return results that are more specific for a particular view. You can quickly access the derived types of the ActionResult during development by hovering over an ActionResult in an action result’s method signature then expanding the type tool window, to see what *Results the ASP.NET Framework provides.To get a deeper look at what exactly an ActionResult type is and how it works, running the code with a breakpoint set at the end of an action result method will get the information we want. Inspecting the image below of the Watch window shows some of the properties that you can tap into that ActionResults return.

Notice the Model, TempData, ViewBag, and ViewData properties. Drilling into the Watch window even further exposes the Model property’s strongly typed collection of objects.

SNAGHTML4d9b785_thumb3_2

These objects contain everything you need when working in the view. Of course, the Model is the most heavily used object, containing our application’s schema and data. The TempData object holds data between multiple controllers, while ViewBag and ViewData objects holds data between controllers and/or views.

Since the Model property is the actual model the view uses to render the data, its data type should align with the type specified in the @model directive in the target view. As pointed out in the image above, the Model property contains a strongly typed list of Product objects (or whatever you’re returning), matching the view’s model.

Looking in the Watch window shows that the runtime converts the ActionResult to a ViewResult, however you’ll want to be more specific during design time. Swapping ActionResults for more specific/derived classes, for example, a ViewResult, produce the exact same object structure as the ActionResult. With this in mind, using more specific types increases code accuracy, maintainability, and even performance as the compiler has a much better idea of what should happen at compile time, rather than at the last minute at runtime, since no runtime conversion happens.

Action methods, action results & routing

Action methods and the routing system work together in every MVC application. MVC does this by using a set of conventions, defined as routing patterns in the global.asax.cs file. These patterns connect HTTP requests with controllers and action methods. As an HTTP Request enters the routing system, it determines which controller should serve data to which view (if any).

The global.asax.cs defines the default routing pattern, {controller}/{action}/{id}, as described in more detail here:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
}

Picking apart each piece of the route pattern is a great way to digest what the routing system is doing…

  • {controller} Controller maps a part of the URL to the name of the controller class. For example, a class named ProductsController, will map to URLs that start with /Products (after the domain of course). ASP.NET automatically drops the word “Controller” from the URL so is it’s more user friendly, e.g., /Products vs. /ProductsController.
  • {action} Action maps a part of the URL to the individual methods inside controllers. Therefore the ProductsController.Edit(…) and ProductsController.Details(…) methods align with the /Products/Edit and Products/Details URLs, respectively. Action maps without any parameters, since the next route pattern, id, defines them.
  • {id} Id maps to an identifier, such as a product id or a product name. These are controller action method parameters, so the value at the end of the URL is generally the value of the method’s argument. For example, /Products/Edit/2 matches up with the id argument in ProductsController.Edit(int id). The controller methods normally use this id to query for a single record with a matching id to return to the view.

Below is a table detailing the mappings between routes, controllers, action methods and their parameters.

Action Method Route {controller}/{action}/{id} HTTP POST/GET
public ActionResult Index() { } /Products GET
public ActionResult Details(int id) { } /Products/Details/id GET, values in URL
public ActionResult Edit(int id) { } /Products/Edit/id GET, values in URL
[HttpPost]
public ActionResult Edit(int id, FormCollection collection) { }
/Products/Edit/id POST, values in FormCollection
public ActionResult Create() { } /Products/Create GET
[HttpPost]
public ActionResult Create(FormCollection collection) { }
/Products/Create POST, values in FormCollection
public ActionResult Delete(int id) { } /Products/Delete/id GET, values in URL
[HttpPost]
public ActionResult Delete(int d, FormCollection collection) { }
/Products/Delete/id POST, values in FormCollection

You may have noticed that the Edit, Create, and Delete action methods come overloaded as pairs, and an [HttpPost] attribute decorates one method in each pair. Since [HttpGet] is the default, the other method doesn’t need to be marked. Additionally, all methods decorated with the [HttpPost] attribute are meant to accept HTML input fields located between the <form> tags. The collection parameter of type FormCollection[1] contains all the input fields from the <form> of the HTTP Post.

Every method in a controller class returns an ActionResult by default; however, some actions will be more optimized, clear, or accurate in the code, if we are to specify a more specific action results, for instance, a ViewResult, rather than an ActionResult. Action result methods can also designate that its result will return something other than data for a view, e.g., a HttpNotFoundResult or an HttpStatusCodeResult, as shown in the code below:

Returns an HTTP 404 Not found error:

public HttpStatusCodeResult NotFound()
{
    var result = new HttpStatusCodeResult(404);
    return result;
}

Redirects to a separate view altogether:

[HttpPost]
public RedirectResult Create(FormCollection collection)
{
    // code to save form data ...     
    return new RedirectResult("Home/Index", false);
}

There’s many more ActionResult types to explore. Check them out and find something that meets the needs of your controller and/or view.

Summary

ActionResults are a key component to ASP.NET MVC, so understanding them is essential for MVC application development. Whether you need to make AJAX calls, redirect, return a file stream, or just return data to a view, ActionResults are right there in the center of all the……action.

[1] I recommend rather than using FormCollection, you should use a strongly typed parameter or multiple, differently typed parameters that match to data types in the HTML form. Look forward to a blog post soon to demonstrate this.

Building a relational data model in ASP.NET MVC w/EF Code First

Just about every application uses some sort of data model, and .NET developers have been using POCOs (Plain Old CLR Objects) for some time now. You can use either new or existing POCOs in MVC 3 applications and still take advantage of EF (Entity Framework), and in particular, EF’s Code First feature. EF’s Code First feature allows you to base both an application and a database from your data model. EF additionally carries features for database and model first development.

Data Models, ORMs & Entity Framework

As with most business apps of any type, data models are at the heart of an application. When developing ASP.NET MVC applications it’s best to go with an ORM (Object-Relational Mapper) such as EF, as ORMs alleviate many pains in dealing with databases and their objects. Since MVC is extensible and pluggable, you also have the choice of using 3rd party or open source ORMs, for example, the widely used nHibernate.

That’s where things can get complex, and that’s where EF fits in with multiple strategies to help alleviate common pains in modeling. There are many ways you can model data to represent and manipulate it the way you need to, either visually with a designer, or by using code. EF supports these data access options:

  • Database first
    • You can use Visual Studio to connect to a data source and visually generate a data model from an existing database(s).
  • Model first
    • Using model first you can build brand new databases from models you’ve created using the designers in Visual Studio.
  • Code First
    • With code first, you start with your own POCOs, just add a small amount of code, and voilà, instant ORM.

In addition to these features, EF has more advanced features, such as a XML based schema mappings and fluent APIs. EF is flexible enough to cover the spectrum of applications from the smallest of web sites to enterprise applications.

Before coding EF classes, you must add a NuGet package reference to EntityFramework by selecting “Add Library Package Reference” from the Project menu, and before using SQL CE 4.0 you’ll need to add a regular reference to the System.Data.SqlServerCe library.

Building the basic data model

Code First is a feature of EF that maps POCOs containing classes, relationships, data annotations, etc…, to database tables, columns, constraints, and relationships in physical databases. EF CF creates the database by examining the code in the data model, then building the corresponding physical database and its objects. You have the option to merge or drop/recreate any databases generated by EF Code First, and you can additionally seed the database with  data (coming in a later post).

Since the controller returns the model to the view, you can send validation information to the view by using Data Annotations. Data annotations are attributes that you can apply to a model to perform common types of validation at the property level, as shown below in two basic POCO classes.

public class Category

{

    public int Id { get; set; }

 

    [DisplayName("Category")]

    [Required(ErrorMessage = "The product category is required.")]

    public string Name { get; set; }

}

public class Product

{

    public int Id { get; set; }

 

    [DisplayName("Delicious Treat")]

    [Required(ErrorMessage = "The product name field is required.")]

    public string Name { get; set; }

 

    [Required(ErrorMessage = "The product description field is required.")]

    public string Description { get; set; }

 

    [DisplayName("Sale Price")]

    [Required(ErrorMessage = "The Sale Price field is required.")]

    public decimal Price { get; set; }

 

    [DisplayName("Made fresh on")]

    [Required(ErrorMessage = "The Freshly Baked On field is required.")]

    public DateTime CreationDate { get; set; }

 

    [DisplayName("Don't Sell After")]

    [Required(ErrorMessage = "The Expiration Date field is required.")]

    public DateTime ExpirationDate { get; set; }

 

    [DisplayName("Qty Available")]

    [Required(ErrorMessage = "The Qty Available field is required.")]

    [Range(0, 120,ErrorMessage="The Qty Available must be between 0 and 120.")]

    public int QtyOnHand { get; set; }

 

    [DisplayName("Product Image")]

    public string ImageName { get; set; }

}

Now that you have a model, you can add a few lines of code to tell EF to generate the database for you, and even seed it with data if you want to. In order for EF to know what classes in a project it should use as a model to generate the database, you need to tap into two classes from the System.Data.Entity namespace:

  • DBContext class.
    • The DbContext is a lot like a connection, except it manages database connectivity for you automatically (i.e., no need to explicitly call open/close on connections). Additionally, there are many properties methods on the DbContext class to work directly with the model and/or database, such as the SaveChanges method or the ValidateEntity method.
  • DbSet class
    • This object knows how to deal with CRUD operations on the entity class itself (i.e., Category or Product), and works in tandem with the DbContext object to perform those operations.

A data model is not just a set of POCO classes, though. Models need a class to manage the POCOs, perform connection management, or other duties that an ORM would do. These management classes are often called a context or repository[1]. Rather than writing the database and connection management code yourself, you can take advantage of EF and receive features provided automatically by inheriting from the DbContext class in your repository class.

The DbContext also needs to know what POCO collections to work with. You can do this by adding properties of type DbSet<T> for each of your collection types, as the code below demonstrates.

public class FourthCoffeeWebContext : DbContext

{

    public DbSet<Category> Categories { get; set; }

    public DbSet<Product> Products { get; set; }

}

At this point, the two POCO classes and DbContext are all you need to see EF in action, and you can move onto running the application and generating the physical database.

Generating the database from the model

Assuming you have the controllers and views in place to perform CRUD operations on the Categories and Products collections, running the MVC application will create a SQL (Express or CE 4.0) database automatically for you. Of course, there’s no data, just the schema, but the site and database are both up, running, and completely functional. Navigating to the create action on the products controller in a browser renders the create view like the one below (including validation!):

 

image_6

 

Once you save a product, the app takes you back to the listing of products, where you can see the results.

image_8

Although you can see the data on in the browser, you probably can’t find the database in the Solution Explorer. Checking out the customary App_Data folder reveals nothing, and examining the Web.Config file comes up empty. Since EF could find no information about the database, it created a SQL Express[2] database with the a default name and path shown here:

C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\FourthCoffee.Web.Models.FourthCoffeeWebContext.mdf.

If you want to name your database something different, modify the <connectionStrings> section of the Web.Config file to point to the preferred database name and location. This connection string connects to the \App_Data\bakery.sdf database.

<connectionStrings>  

  <add name="FourthCoffeeWebContext" connectionString="Data Source=|DataDirectory|bakery.sdf" 

  providerName="System.Data.SqlServerCe.4.0" />

</connectionStrings>

By convention, the name of this connection string needs to match the name of your context/repository class, in this case, FourthCoffeeWebContext, so EF can identify the connection string to use. Notice that the connection string points to the data directory (App_Data) and it’s a SQL CE 4.0 database. If you wish to use a different edition of SQL, feel free to change the connection string and provider name to point to other locations.

Once the changes are in place, run the application, enter some data, and return to Visual Studio where you can see the App_Data folder now contains the bakery.sdf database.

image_10

Since the option to drop and recreate the database exists, you can design your data model through code and tests to verify that it works in a repetitive cycle, so relating the classes and regenerating the database is easy.

Relating classes in the data model

The Category and Product classes relate to each other in a one-(zero or)many relationship. You can express this relationship in code by adding a property in the Category class to represent the collection of related products, as shown here:

public virtual ICollection<Product> Products { get; set; }

The Product class needs two lines of code, so you’ll need to add the following properties below to the Product class.

public int CategoryId { get; set; }

public virtual Category Category { get; set; }

While the data model is complete, the code in controllers and views does not reflect the updates made to the model. The Edit and Create views associated with the Product need to include a dropdown of the categories, with the current product’s category selected, similar to the code below:

<div class="editor-label">

    Category

</div>

<div class="editor-field">

    @Html.DropDownListFor(model => model.CategoryId, 

    ((IEnumerable<FourthCoffee.Models.Category>)ViewBag.PossibleCategories)

        .Select(option => new SelectListItem {

        Text = (option == null ? "None" : option.Name), 

        Value = option.Id.ToString(),

        Selected = (Model != null) && (option.Id == Model.CategoryId)

    }), "Choose...")

    @Html.ValidationMessageFor(model => model.CategoryId)

</div>

Since the view is counting on the controller to pass in a ViewBag.PossibleCategories, you’ll now need to wire up the Create/Edit action methods of the Products controller so the view can use it. Just create a dynamic property on the ViewBag object and set it to the context’s Categories property.

// the context variable is of type FourthCoffeeWebContext (Inherits from DbContext)

ViewBag.PossibleCategories = context.Categories;

Generating an app from the finished model

The application at run time produces 100% supported CRUD operations, but now with relational operations and validation as well. This is evident in the Product’s Edit or Create view.

image_11

Note: Before running the application, you’ll need to delete the database or you’ll receive an error message.

Summary

MVC with Entity Framework Code First enables you to rapidly build sites with easy to understand data models.

Resources:

Code First w/existing DB

Code First

 

[1] Dear purists: I am not going to be pedantic about the repository pattern in this blog post.

[2] If you don’t have SQL Express installed, you might get an error. If that’s the case modify the web config to use SQL CE 4.0 instead, as it does not need to be installed.

Managing data in web applications with HTML5 Web Storage

Before the advent of Web Storage, developers have had to juggle between cookies, session, query strings, and HTML forms to manage data across stateless HTTP requests – with cookies being the only client-side, data storage mechanism. Working with all these different ways to get data from here to there is often tedious at best, but unavoidable, as most web applications do need to preserve state somewhere. At the same time, you also need to consider users who have turned off features like cookies, either knocking both cookies and session objects out of the question or making them harder to work with than they should be.

Enter…HTML5 Web Storage

HTML5 Web Storage, also known as DOM Storage, is a way to preserve state on either the client or server, making it much easier to work with (or should I say against?) stateless nature of HTTP. Web storage gives you, the developer a great deal of flexibility in how you deal with data. In the earlier days of the web, hardware constraints on both the server and client, coupled with low bandwidth, created an environment in which it was much harder to pass data around. Today however, hardware is cheaper, better, and faster, so most of the constraints have been lifted, but the supporting mechanisms to move data around haven’t changed much (e.g., cookies, session, query strings). That is, until the advent and adoption of Web Storage.

Today’s storage issues revolve around these points:

  • Having a choice between storage on the server or client between HTTP requests
  • The need to deal with larger sets of data, to provide a rich client side experience to users
  • Optimize performance and scalability by not forcing data to travel with the HTTP requests, like cookies, form data or query strings.
  • Cross browser friendliness

Web Storage helps solve these important issues, as you can add data to either server (session) storage or a local (client memory) storage.

Web Storage Browser Compatibility

As far as cross browser compatibility goes, all the major browsers support Web Storage.

image_2

 

Web Storage size limits

Web Storage also allows you to cram much more into storage than the traditional 4k that you get with cookies. So far, the value is 5MB; however, browsers can implement the limits they’d like. According to the W3C, here’s the official word on Web Storage size limits.

“A mostly arbitrary limit of five megabytes per origin is recommended. Implementation feedback is welcome and will be used to update this suggestion in the future.”

IE allows up to 10MB, as stated here in the DOM Storage documentation on MSDN.

“Storage size is calculated as the total length of all key names and values, and a single storage area can contain up to 10 million bytes. The remainingSpace property is used to determine the available storage space.”

Moving from a mere 4k to more than 5MB gives you far more space to work with than ever before. Of course, you still need to write the code to work with Web Storage.

Working with the Web Storage API

The Web Storage API is a really small and easy to use library to stash data wherever and whenever you need. However, Web Storage isn’t just a huge bag of cookies or over-bloated session variables. Because you can store data locally, without transmitting it back to the server, applications such as these are far easier to write and maintain.

  • Wizards, multi-page applications
  • Shopping cart data
  • Local document storage, for online word processing, spreadsheets, or blogs
  • Rich, UI heavy web applications that need to display large amounts of data

Applications like these will also perform much better, as bandwidth needs decrease when the data stays put, and doesn’t travel with the HTTP request, as cookies and form elements do.

There are two ways to deal with data in the Web Storage API:

  • Local storage
    • Long term data persistence
    • The local storage object spans multiple windows and persists beyond the current session
    • Values put into localStorage are shared across all windows from the same origin
    • Data is stored on the client. Behaving similarly to cookies, values persist beyond when the browser’s session ends
  • Session storage
    • Short term data persistence
    • Once the browser’s session ends (window/tab closed), sessionStorage ends
    • Values put into sessionStorage are only visible in the window/tab that created them
    • Data is stored on the server

Both objects are properties of the browser’s window object, and you can access them by using JavaScript/jQuery. Both local and session storage objects are of type

Implementing a simple hit counter will work with similar syntax between local and session storage, however, it will behave much differently in each. Take for example, the following code that sets a page count in local storage and outputs it to an element with an id of pageCount :

$(function () {

    if (localStorage.pagecount) {

        localStorage.pagecount = Number(localStorage.pagecount) + 1;

    }

    else {

        localStorage.pagecount = 1;

    }

    $("#pageCount").text(localStorage.pagecount)

});

<div id="pageCount">Page Count</div>

The page count will increment each time this page is visited by the same user agent, regardless of whether or not it’s a different tab or  window. Closing and reopening the browser will continue to show data in local storage, as it’s been saved to disk. Session storage, on the other hand, though similar in syntax, will vanish once the user has closed the browser. Below is a sample of the same code, but done with session storage:

$(function () {

    if (sessionStorage.pagecount) {

        sessionStorage.pagecount = Number(sessionStorage.pagecount) + 1;

    }

    else {

        sessionStorage.pagecount = 1;

    }

    $("#pageCount").text(sessionStorage.pagecount)

}); 

<div id=”pageCount”>Page Count</div>

Due to JavaScript’s dynamic nature, you can create properties on either local or session storage on the fly, as is the case with the pagecount variable in the previous samples. This gives you a lot of flexibility when determining how and where to work with data. This flexibility does come at a price…

Web Storage and security

Security is important to all aspects of development, as where malicious users can gain access to sensitive information or cause damage. Any time that you involve and store data, an attacker will try to gain access to it.

Web Storage is more public than cookies, and you’ll need to take special precautions to ensure security if Web Storage isn’t compromised by attackers. The W3C provides these guidelines on Web Storage security, quoted here:

7.1 DNS spoofing attacks

Because of the potential for DNS spoofing attacks, one cannot guarantee that a host claiming to be in a certain domain really is from that domain. To mitigate this, pages can use TLS. Pages using TLS can be sure that only the user, software working on behalf of the user, and other pages using TLS that have certificates identifying them as being from the same domain, can access their storage areas.

7.2 Cross-directory attacks

Different authors sharing one host name, for example users hosting content on geocities.com, all share one local storage object. There is no feature to restrict the access by pathname. Authors on shared hosts are therefore recommended to avoid using these features, as it would be trivial for other authors to read the data and overwrite it.

Even if a path-restriction feature was made available, the usual DOM scripting security model would make it trivial to bypass this protection and access the data from any path.

7.3 Implementation risks

The two primary risks when implementing these persistent storage features are letting hostile sites read information from other domains, and letting hostile sites write information that is then read from other domains.

Letting third-party sites read data that is not supposed to be read from their domain causes information leakage, For example, a user’s shopping wishlist on one domain could be used by another domain for targeted advertising; or a user’s work-in-progress confidential documents stored by a word-processing site could be examined by the site of a competing company.

Letting third-party sites write data to the persistent storage of other domains can result in information spoofing, which is equally dangerous. For example, a hostile site could add items to a user’s wishlist; or a hostile site could set a user’s session identifier to a known ID that the hostile site can then use to track the user’s actions on the victim site.

Thus, strictly following the origin model described in this specification is important for user security.

As you can see, there is some thought needed before running off to use Web Storage. Additionally, this article from Network World describes HTML5 security issues in general and including specifics on Web Storage.

Summary

Web Storage has the support of all major browsers while promising to be a versatile technology that allows you to create more robust, data driven, client side sites with little code. However, Web Storage is very new and you need to use it with caution, especially when concerned with security.

MSDN Intro to DOM Storage http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx

What you need to know about the Microsoft MVP Award

Each turn of the Microsoft MVP award cycle raises many questions in the developer and IT Pro communities as to what the award is about, who gets the award, and why we have it. This post aims to answer those and other frequently asked questions.

About The Microsoft MVP Award program

images_8

The MVP Website states:

“The MVP Award recognizes exceptional technical community leaders from around the world who voluntarily share their deep, real-world knowledge about Microsoft technologies with others.”

Each quarter, selected nominees receive the MVP award for their contributions to Microsoft technical communities in the past year. One can become a Microsoft MVP by way of nomination process, and anyone can nominate someone for an MVP award. Nominations do not guarantee receipt of the award.

The Becoming an MVP page of the MVP Website gives some details as to what happens once someone is nominated for the award.

“To receive the Microsoft MVP Award, MVP nominees undergo a rigorous review process. A panel that includes members of the MVP team and Microsoft product groups evaluates each nominee’s technical expertise and voluntary community contributions for the past 12 months. The panel considers the quality, quantity, and level of impact of the MVP nominee’s contributions. Active MVPs receive the same level of scrutiny as other new candidates each year.”

The panel consists of members of the MVP program with input from product team members and the field. The MVP program admins then invite awardees to participate in the MVP Award Program benefits for a one year award cycle. If the awardee accepts the MVP award, they must adhere to both a code of conduct and an NDA (a non disclosure agreement, which is a legally binding contract).

Here is what the award welcome gift looks like for 2012 (placard on the left, certificate on the right).

 

WP_000202_2

There are some frequently confused sentiments about MVPs and the award program:

  • Obtaining the award one year does not guarantee or influence next year’s decision. Much like the Grammy’s or Oscars, or other awards, it’s an award based on work in a particular area, for the previous year.
  • There is no prescriptive way or particular set of actions to become an MVP, since a prescriptive guide means it’s a certification, not an award.
  • Open Source Software is not an award category, since awards are hosted by product teams. Contributions to OSS projects can be, but are not necessarily, taken into consideration for the award.
  • Criticism of Microsoft products does not disqualify people from becoming an MVP, nor does it cause MVPs to “lose their MVP”.
  • The MVP award is not the result of a competition. One person never wins the MVP award in favor of another.  
  • The MVP award is not a membership or club.

Read the full set of FAQs here! If you’re not familiar with the varying Microsoft awards, certifications, and other programs, it’s easy to confuse them.

Certifications, Insiders, & Regional Directors Programs

Because programs like certifications are often confused with the MVP program, here is a quick rundown of Microsoft programs & certifications:

Certificationss: Microsoft certifications exist for nearly every active product. Certifications are 100% prescriptive, so there will always be an exam, lecture, or other set predetermined activities, that one must complete, while meeting a quality metric (i.e., a minimum score). Since certifications require exams, the certification candidate must pay to take the related exams, whereas there are no costs associated with receiving the MVP award. For more on MS certs, see the Certification Overview page.

Insiders: Microsoft maintains relationships with customers and partners of all types, from an individual contributor to companies and organizations. The ASP Insiders (and other insider programs) are Microsoft sponsored programs whose members participate in by providing feedback to ASP.NET, Visual Studio, or other product teams.

Regional Directors are trusted experts that Microsoft engineers in the field rely on for help with directing the best technical solutions for both the RD’s and Microsoft’s customers. Read more about RDs at the RD Home Page.

Summary

Congratulations to all of our new and renewed MVPs! Thank you all very much for sharing your expertise, experiences, and knowledge with the technical communities surrounding technology. I know many MVPs who get the award each year and it is because of their passion for Microsoft technologies, and a love of sharing their expertise.

The fine print:

MVPs, RDs, and Insiders, are not employees of Microsoft.

Previous to joining Microsoft, I had received the MVP award for multiple years, and also participated as an ASPInsider, and an MCT. I hold multiple certifications from Microsoft and other tech companies.