HTML5 Form Helpers For WebMatrix

It's an odd thing: WebMatrix 2 is lauded for its support of HTML5, but the Web Pages framework doesn't include any helpers for the new HTML5 form input types such as email or color. It's fair to say that support among browsers for the new inputs is patchy at the moment, but with barely a week flying past without a new version of one or other browser being released, it won't take long for that to change. So in the meantime, if you prefer to use helpers, you have to write your own for rendering HTML5 forms.

The new HTML5 form inputs cater for a wide variety of data types:

  • Color - should display as a colour picker of some sort
  • Date - will probably invoke a date picker
  • DateTime - will probably invoke a date picker combined with a mechanism for selecting hours and minutes and a time zone
  • DateTime-Local - as above but without specifying a time zone
  • Email - validates a string to ensure it is in an acceptable format for an email address
  • Month - will enable the user to select a month
  • Number - will allow users to supply a number value, possible through the use of a spinner control or similar
  • Range - a slider for selecting a number within a range
  • Search - behaves like a normal text box, but may be styled differently by the browser
  • Tel - text box used for telephone numbers. May be given some additional behaviour by mobile browsers
  • Time - enables input of a time in 24 hour format and validates it
  • Url - validates a string to ensure it is in an accepted format for a URL
  • Week - will enable the user to select a week number

While browser support varies, you can begin to use these new input types right now as browsers that don't understand the value you provide for the type attribute of an input element will always fall back on type="text" and render the element as a regular text box. Where they are implemented in browsers, they feature a number of new attributes such as "required", "min" and "max", allowing you to ensure that fields are mandatory, and to restrict the range of acceptable values. Moreover, validation on submission is performed by the browser, which means no more need for client-side JavaScript validation. Different browsers implement this in different ways (and to different extents at the moment).

The Web Pages framework was released as Open Source not long ago. That means the source code for the existing input helpers is available for all to see without having to obtain some kind of disassembly software. The code for the HTML5 helpers borrows a lot of inspiration from that:

using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
using System.Web.WebPages.Html;

public static class Html5Extensions
    private enum InputType{
        Color, Date, DateTime, DateTime_Local, Email, Month, Number, Range, Search, Tel, Text, Time, Url, Week

    public static IHtmlString Color(this HtmlHelper helper, string name, object value = null, object attributes = null){
        if (name.IsEmpty()) {
            throw new ArgumentException("Value cannot be null or an empty string.", "name");
        return BuildInputTag(name, InputType.Color, value, attributes);

    //Other methods removed for brevity

    private static IHtmlString BuildInputTag(string name, InputType inputType, object value = null, object attributes = null) {
        TagBuilder tag = new TagBuilder("input"); 
        tag.MergeAttribute("type", GetInputTypeString(inputType));
        tag.MergeAttribute("name", name, replaceExisting: true);
        if (value != null || HttpContext.Current.Request[name] != null) {
            value = value != null ? value : HttpContext.Current.Request[name];
            tag.MergeAttribute("value", value.ToString());
        if (attributes != null) {
            var dictionary = attributes.GetType()
             .ToDictionary(prop => prop.Name, prop => prop.GetValue(attributes, null));
            tag.MergeAttributes(dictionary, replaceExisting: true);
        return new HtmlString(tag.ToString(TagRenderMode.SelfClosing));

    private static string GetInputTypeString(InputType inputType) {
        if (!Enum.IsDefined(typeof(InputType), inputType)) {
            inputType = InputType.Text;
        return inputType.ToString().Replace('_', '-').ToLowerInvariant();


The class is declared as static. This is needed because the helpers are all extension methods on the HtmlHelper class. That means that theyr will appear as additional methods on the WebPage's HtmlHelper property. The enumeration (InutType) is declared to hold values that will be used to identify the type of input that the BuildInputTag method is responsible for constructing. I could pass in simple strings to represent the type of tag to be built, but enumerations are type-safe and prevent typo errors. The GetInputTypeString method is responsible for converting the enum value to its string representation.

The main method is the BuildInputTag method. This is responsible for constructing and outputting the HTML for the input. It uses the TagBuilder class, and piece by piece, builds the tag with any attributes specified. It also sets the "value" by default to a matching value if one is found in the Request.Form collection. This will repopulate form fields in the event, say, of failed validation.

The code above illustrates the Color input helper. The code for all other input helpers is identical except for the InputType value passed to the BuildInputTag method and obviously, the name of the method. For example, this is the Url method:

public static IHtmlString Url(this HtmlHelper helper, string name, object value = null, object attributes = null) {
    if (name.IsEmpty()) {
        throw new ArgumentException("Value cannot be null or an empty string.", "name");
    return BuildInputTag(name, InputType.Url, value, attributes);

The download that accompanies this article includes methods for all other HTML5 input types. The helpers are saved in a C# class file called Html5Extensions.cs in the App_Code folder.

You use the helpers in largely the same way as the existing form helpers: start typing @Html. and the new extension methods will be available in IntelliSense. The blue downward-pointing arrow next to the pink cube denotes that the method is an extension method:

The following snippet shows a number of the helpers being used with some of the new HTML5 attributes

<form method="post">
    @Html.Email("email", attributes: new {required = "required"})
    <div>Date Time</div>
    @Html.Number("number", attributes: new { min=5, max=100, step=5 })
    @Html.Search("search", attributes: new { placeholder = "Enter Search Term" })
    <div><input type="submit" /></div>

Different browsers offer differing levels of support for these, and where they do offer support for a particular inut type, they may render them in different ways:

The required attribute specifies that the field is mandatory, and browsers may prevent form submission if no value is provided:

The balloons or callouts in the above image belong to the browser. They have not been invoked using any client-side code or libraries.

You can also see the placeholder attribute working in all browsers except IE9. It provides a default value for the textbox, which disappears when you click into it to start typing. It reappears if you move the focus away without typing anything into the textbox. The default text does not get posted if the form is submitted. You have to use JavaScript to achieve this within an HTML 4.1 or XHTML 1.0 document.

The min, max and step attributes have been applied to the Number input. The Number input is represented as a spinner control in Chrome, Opera and Safari. It will restrict the range of values that can be selected, and will ensure that they are only available in steps of 5 in this particular example.

While HTML5 controls include built-in validation support, you should not rely on that any more than you can rely on client-side Javascript validation currently. Ignoring the fact that not all browsers support these new attributes or input types, where they are supported, the values can be altered or even removed very easily using the developer tools that come with most browsers these days. Server-side validation works with these helpers in exactly the same way as with the built-in form helpers:

        Validator.Required("You must provide an email address"),
        "Invalid format for an email address")
        if (!Validation.IsValid()) {
            ModelState.AddFormError("There are some errors with your submission"); 

<!DOCTYPE html>

<html lang="en">
        <meta charset="utf-8" />
        <title>My Site's Title</title>
            body{font-family:Arial; font-size:12px; margin-left:20px;}
            div{padding-top: 5px;}
        <form method="post">
            @Html.Email("email", attributes: new {required = "required"})
            <div>Date Time</div>
            @Html.Number("number", attributes: new { min=5, max=100, step=5 })
            @Html.Search("search", attributes: new { placeholder = "Enter Search Term" })
            <div><input type="submit" /></div>

Server-side validation will kick in on the two browsers that do not support the HTML5 required attribute:

HTML5 support among browsers is growing rapidly - especially in the mobile browser space. If you are working predominantly with HTML5, I hope these form helpers will be useful. If you are not there yet, the article should give you a good idea about how to create your own helpers to work with WebMatrix.

A repo containing the complete code for this article is available at GitHub.


Date Posted:
Last Updated:
Posted by:
Total Views to date: 31255


- Aditya

Useful article.

- sudesh kumar chhipa

Thanks for this article

- Sagar Pokhrel

Useful and nice read. Get the content really helping. :)

- saeb panahifar

thanks for nice article

- Jonathan Comer

Very well written and nicely explained. Should be very useful for my next project.
Add your comment

If you have any comments to make about this article, please use this form to do so. Make sure that your comment relates specifically to the article above. More general comments can be posted through the form on the Contact page.

Please note, all comments are moderated, and I end up deleting quite a lot. The kind of things that will ensure your comment is deleted without ever seeing the light of day are as follows:

  • Requests to fix your code (post a question to instead, please)
  • Gratuitous links to your own site or product
  • Anything abusive or libellous
  • Spam

I do not pass email addresses on to spammers, so a valid one will assist me in responding to you personally if required.

Recent Comments

Senad Mustafa 3/31/2015 8:57 AM
In response to ASP.NET MVC DropDownLists - Multiple Selection and Enum Support
Hi Mike, Thanks for the articles on dropdownlists. They are really great but I think you are one...

Black 3/28/2015 4:02 AM
In response to Displaying One-To-Many Relationships with Nested Repeaters
it's working. thank for the code...

Lorenzo 3/26/2015 8:21 AM
In response to iTextSharp - Introducing Tables
Hi Mike How can I add padding to all cells in the table? Kind Regards Lorenzo...

Satyabrata Mohapatra 3/25/2015 8:11 AM
In response to How To Send Email In ASP.NET MVC
Great article. Simple and up to the point....

Afzaal Ahmad Zeeshan 3/24/2015 8:17 PM
In response to How To Send Email In ASP.NET MVC
A great way to teach the MVC framework for sending the emails... Also, what I found helpful was the...

Jim H 3/24/2015 2:32 PM
In response to Migrating From Razor Web Pages To ASP.NET MVC 5 - Model Binding And Forms
Thank you. This helps....

wazz 3/22/2015 5:48 AM
In response to Posting Data With jQuery AJAX In ASP.NET Razor Web Pages
great info!!...

rael 3/21/2015 8:53 PM
In response to Getting the identity of the most recently added record
I spent hours trying to figure how to achieve this in C#. This article helped me. Thanks a lot...

Stephen 3/21/2015 8:48 PM
In response to Ajax with Classic ASP using jQuery
This was very helpful, thanks:)...

patrick voes 3/19/2015 10:19 AM
In response to iTextSharp - Introducing Tables
Thank you! very helpfull....