How to create dynamic XML sitemaps in ASP.NET MVC

When developing web applications (especially websites), some rules have to be obeyed. One of those rules are Sitemaps. Sitemap is an essential to tell more about a website to search engines. According to sitemaps.org, sitemaps are an easy way for webmasters to inform search engines about pages on their sites:

Sitemaps are an easy way for webmasters to inform search engines about pages on their sites that are available for crawling. In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site.

Implement sitemaps in ASP.NET MVC is very easy and this post is going to cover it.

There are several ways to implement sitemaps in ASP.NET MVC. Since sitemaps are just XML files, they can be generated using XLINQ (LINQ to XML) technology.

The process of creating a sitemap in a website can be divided into the following steps:

  • Get a list of URLs which has to be included in the sitemap.
  • Create the sitemap XML in code.
  • Return the created XML to the user.

Note: You don’t really need to create an actual XML file. All of the process above can be done inside a controller action.

The first step is to get the list of objects we want to create the sitemap based on. In this post, I have a list of categories which have a unique URL based on its ID. So:

public ActionResult SiteMap() {
    var items = categoryService.SelectAll();
}

After that, it’s time to create the XML document. Sitemaps must have a specific format; so, they can recognized by search engines. The following is a valid XML sitemap:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.example.com/</loc>
      <lastmod>2005-01-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
</urlset>

As you know, creating such XML file in LINQ to XML is a very simple task to do:

public ActionResult SiteMap() {
    XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
    const string url = "http://example.com/Category/{0}";
    var items = categoryService.SelectAll();
    var sitemap = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XElement(ns + "urlset",
        from i in items
        select
        new XElement(ns + "url",
            new XElement(ns + "loc", string.Format(url, i.CategoryId)),
            new XElement(ns + "lastmod", String.Format("{0:yyyy-MM-dd}", DateTime.Now)),
            new XElement(ns + "changefreq", "always"),
            new XElement(ns + "priority", "0.5")
    )));
}

As you can see in above code, we’ve simply created an XML file in sitemap format. Now we can return it to the user.

return Content("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + sitemap.ToString(), "text/xml");

Look at the code above. When creating normal actions, we usually return a View or PartialView objects; but, since we’re going to return a content, we use the Content method. Content method requires two arguments. The first argument is the content we’re going to return to the user as string and the second is the content’s MIME type.

Hope it helps.

How to use Entity Framework to connect to a MySQL database

In my previous post I blogged about the importance of choosing the best database platform for your project. As database platforms are usually very expensive and more than 80% of the applications you’re developing are small size, you need to choose an affordable database platform and as I described in my previous post, MySQL is one of the best choices.

There’s no doubt that Microsoft.NET framework is one of the best framework for developing apps no matter what kind of app you’re going to develop. But sometimes you need to use a different database platform. Most of .NET developers are using Microsoft SQL Server as their database back-end. In this post I want to tell you how to connect to a MySQL database and use it alongside Entity Framework.

Note: I am using Microsoft Windows in this post. You cannot use this post’s instructions if you’re using Linux or Mac because as the time of writing this post, Entity Framework cannot be installed and used with Mono Develop or Xamarin Studio.

Getting Started

The first thing you need is obviously MySQL Server. MySQL Server is a service which runs on your machine and enables you to have MySQL functionality and it’s available to download from MySQL download center.

After installing MySQL Server it’s possible to connect to it via Windows Command Prompt but it’s such a pain in the neck! So you need to use something like Microsoft SQL Server Management Studio (SSMS) to connect to your database server. There are bunch of free/open source applications you can use which work like SSMS. For example, phpMyAdmin is a free tool you can use to access your MySQL database on the web. But I recommend you to use MySQL Workbench!

MySQL Workbench is a unified visual tool for database architects, developers, and DBAs. MySQL Workbench provides data modeling, SQL development, and comprehensive administration tools for server configuration, user administration, backup, and much more. MySQL Workbench is available on Windows, Linux and Mac OS X.

It’s very cool and easy to use tool to connect to your MySQL database and it can be downloaded from here.

Now it’s possible to just connect to your database by using MySQL Workbench and then create you first database. While this post is not going to cover T-SQL stuff, I assume that you know T-SQL enough as you can create a database named “test”, a table named “test_table” with two columns as shown below in it:

My SQL Workbench table scheme

Also add a new record with id of “1” and name of “It works!” to the table you’ve just created so we can test whether we’re connect to the database or not.

Now your database is ready. The next step is to make Visual Studio ready as well! In order to connect to a MySQL database, you’ll need to install two things:

  1. MySQL connector for Visual Studio: This is the main library to access MySQL from Visual Studio. Even if you’re not going to use Entity Framework, you need to install this component.
  2. MySQL for Visual Studio: It’s a Visual Studio plugin that has to be installed when want to connect to a MySQL database via Entity Framework.

After installing MySQL tools for Visual Studio, it’s time to launch Visual Studio and create a console application and call it mySqlTest.

After new application created, right-click on your project in Solution Explorer, point to Add and select New Item. In the window appears, select “ADO.NET Entity Data Model” from the list,change the name to “DataModel.edmx” and click Add as shown below:

Select ADO.NET Entity Data Model

By clicking Add button, Entity Data Model Wizard will be opened:

Entity Data Model Wizard

Select “Generate from database” and click next. A new window will be opened and ask you for the database connection.

This is the most important part of connecting to a MySQL database. Click on “New Connection” button. The “Connection Properties” page will be open to ask you the server name you’re going to connect to. The first field in the Connection Properties page is the data source. By default data source field is set to “Microsoft SQL Server (SqlClient)” but to connect to a MySQL database, you need to change it; so, click on “Change” button. By clicking the “Change” button, “Change Data Source” Window will be appeared:

changedatasourcepage

Select “MySQL Database” and then click “OK”. When “OK” is clicked, a new window will be opened to ask you about your database credentials which has 3 major fields.

The first field is “Server name”. If MySQL is installed on your local machine, just type “localhost” in the “Server name” field. The next two fields are database username and password. These fields are required to connect to your database. After filling all 3 fields, click “Test Connection” to see if everything is OK and the click “OK”. As a result, Visual Studio creates the connection string for you. just click “Next”.

The next window asks about the database objects you’re going to add to the data model. As we have only one table “test_table”, just check Tables node and click “Finish”.

You’re almost done! Now open “program.cs” file and add the following lines of codes to the main function:

DataModelEntities db = new DataModelEntities();
Console.WriteLine(db.test_table.First().name);
Console.ReadLine();

Now run the app by pressing F5. If everything is correct, you must see the following:

mysqlConnected_Test

Now you app is connected to a MySQL server via Entity Framework. You can now add,edit,delete or do anything else using entity framework.

Hope it helps

Choosing the best database platform for your project

Choosing the best platforms which covers all of your project’s needs is one of the most important tasks to do before starting every project. You have a very important decision to make because it’s the platform you’re going to work with until end of project. Many decisions need to be made before getting started but this post covers one of them; the database!

Beside operating system, database platform is the most expensive part of your project. Some of the databases’ licenses are very expensive. For example, if you take a look at Microsoft SQL Server pricing page you will notice that the enterprise edition of SQL Server 2012 price is $6,874 per core! Which means, if you want SQL Server to use all of your server’s resources and assume that your server has a four-core processor, you’ll have to pay about $27,496 which is seriously expensive.

Unfortunately, In my country (Iran), most of developers don’t care about pricing because the lake of copyright. A few month ago, I saw a web server in Iran which had SQL Server 2012 Data Center edition without paying ever $1! Most Iranian developers prefer to use SQL Server in their projects because of three main reasons:

  • .NET Framework is very very popular among Iranian developers. It’s also very easy to learn.
  • Pricing/Licensing is not important due to the lake of copyright.
  • SQL Server is integrated with Microsoft technologies like .NET. As a result, it’s the easiest choice for .NET developers.

Anyway and beside pricing/licensing, choosing a database platform depends on lots of things. Here are some:

Size of your application

Unfortunately, some developers don’t care about it often. The want the best for all of their solutions. For instance, a while ago, I saw a personal website which was using SQL Server 2008 Enterprise edition as its database back-end. It’s obvious that a personal website doesn’t need a database this big! However, if you’re developing a large application such as banking and accounting apps you will need to use a powerful database. My previous blog was using XML as data source. It was enough for my website and I never felt I need more. If you think you want more than XML, you can try using SQLite or MySQL which are both free. SQL Server also has an Express edition which is free too.

Your server’s hardware configuration

Believe me, there’s no need to install a very heavy database platform on a server with only 1 GB of RAM! While Enterprise editions have the most, they use more resources as well. For example, if you’re using a VPS with only 2 GB or RAM and a single core of CPU to host your website, you should not install Oracle Enterprise edition. It slows down your server so other calculations will get slow too.

Your server’s OS

Another important things to consider is the server’s operating system. Some of database platforms are cross-platform (which means they can be installed on any operating system) and some are not! For example, Microsoft SQL Server can be only installed on Windows and you cannot install it on other operating systems like Linux or Mac whereas Oracle is cross-platform. You can design and implement your database on a windows machine and then deploy it on a Unix server which is pretty cool.

Conclusion

Choosing a database platform is very important before starting a project. There are many factors you should consider while choosing a database platform. More than 80% of websites and applications are small-sized; therefore, you should not use heavy and expensive databases. I believe MySQL is the best choice. It’s open-source, free and highly scalable. It covers all of my needs and it can be installed on any server no matter what operation system is installed.

I think you should reconsider about the database you’re using and change it if you think it’s more than you want ASAP before it gets too late.

Simple but useful: Gravatar Html Helper for ASP.NET MVC

To be honest, I’m a big fan of Globally Recognized Avatar (aka Gravatar). As you may know, this company has been acquired by WordPress recently. Here’s the description of Gravatar, if you don’t know about it:

Your Gravatar is an image that follows you from site to site appearing beside your name when you do things like comment or post on a blog. Avatars help identify your posts on blogs and web forums, so why not on any site?

This service is getting more and more popular every day. Most developers around the world are using this service in their project especially in comment sections; when people comment on a post, news, and etcetera.

Some of these websites are developed using ASP.NET MVC these days; and, in this post I want to show you a very easy way to use this service in your ASP.NET MVC applications.

The first time I decided to use this service in one of my project, I developed a very lightweight class library which contains a MVC HTML helper that returns a HTML image element. You can use this helper wherever you want. In order to use this library just follow these steps:

  1. Add Reference the library (You can download it using the link at the bottom of this post).
  2. Use the “using” statement at the top of the view you want to use this helper to tell the MVC view engine to recognize this helper. The helper is in “MMR.Web.Mvc.Gravatar” namespace:
  3. Simply use @Html.Gravatar(“[email address]”) helper to display your Gravatar.

It’s that simple!

This Gravatar helper accepts three more optional parameters for more customizations stuff:

  • Size: this parameter indicates the size of requested avatar in pixels. The default value for this parameter is 48.
    Note: Gravatar images are square images. So whatever size you select will be applied to both width and height of the image.
  • CssClass: The CSS class for the image element for more flexibility. The default value is “” means no class is applied to the image.
  • Secure: This parameter is very cool! If you’re running your application under SSL protocol, you can turn this option on and the request will be sent to Gravatar server securely.

You can download the compiled version here: MMR.Web.Mvc.Gravatar.zip (2.45 kb)

If you have any question regarding this library, don’t hesitate a moment and ask it in the comments section.

Hope it helps.

Creating multi-language websites – managing dates

I am currently work on a project which has many DateTime fields in its database that needs to be shown to the end-user; but, in a correct format. Unfortunately, most websites, which I have visited lately, didn’t manage date formats. For instance, if the website’s current language is Persian, the date format should be different. Persians are using Shamsi calendar notwithstanding the fact that Gregorian calendar is used by many other countries including England and United States. So, if the user changed the website’s language to another, which has special calendar (Like Persian), date formats also have to be changed.

There are several ways to manage this issue; but, here is my opinion:

Scenario

I have a website which supports two languages: English and Persian. When the user changed the website’s language to Persian, all dates in that website have to be changed to Shamsi; also, if the user switched back to English, dates must be shown in Gregorian format.

Note: My database stores all dates in datetime fields; so, if you want to use this solution in your own applications, you have to do the same thing. I say this because I have seen some developers who are storing dates in integer data types or some others who store Persian dates instead of standards dates in their databases.

The solution

Since extension methods were introduced by Microsoft, I have used them in nearly all of my projects to achieve different kinds of approaches. I just love them because they give me ability to extend .NET APIs and classes in just the way I want. As a result, I preferred using them in this solution too.

The first thing you need is a method for converting Gregorian dates to Persian. As you know, this would be a very simple method:

private static string ConvertToPersian(DateTime dt) {
    var pc = new PersianCalendar();
return string.Format("{0}/{1}/{2}", pc.GetYear(dt), pc.GetMonth(dt).ToString("00"), pc.GetDayOfMonth(dt).ToString("00")); }

Then, you need to create an extension method for DateTime object. I will name it “Localized” because what this method does, is converting the specified date to the correct format according to the website’s language:

public static string Localized(this DateTime dt) {
    var currentCulture = Thread.CurrentThread.CurrentCulture;
if (currentCulture.Name.Equals("fa-IR", StringComparison.OrdinalIgnoreCase)) { return ConvertToPersian(dt); } else { return dt.ToShortDateString(); } }

As you can see in the above code, the website’s current culture has been retrieved from System.Threading.Thread.CurrentThread.CurrentCulture property; consequently, as the above code, you can get the website’s current language and return the correct format of date.

After the implementation of this extension method in an application, the “Localized” method can be accessed in all DateTime objects. The following example demonstrates the use of this method:

static void Main(string[] args) {
    Console.WriteLine("English date: {0}", DateTime.Now.Localized());

// Changing system language to persian. var culture = new CultureInfo("fa-IR"); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; Console.WriteLine("Persian date: {0}", DateTime.Now.Localized()); Console.ReadLine(); }

And the result would be something like this:

LocalizedMethodSample

 

Hope it helps.

How to create a dynamic object in C# to manage QueryStrings

One of the most important features in C# 4 is Dynamic types that enable you to create dynamic objects. The following is the definition of dynamic types from MSDN:

Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation. Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. However, if the code is not valid, errors are caught at run time.

Unfortunately, after about 2 years from Visual Studio 2010 and C# 4 release, most of C# developers don’t know how to use this feature! This is sad because I think dynamic types are one of the most useful features introduced in C# 4. In this post I’m going to show you a very simple use-case of Dynamic types:

As you know, getting a QueryString parameter is very easy in .NET. You can simply use Requst.QueryString[“{ParameterKey}”] to get the value of a QueryString parameter. By calling Request.QueryString, .NET looks for a QueryString item and returns the value of it if the key is available; otherwise, it’ll return null string.

With C#’s Dynamic feature, you create a class to access the QueryString parameter like the following:

QueryString.{ParameterKey};

To achieve this, you need to create a new QueryString class; and this class must inherit System.Dynamic.DynamicObject class. DynamicObject class is an abstract class and all of the objects with Dynamic functionality must inherit this class.

DynamicObject class has some methods that you can override in order get, set and delete Dynamic values. In this example I’m going to use “TryGetMember” method to get the value of a QueryString parameter.

TryGetMember method provides the implementation for operations that get member values. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as getting a value for a property.

TryGetMember method has two parameters. The first one is “binder” and the second is “result”. The following is definition of each parameter by MSDN.

Binder:

Binder parameter provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the DynamicObject class, binder.Name returns “SampleProperty”.

Result:

Result parameter provides the result of the get operation. For example, if the method is called for a property, you can assign the property value to result.

So everything is very simple now! You can get a QueryString parameter using a Dynamic object. The following is the implementation:

public class DynamicQueryString : DynamicObject {
        public override bool TryGetMember(GetMemberBinder binder, 
        out object result) {
            var queryValue = string.Empty;
            queryValue = 
            HttpContext.Current.Request.QueryString[binder.Name];
            result = 
            string.IsNullOrEmpty(queryValue) ? string.Empty : queryValue;
            return true;
        }
 }

Now your Dynamic class is ready to use. You can use this class in a variety of ways but here’s what I prefer:

public class MyPage : System.Web.UI.Page {
        public dynamic QueryString {
            get { return new DynamicQueryString(); }
        }
}

All of my pages in my ASP.NET Web Forms application are inherited to this class so I easily can use my dynamic property. Below showing a page that inherits MyPage class and gets the QueryString parameter ID using dynamic types:

public class Default : MyPage {
    protected void Page_Load(object sender, EventArgs e) {
        Response.Write(this.QueryString.ID);
    }
}

Hope it helps.

Quick post: How to access an action in different areas in ASP.NET MVC

Sometimes I like to post about something, but that thing is very simple and can be described in one or two paragraphs. Previously, I preferred not to post these kinds of things as a blog post but recently, I decided to post almost anything in my blog no matter how many characters they are. So here you go!

When developing an ASP.NET MVC 3 application, you may want to partition your application into different areas for any kinds of reasons:

The MVC pattern separates the model (data) logic of an application from its presentation logic and business logic. In ASP.NET MVC, this logical separation is also implemented physically in the project structure, where controllers and views are kept in folders that use naming conventions to define relationships. This structure supports the needs of most Web applications.

However, some applications can have a large number of controllers, and each controller can be associated with several views. For these types of applications, the default ASP.NET MVC project structure can become unwieldy.

To accommodate large projects, ASP.NET MVC lets you partition Web applications into smaller units that are referred to as areas. Areas provide a way to separate a large MVC Web application into smaller functional groupings. An area is effectively an MVC structure inside an application. An application could contain several MVC structures (areas).

For more about MVC areas, check this out: http://msdn.microsoft.com/en-us/library/ee671793/

When want to develop a web application using MVC, you probably need to access actions/partial views from different areas. For example: You need to have an ActionLink to access the login action in Admin area. In order to do so, you simply need to add a RouteAttribute to your ActionLink as following:

@Html.Action("LoginStatus", "Users", new { area = "Admin" })

If you want to access root area, all you need to do is to set the area name to String.Empty:

@Html.Action("LoginStatus", "Users", new { area = "" })

Hope it helps.

Using SyndicationFeed class to create and read RSS/Atom feeds

Feeds are one of the most important elements in every website out there. One of the main ways to make your website’s contents shareable is to use these kinds of feeds. It also one of the feature I prefer to add in my entire website projects.

Creating and reading RSS/Atom feeds in .NET Framework have a lot of ways of implementations. Some folks are using XLINQ and some using XmlWriter or XmlReader. One of the most popular ways to create RSS feeds is the following:

protected void Page_Load(object sender, EventArgs e)
{
  // Clear any previous output from the buffer
  Response.Clear();
  Response.ContentType = "text/xml";
  XmlTextWriter feedWriter 
    = new XmlTextWriter(Response.OutputStream, Encoding.UTF8);

  feedWriter.WriteStartDocument();

  // These are RSS Tags
  feedWriter.WriteStartElement("rss");
  feedWriter.WriteAttributeString("version", "2.0");

  feedWriter.WriteStartElement("channel");
  feedWriter.WriteElementString("title", "Daily Coding");
  feedWriter.WriteElementString("link", "http://www.dailycoding.com");
  feedWriter.WriteElementString("description", "Daily Coding");
  feedWriter.WriteElementString("copyright", 
    "Copyright 2008 dailycoding.com. All rights reserved.");
 
  // Get list of 20 most recent posts
  PostList posts = PostList.GetTopPostList(AppGlobals.MainArgs, 20);

  // Write all Posts in the rss feed
  foreach(PostInfo post in posts)
  {
    feedWriter.WriteStartElement("item");
    feedWriter.WriteElementString("title", post.Title);
    feedWriter.WriteElementString("description", post.PostHtml);
    feedWriter.WriteElementString("link", 
      UrlHelper.GetShowPostUrl(this, post.Name));
    feedWriter.WriteElementString("pubDate",
      post.DatePosted.ToString());
    feedWriter.WriteEndElement();
  }

  // Close all open tags tags
  feedWriter.WriteEndElement();
  feedWriter.WriteEndElement();
  feedWriter.WriteEndDocument();  
  feedWriter.Flush();
  feedWriter.Close();

  Response.End();
}

Here’s the original post for the code snippet above: http://www.dailycoding.com/Posts/create_rss_feed_programatically_from_data_in_c/

But maybe we should change the way we create and read these feeds.

In .NET Framework 3.5, Microsoft introduced a new class named SyndicationFeed! This class is in System.ServiceModel namespace so you should add a reference to this assembly in order to make use of SyndicationFeed class.

SyndicationFeed Represents a top-level feed object, <feed> in Atom 1.0 and <rss> in RSS 2.0.

Using SyndicationFeed:

In order to get data from a RSS link, you just need to create an instance of SyndicationFeed class.

If you want to create a new feed to publish, just create a default instance of the class; otherwise, you need to use SyndicationFeed.Load static method to load data from a link:

When the SyndicationFeed object filled, you can make use of its properties and methods to get any kind of data you want from specified feed. Here’s an example of creating a list that represents last 5 RSS feed items in a page:

SyndicationFeed feedReader = 
SyndicationFeed.Load("http://ramezanpour.net/syndication.axd"); @foreach (var item in feedReader.GetFeed().Items.Take(5)) { <div> <strong>
<a href="@item.Links[0].Uri.OriginalString">@item.Title.Text</a></strong> <p>@Html.Raw(item.Summary.Text)</p> </div> }

Hope it helps.

Introducing an awesome asyc file uploader, “ManageMedia”

Yesterday, one of my best friends, Omid Mafakher, called and told me about one of his project which he’s working on for a while and as I checked it out, realized that this is so cool so I decided to share it with you too.

I know there are some Asyc File Uploaders available right now like AjaxControlTookit.AsycUploader and such but this control is something different! Actually, you may have seen such a thing on a few websites like Google and Facebook!

ManageMedia Snapshot

Besides, there are lots of useful features in this library as well like image resizing, watermark, background and foreground settings, etc.

Here’s the list of key features:

  • Upload file up to any size in .NET.
  • Validate the file (size, type) before uploading.
  • Upload with progress (Size, Speed, Time, Total Size, etc.)
  • Upload to temp file during upload.
  • Save uploaded file with too many configurations.
  • Manage the Image file and save in any format (PNG, JPG, GIF, BMP, etc.)
  • Save image in any size.
  • Resizing styles: "Center, Tile, Stretch, Zoom, CenterIfNoZoom, Corp (Facebook style)".
  • Set the Background and Foreground in your image.
  • Change the image Alpha and Resolution.
  • HttpHandler for generating images.
  • HttpModule for generating unsaved or deleted images.
  • web.config Section for Multiple settings to save file and image.
  • web.config Section to manage HttpHandler and HttpModule.

Fortunately, my friend has published it in CodePlex as an open source project so you can enjoy using it for free! You can click the link below to access and download this library from CodePlex:

http://managemedia.codeplex.com/

I highly recommend you to check this out! And comment your feedback here or in its official CodePlex page.

Hope you like it.

Implementation of HTML 5 number input in ASP.NET web forms

As I mentioned in my previous post, HTML 5 and CSS 3 are rocking and most of web developers are trying to upgrade their project to HTML5 because it makes their life easier and Microsoft has done a great job by adding HTML5 intellisense to Visual Studio 2010 SP1.

Everything works great in ASP.NET MVC and ASP.NET Web Pages project but when it comes to ASP.NET web forms, you may have some problems using HTML5 tags in your application and access them from runtime. You can’t use the following:

<input type="number" runat="server" />

Yesterday, I was trying to use HTML5 number input tag in my application and found out that ASP.NET web forms engine doesn’t support HTML5 new elements so I decided to write my own NumberTextBox control in order to do so and in this post I’m going to share it with you.

As you know, when want to develop an ASP.NET custom server control, you have to inherit your control’s class to System.Web.UI.WebControls.WebControl; and in this case, I implemented IPostBackDataHandler because it’s a necessary interface when your control is going to process during post backs.

public class NumberTextBox : WebControl, IPostBackDataHandler

The second is to add a “Value” property to the class in order to get and set the value of control which is very easy task to do.

public int Value
{
    get
    {
        if (Page.IsPostBack)
        {
            try
            {
                ViewState["Value"] = Page.Request.Form[this.UniqueID];
            }
            catch { ViewState["Value"] = 0; }
            return Convert.ToInt32(Page.Request.Form[this.UniqueID]);
        }
        if (ViewState["Value"] == null) return 0;
        return (int)ViewState["Value"];
    }
    set { ViewState["Value"] = value; }
}

There are a few things to consider while adding the value property:

  • The property must return value from Page.Request.Form[“Control ID”] because all HTML controls send data via HTTP headers (or QueryString) in Postbacks; so the only way to get the value which is entered by user in post back is using Page.Request.Form[“Control ID”].
  • You should use ViewState in order save the current value of control over posts backs. It’s very common among Visual Studio Controls. As I checked, TextBox control is also use this way to save that data. The third is the implementation of IPostBackDataHandler:
public event EventHandler TextChanged;

public bool LoadPostData(string postDataKey, 
System.Collections.Specialized.NameValueCollection postCollection)
{
    string currentValue = this.Value.ToString();
    string postedValue = postCollection[postDataKey];
    if (currentValue == null && !currentValue.Equals(postedValue))
    {
        this.Value = Convert.ToInt32(postedValue);
        return true;
    }
    else
        return false;
}

public void RaisePostDataChangedEvent()
{
    OnTextChanged(EventArgs.Empty);
}

public virtual void OnTextChanged(EventArgs e)
{
    if (TextChanged != null)
        TextChanged(this, e);
}

The last thing to do is to render the control:

protected override void RenderContents(System.Web.UI.HtmlTextWriter w)
{
    w.Write(
        "<input type=\"number\" id=\"{0}\" name=\"{0}\" value=\"{1}\" />", 
        this.UniqueID, this.Value.ToString());
}

As you can see I use HTML5 features.

Now you can add your custom server control to your application:

<cc1:NumberTextBox ID="NumberTextBox1" runat="server" />

And the result would be something like this:
HTML5 number

      By the time, Only Opera and Google Chrome supports up/down arrows functionalities and I really recommend to use

Modernizr

    to make your web app work fine on all browsers.

I also send the source code of this control to help you out. The only thing you need to do is to add this to your project and enjoy:

NumberTextBox.cs (2.02 kb)