I am building events site on ASP.NET MVC 3 and Entity Framework. Today I added tagging support to my site and created simple tag cloud. In this posting I will show you how my tag cloud is implemented. Feel free to use my code if you like it.
To give you better idea about the structure of my classes here is my Entity Framework model. You can see that events and tags have many-to-many relationship defined between them.
In database I have one table between events and tags but as this table contains primary key that is 100% made up of foreign keys of events and tags table then Entity Framework is able to create many-to-many mapping automatically without creating additional object for relation.
You can also see that there is Events navigation property defined for Tag class. It is not good idea to create more navigation paths than you need and in the case of Tag class we need this navigation property.
Tag cloud solution
To create tag cloud we need to go through the following steps:
- Create Tag table and bind it to Event.
- Update your Entity Framework model to reflect new changes made to database.
- Add some classes that hold tag cloud data (TagCloud is container class that keeps collection of MenuTag objects).
- Create extension method to Html class that generates tag cloud.
I started with code I found from Mikesdotnetting blog posting Creating a Tag Cloud using ASP.NET MVC and the Entity Framework and worked out my own solution. Referred posting was great help for me and let’s say thanks to author for sharing his ideas with us.
Tag cloud implementation
As a first thing let’s create the class that holds tag data. I named this class as MenuTag.
public class MenuTag
public string Tag;
public int Count;
Tag is the title of tag and Count shows how many events are tagged with this tag.
Next we need the class that packs everything up and provides us with tag rank calculation. For that I defined class called TagCloud.
public class TagCloud
public int EventsCount;
public List<MenuTag> MenuTags = new List<MenuTag>();
public int GetRankForTag(MenuTag tag)
if (EventsCount == 0)
var result = (tag.Count * 100) / EventsCount;
if (result <= 1)
if (result <= 4)
if (result <= 8)
if (result <= 12)
if (result <= 18)
if (result <= 30)
return result <= 50 ? 7 : 8;
Now we have to add new method to our Entity Framework model that asks data from database and creates us TagCloud object. To add new methods to model I am using partial classes.
public partial class EventsEntities
private IQueryable<Event> ListPublicEvents()
var query = from e in events
where e.PublishDate <= DateTime.Now
orderby e.StartDate descending
public TagCloud GetTagCloud()
var tagCloud = new TagCloud();
tagCloud.EventsCount = ListPublicEvents().Count();
var query = from t in Tags
where t.Events.Count() > 0
select new MenuTag
Tag = t.Title,
Count = t.Events.Count()
tagCloud.MenuTags = query.ToList();
And as a last thing we will define new extension method for Html class.
public static class HtmlExtensions
public static string TagCloud(this HtmlHelper helper)
var output = new StringBuilder();
using (var model = new EventsEntities())
TagCloud tagCloud = model.GetTagCloud();
foreach(MenuTag tag in tagCloud.MenuTags)
And you are almost done. I added my tag cloud to my site master page. This is how what you should write to show tag cloud in your view:
You can also go on and create partial view but then you have to give data to it through your view model because writing code behind views is not a good idea. If you look at my extension method you will see it’s simple and short and that’s why I prefer to keep it this way.
ASP.NET MVC and Entity Framework make it easy to create modern widgets for your site. Just keep as close to ASP.NET MVC framework as you can and orchestrate it with Entity Framework models. In this posting I showed you how to create simple tag cloud component that plays well together with ASP.NET MVC framework. We created some classes where we keep our data. Tag cloud data is coming from Entity Framework model and tag cloud is included in views using Html extension method.