Click here to Skip to main content
15,886,783 members
Articles / Web Development / HTML5

Using HTML5 data-* tags, Razor, and C# Anonymous Objects

Rate me:
Please Sign up or sign in to vote.
4.80/5 (5 votes)
24 Jun 2012CPOL3 min read 24.3K   16   2
How to use HTML5 data-* tags, Razor, and C# anonymous objects

One of the most used new features of the HTML5 spec are the data-* attributes. This provides a nice and valid way to store JSON data corresponding with HTML elements on a page.

The basic usage is as follows:

Say I have an HTML element like so:

XML
<div id="user" data-my='{id:123,name:"John Doe", email:"johndoe@mail.com"}'>
    John Doe
</div>

You can see that there is some JSON data stuffed into the “data-my” tag. If this attribute was not prefixed with “data-”, then this would officially be against the w3c guidelines. However, since it is, we can stuff pretty much whatever we want into there.

The interesting part, though, is that we can now utilize the .data() function of jQuery in order to access that information, and it will provide us that information as an actual JS object, rather than as a string like the .attr() function would work:

JavaScript
console.log($("#user").data("my").name); //prints "John Doe"

This is a pretty powerful feature in and of itself… but now it is left up to me to write the server side code which generates these HTML attributes, which might be a pain.

If you go look at the HTML source code for any random facebook page, you will find that almost every element in that page has a “data-ft” attribute and some associated data with it. The reason is because if you want to write heavy client-side apps where interaction with different elements on the page is everywhere, it is a lot easier to just stuff a bunch of metadata into these data tags and then look for it in your JavaScript, rather than having to figure out the metadata from hidden input fields which are nearby (which of course is the super-old-school HTML4 way of doing things).

I am writing an app in ASP.NET with the C# Razor View Engine that just so happens to have a heavy client-side component, so I thought I would write some code to help me make this process cleaner…

C#
using System.Web;
using System.Web.Script.Serialization;
public static class DisplayExtensions
{
    /// <summary>
    /// Returns an Html-Encoded string to be put inline with an Html Element with the
    /// data-attribute name "data-my".  Ie, returns: data-my="{ encoded Json }"
    /// </summary>
    public static IHtmlString MYData(object data)
    {
        var serializer = new JavaScriptSerializer();
        return new HtmlString(string.Format(
            "data-my=\"{0}\"",
            HttpContext.Current.Server.HtmlEncode(serializer.Serialize(data))
            ));
    }
}

This method, which I’ve called “MYData” but it could be whatever you want it to be, which accepts an object and returns an IHtmlString wrapped string which contains the HTML data-* attribute which I’ve hard-coded as “data-my” and the strict JSON serialized representation of the object, HTML-encoded into the attribute tag’s value. The object is being serialized using Microsoft’s JavaScriptSerializer class.

In order to keep my view’s syntax nice and sweet, I’d like to have “MYData” available to me as an instance function off of my WebPage base-class, so I re-implemented the ASP.NET Razor WebPageBaseType. In order to do this, you need to:

1. Create a New Abstract View Base Class

C#
using System.Web.WebPages;
public abstract class CustomWebView : WebPage
{
    public IHtmlString MYData(object data)
    {
        return DisplayExtensions.MYData(data);
    }
}

2. Tell Razor to USE Your base-class by Default via your Web.Config

XML
<configSections>
  <sectionGroup
    name="system.web.webPages.razor"
    type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup,
      System.Web.WebPages.Razor,
      Version=1.0.0.0,
      Culture=neutral,
      PublicKeyToken=31BF3856AD364E35">
    <section
      name="pages"
      type="System.Web.WebPages.Razor.Configuration.RazorPagesSection,
      System.Web.WebPages.Razor,
      Version=1.0.0.0, Culture=neutral,
      PublicKeyToken=31BF3856AD364E35"
      requirePermission="false" />
  </sectionGroup>
</configSections>
<system.web.webPages.razor>
  <pages pageBaseType="MyNameSpace.CustomWebView"></pages>
</system.web.webPages.razor>

Note: You can alternatively use the @inherits MyNameSpace.CustomWebView keyword if you want to use it on a page-by-page basis.

Now, I will have this available to me in my .cshtml file

conveniently add metadata to HTML elements in Razor

HTML
<!DOCTYPE html>
<html>
    <head></head>
    <body>
        @{
            var user = new
            {
                id = 123,
                name = "John Doe",
                email = "johndoe@mail.com"
            };
        }
        <div id="user" @MYData(user)></div>
    </body>
</html>

For a bonus, you can even write a small jQuery function which will get your data by default:

JavaScript
$.fn.my = function () {
    /// <summary>
    /// quick-hand to grab the object in the "data-my" attribute
    /// </summary>
    return this.data("my") || {};
};

and so then you could use it like so:

JavaScript
console.log($("#user").my().email); //prints "johndoe@mail.com"

This is all pretty small stuff, but if you are writing a large application that will make heavy use of AJAX and JavaScript/client manipulation… it can be really instrumental in writing simpler code without muddying up your HTML with a bunch of hidden inputs or some other method of storing the data inside the HTML.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder
United States United States
My name is Leland Richardson. I love learning. At the time of writing this I am 23 years old and live in Houston, TX. I was born in West Palm Beach, Florida, grew up in St. Louis, Missouri, and went to school in Houston, Texas at Rice University.

At Rice I received two degrees: one in Physics and one in Mathematics. I love both. I never received any formal education on Computer Science, however, you will find that most of this blog will be about programming and web development. Nevertheless, I think being a good programmer is about being good at learning, and thinking logically about how to solve problems - of which I think my educational background has more than covered.

Since high-school, I had found that the easiest way to make money was by programming. Programming started off as a hobby and small interest, and slowly grew into a passion.

I have recently started working on a new startup here in Houston, TX. I wont bore you with the details of that just yet, but I am very excited about it and I think we can do big things. We plan to launch our project this year at SXSW 2013. What I will say for now, is that we would like to create a company of talented software developers who are similarly ambitious and want to create cool stuff (and have fun doing it).

Comments and Discussions

 
GeneralMy vote of 5 Pin
StianSandberg3-Jul-12 0:08
StianSandberg3-Jul-12 0:08 
GeneralMy vote of 5 Pin
Adesh_Viprak26-Jun-12 20:27
Adesh_Viprak26-Jun-12 20:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.