Getting started w/ Web Workers

Hello,

I am not even going to discuss as to how long it’s been since I blogged about anything, because, it’s been forever. But here I am with a new post! This is about html 5 web workers and I should agree that it’s quite exciting to use web workers! In this post I am going to show a pretty simple web worker that calculates how long a user was on a certain page. Let’s see how far I can get w/ this!

Initial requirements are simple: create a worker script file that displays how long (in seconds) you’ve spent in a page. To do this, I have a simple page as shown below (MVC 4 cshtml):

@{
    ViewBag.Title = "Web Workers";
}

<h2>Web Workers</h2>

<p>
    You've been in this page for <span id="result">0</span> seconds!!
</p>

@Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
    var worker = new Worker('@Url.Content("~/Scripts/timer.js")');
    worker.onmessage = function(event) {
        $('#result').html(event.data);
    };
</script>

Line 13 in the above snippet initializes a new web worker asking it to run the timer.js file. Whenever the worker accomplishes something (spending 1 second in this case), it “posts” a message saying that it did! Here is the timer.js file in its entirety!

var secs = 0;
function timer() {
    setTimeout(function () {
        secs++;
        postMessage(secs);
        timer();
    }, 1000);
}

timer();

In the above script I setup a timer function which uses the setTimeout function to call itself after every second. Before calling itself, it “posts” a message to the parent which is listening for the onmessage event. As indicated in the first snipped, this data is retrieved and using jQuery the corresponding span is updated! Here is the output:

Okay! It works!! But let’s improvise now! The following changes to timer.js starts as seconds and then into minutes! To begin with lets update the html in line 8 to the following:

<p>
    You've been in this page for <span id="result">0 seconds</span>!!
</p>

Then the following update to timer.js takes care of minutes and seconds.

var secs = 0;
function timer() {
    setTimeout(function () {
        secs++;
        var msg = getTimeSpent(secs);
        postMessage(msg);
        timer();
    }, 1000);
}

function getTimeSpent(sec) {
    if (sec < 60) {
        return sec + " seconds";
    }

    var mins = Math.floor(sec / 60);
    var secs = sec % 60;
    return mins + " minutes " + secs + " seconds";
}

timer();

Here is how it would look now:

So, What's next? I could go on w/ hours, minutes & seconds and so on. But I am going to stop here for now! Hope you enjoyed this post!

Happy coding!

Share

Overriding the Private Method of a Ruby Class

It feels like forever since I ever posted anything, but, here I am with an interesting post on ruby! Consider the following class which has a private method called “say”.

class Client
   def print
      say
   end

   private
      def say
          "hello"
      end
end

c = Client.new
puts c.print

Let’s assume you are unit testing the Client class and you want to override the say. But, why would you want to override the said method? There are numerous reasons – for one, the say method could talk to a web service to get some data to be used by one of the public methods. For unit tests, it’s better to have some predictable data rather than have something that would change quite often, rendering the unit tests useless!

So, under the assumption that the data will always be available using a specific format we can override this private method as shown below:

class Client
    def self.print
       new.print
    end

    def print
       say
    end

    private
        def say
           "hello"
        end
end

c = Client.new
puts c.print

puts "=========="

k = Class.new(Client) do
    define_method(:say) do
        "hello from an overridden private method"
    end
end

puts k.print

puts "=========="

k_instance = k.new
puts k_instance.print

Since this is not an introduction to ruby classes :) , I am going to make this quick! Lines 21 to 25 are of prime interest. Ruby’s Class.new class method is used to create a new class by passing the class in question – Client. Then using the define_method method I pass in a method name :say and define what it’s supposed to do – in this case return a different string instead of the one defined in the Client class.

That’s it! You can also create an instance of the newly defined class as shown in line 31! Calling the print method would display the following:

hello
==========
hello from an overridden private method
==========
hello from an overridden private method

Line 1 displays what will be printed without any overrides. Line 3 displays what will be printed when the class method is called after the say method is overridden by Class.new returns a new class and line 5 displays the same as line 3, but this time with an instance created using the class returned, again by Class.new

Share

EditPlus: Search & Replace with RegEx

Hello people! It’s been so long since I posted anything here. So here you go! This is going to be a short and sweet post! One of my favorite text editor is EditPlus and this is a way by which you could do a search using a RegEx and also replace it by using RegEx! Here is the scenario. I have an XML file where there are some elements without the end tag. So I wanted to replace them at a single shot instead of doing it numerous times. Remember, this is a 50,000 line file, so you can imagine! Here is the text:

<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO">
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO">
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO">
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO">
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO">

The expected result is (self-closing):

<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO"/>
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO"/>
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO"/>
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO"/>
<SomeElement Code="C198440" StartDateTime="01-04-2014 08:02:00.000" EndDateTime="" Admin="PO"/>

You could use the following process in EditPlus to achieve this!

  • Open the “Replace” dialog by pressing Ctrl + H
  • Enter (<SomeElement)([a-zA-Z0-9 \"=\-\:\.]*)(>) in the “Find what” text box
  • Enter \1\2/> in the “Replace with” text box
  • Press the “Replace All” button! That’s it!!

Pretty cool, isn’t it! Made my life so much easier :) And of course, the regex in the find text box can be simplified, but for now it’s fine! Here is what’s happening… The text entered in “Find what” has 3 groups: first group finds a literal “<SomeElement”, second group matches anything that follows it and the third group matches a literal “>”! The text entered in “Replace with” means this: \1 represents the first matched group, used as it is. \2 is the second matched group, also used as it is. Finally a literal “/>” to get the desired XML! Hope you had fun learning something interesting about EditPlus!

Share

JsFiddle: Something that would be really useful!

To begin with, let me say I love jsfiddle! In case you are not aware of jsfiddle, its a site where you could quickly test out your javascript, instead of creating a page to do the same locally! I have hundreds of fiddles and my manager always asks me how much I cost them :) One feature I tend to use a number of times is the “External Resources” tab, where I add a number of other additional .js files from various CDN’s. cdnjs.com is my go to place for a number of scripts and I am not sure if such another place exists!

External Resources tab

Here is what I am thinking should be available:

If a jsfiddle user types in (say) cdnjs: underscorejs in the text box within “External Resources” and press the tab key, the cdn url for underscore.js will be automatically added to the list of external sources! How cool would that be?

I think if this is possible it would be really cool ( I know it is ;) )! What do you people think :) ?

Update: Found out about codepen.io, which kind of does this, hoping to see this in jsfiddle soon!

Happy coding!

Share

Ninject: Passing dynamic parameters to the constructor

Hello poeple!

Been a really long time since I posted anything. But, here you go! This is a very interesting snippet about passing dynamic arguments to constructor that will be injected to a controller (say), using ninject. When you register a dependency in ninject, you do the following:

kernel.Bind<IData>().To<Data>();

Whereas, if you also want to pass a parameter to the construction of Data, you would do the following:

kernel.Bind<IData>().To<Data>().WithConstructorArgument("collectionName", "SomeValue");

But what if the value for collectionName changes based on various conditions, like in my case? Obviously, there is a way! You can pass callbacks to the WithConstructorArgument method, as shown below:

    public static class NinjectWebCommon
    {
	    // -- Snip --

        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IData>().To<Data>().WithConstructorArgument("collectionName", GetConstructorArgFromSession);
        }

        private static object GetConstructorArgFromSession(IContext context)
        {
            var httpContext = context.Kernel.Get<HttpContextBase>();
            if (httpContext != null && httpContext.Session != null)
            {
                var arg = httpContext.Session["Collection_Prefix"];
                if (arg != null && !string.IsNullOrEmpty(arg.ToString()))
                {
                    return arg;
                }
            }
            return null;
        }
    }

In the above snippet, WithConstructorArgument method, apart from the parameter name to be passed to the constructor for Data also takes in a callback. This callback uses the instance of IContext provided to get an instance of the HttpContextBase using which you could get the Session property as shown above. After getting the http context, it is now straight forward to access the Session and get the value I am looking for. This is now passed to the constructor of the Data class, when an instance is created by ninject!

That’s all for this post and hope you learnt something new about ninject, just like me! If at all I have more findings regarding this, I will update the article!

Happy coding!

Share

Announcing Db-Status-Provider NuGet Package – My first!

Hello People,

This is not a blog post per se, but just an announcement! I released my first nuget package yesterday! I have named it DbStatusProvider and as the name implies this package can be used to keep track of the status of your application’s database. I got the idea for this project from my open source project sBlog.Net!

To install this package launch the nuget package manager and enter the following command:

PM> Install-Package DbStatusProvider

Here is the github project page for this package. This page contains complete instructions on how to use this package. This is the package’s information page in the nuget site!

Hope you like this package and do let me know your questions/comments in github or here! Have fun!

Share

Fun With Generics 2: Comparables, Comparers, Sorted Sets

Hello People!

Yet another post in the fun with generics series. I am just trying to refresh stuff I already know and stuff I may have forgotten, also in the process also getting to know new stuff! In this post I am experimenting with IComparer<T>, IComparable<T> and SortedSet<T>. Before I get to the fun part, let me briefly explain the 2 interfaces I am going to use:

IComparable<T> is an interface that an object can implement in order to compare itself against another instance of the same type and return whether one object is “smaller” (-1) than the other, or “equal” (0) or is “greater” (1) to the other. Whereas, IComparer<T> is an interface thats expects us to implement a method that can compare 2 instances and return the same result as before. Native types like int already provides a CompareTo method and I am going to leverage this for the examples in this post!

To begin with, here is a class called User that implements the IComparable<T> interface.

    public class User : IComparable<User>
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string EmailAddress { get; set; }

        public int CompareTo(User other)
        {
            if (other == null)
                throw new Exception("Cannot compare with a null object");

            return UserId.CompareTo(other.UserId);
        }
    }

Notice how the Compare method uses int.CompareTo to see whether an instance is “smaller”, “equal” or “greater”! Now let me show how I could utilize the IComparer<T> interface. In this case, I am creating a UserComparer that can be used to sort a List<User> instance.

    public class UserComparer : IComparer<User>
    {
        public int Compare(User x, User y)
        {
            if (x == null || y == null)
                throw new Exception("Cannot compare null instances");

            return x.UserId.CompareTo(y.UserId);
        }
    }

Now let me put this UserComparer to use. Consider the following:

        public static void Main(string[] args)
        {
            var users = GetUsers();
            users.ForEach(u => Console.WriteLine(u.UserId + " : " + u.UserName));

            Console.WriteLine("--------------");

            users.Sort(new UserComparer());
            users.ForEach(u => Console.WriteLine(u.UserId + " : " + u.UserName));

            // -- Snip --
        }

        static List<User> GetUsers()
        {
            return new List<User>
                       {
                           new User{ UserId = 11, UserName = "testuser1", EmailAddress = "testuser1@mail.com"},
                           new User{ UserId = 62, UserName = "testuser2", EmailAddress = "testuser2@mail.com"},
                           new User{ UserId = 13, UserName = "testuser3", EmailAddress = "testuser3@mail.com"},
                           new User{ UserId = 42, UserName = "testuser4", EmailAddress = "testuser4@mail.com"},
                           new User{ UserId = 55, UserName = "testuser5", EmailAddress = "testuser5@mail.com"}
                       };
        }

Here is the output for this run:

11 : testuser1
62 : testuser2
13 : testuser3
42 : testuser4
55 : testuser5
--------------
11 : testuser1
13 : testuser3
42 : testuser4
55 : testuser5
62 : testuser2

If you notice in line 8, I have passed an instance of UserComparer, so that the framework can use the UserComparer.Compare method to find if an instance is “smaller”, “equal” or “greater” to another instance and sort it based on that! Okay, but where the implementation of IComparable<User> in the User class come in to the picture? When I use a SortedSet<T>! In the case of a SortedSet<T>, I don’t have to call the Sort method with the UserComparer explicitly! Here is the listing for the same:

        public static void Main(string[] args)
        {
            var users = GetUsers();

	    // -- Snip --

            var sortedSet = new SortedSet<User>();
            users.ForEach(u => sortedSet.Add(u));
            sortedSet.ToList().ForEach(s => Console.WriteLine(s.UserId + " : " + s.UserName));
        }

If you notice in the above snippet, when User objects are added to the SortedList, they are already stored as per the sort order! So there is no need to make an explicit call to Sort! SortedSet<User> uses the User.CompareTo method to sort the instance and put them in the correct position as and when they are added! One of my pet peeve would be why they didn't name this class SortedList as opposed to SortedSet! Of course, there is another class called SortedList but for a different purpose altogether (msdn)!

You can download a sample file here!

Hope you had fun! That's all for now!!

Share

Fun With Generics 1: Equality Comparers

Hello People!

I am back with an interesting post, but this is going to be short. I was bored and was thinking up something and it occurred to me that I could just start playing around with generics :) So I thought I may post a series of entries regarding stuff I get to do. In this first post I am going to show how an equality comparer could be used to filter out distinct elements in a List<T> with duplicates. This post is going to have very little explanations and more of code, we love code right? ;)

To begin with, let me consider a simple Employee class as shown below

public class Employee
{
      public string EmployeeId { get; set; }
      public string EmployeeName { get; set; }
}

And let us consider the following program that lists the entries of a List<Employee> after doing a Distinct().

    // Listing 2
    public class FunWithGenerics1
    {
        public static void Main(string[] args)
        {
            var list = GetEmployees();
            var list2 = list.Distinct().ToList();
            list2.ForEach(l => Console.WriteLine(l.EmployeeId + " : " + l.EmployeeName));
        }

        private static IEnumerable<Employee> GetEmployees()
        {
            return new List<Employee>
                       {
                           new Employee{ EmployeeId = "1", EmployeeName = "name 1"},
                           new Employee{EmployeeId = "2", EmployeeName = "name 2"},
                           new Employee{ EmployeeId = "1", EmployeeName = "name 1"}
                       };
        }
    }

Could you guess the output for this program? It would be:

1 : name 1
2 : name 2
1 : name 1

Not what we expected right? The list still has duplicates! This is because Distinct() uses the default equality comparer to filter and this comparer identifies duplicates based on the object addresses and in that way they are different! Consider the following code segment, this explains the behavior of a default comparer.

   public static void Main(string[] args)
   {
      var e1 = new Employee { EmployeeId = "1", EmployeeName = "test 1" };
      var e2 = new Employee { EmployeeId = "2", EmployeeName = "test 2" };

      // Same object is added twice!
      var list5 = new List<Employee> { e1, e2, e1 }; 

      // This displays the duplicate entry!
      list5.ForEach(l => Console.WriteLine(l.EmployeeId + " : " + l.EmployeeName));

      Console.WriteLine();
      // This won't display the duplicate, since .Distinct() will remove the duplicate e1 instance
      list5.Distinct().ToList().ForEach(l => Console.WriteLine(l.EmployeeId + " : " + l.EmployeeName)); 

      // -- Snip --
   }

The following is the output when the above snippet is ran:

1 : test 1
2 : test 2
1 : test 1

1 : test 1
2 : test 2

In order to filter a list by a property rather than an “address”, we have to create a custom equality comparer by implementing the IEqualityComparer<T>. Given below is a type specific implementation of the same:

    public class EmployeeEqualityComparer : IEqualityComparer<Employee>
    {
        public bool Equals(Employee x, Employee y)
        {
            return x.EmployeeId == y.EmployeeId;
        }

        public int GetHashCode(Employee obj)
        {
            return obj.EmployeeId.GetHashCode();
        }
    }

When using IEqualityComparer<T>, 2 methods have to implemented. The first method is the Equals method, that takes in 2 instances of Employee objects and returns the equality by comparing 2 properties, in this case the employee id. Now if you rewrite the code listing 2 as given below, you will get the desired results with duplicates filtered out!

        public static void Main(string[] args)
        {
            var list = GetEmployees();
            var list2 = list.Distinct(new EmployeeEqualityComparer()).ToList();
            list2.ForEach(l => Console.WriteLine(l.EmployeeId + " : " + l.EmployeeName));

	    // -- Snip --
        }

Here is the output if this snippet is ran:

1 : test 1
2 : test 2

But here comes the fun part. I don’t want to write 100 comparers, right? So here is “generic” version of the comparer. To implement the generic comparer without using reflection and strings for the property to compared, I declare an interface as shown below:

    public interface IComparable
    {
        string PrimaryId { get; set; }
    }

Now, I can create a generic comparer as shown below:

    public class GenericEqualityComparer<T> : IEqualityComparer<T>
        where T : IComparable
    {
        public bool Equals(T x, T y)
        {
            return x.PrimaryId == y.PrimaryId;
        }

        public int GetHashCode(T obj)
        {
            return obj.PrimaryId.GetHashCode();
        }
    }

Now, I have to change my Employee class to implement IComparable:

    public class Employee : IComparable
    {
        public string EmployeeId { get; set; }
        public string EmployeeName { get; set; }

        // Or you could just remove EmployeeId and just have PrimaryId, your choice !
        public string PrimaryId
        {
            get { return EmployeeId; }
            set { EmployeeId = value; }
        }
    }

Now, I can use the generic comparer and can do the same for any other class without having to create a new comparer every time!

        public static void Main(string[] args)
        {
            var list3 = GetEmployees();
            var list4 = list3.Distinct(new GenericEqualityComparer<Employee>()).ToList();
            list4.ForEach(l => Console.WriteLine(l.EmployeeId + " : " + l.EmployeeName));

            // -- Snip --
       }

That’s it for this post! Hope you had fun and here is the complete sample program for your perusal! Happy coding!!!

Share

Custom ConfigSection: An Alternarnative to appSettings

Hello people!

I am back with yet another interesting post about something very interesting in ASP.Net – custon configuration sections. Those of you who are familiar with ASP.Net web development will be aware various sections in web.config such as <appSettings /> and <connectionStrings />. These “sections” are supported ASP.Net itself and thus we are able to use these sections to define custom key/value based settings and connection string for our application!

But, what’s the fun in using stuff only provided to us by default? None, isn’t it? Custom configuration sections are there to provide some fun :) I was experimenting a few things for sBlog.Net and found custom configuration sections good for maintaining a few settings related to the blog, that rarely change, in the web.config, instead of having them in the database. While thinking about it, I thought why not write a post about them and so here I am with the new post!

So, let me get to the point of this post after that short introduction. I am going to show how I created a new “section” called <sblognet /> that could store some of a blog’s settings that rarely change. Here is the new section I have added to my web.config:

  <sblognet smtpAddress="mail.mysite.net"
            smtpPassword="password123"
            emailErrors="true"
            adminEmail="administrator@mysite.net"
            blogTheme="PlainClean">
    <logging enabled="true" />
  </sblognet>

With the help of custom configuration sections, we can create a class that strongly types every attribute or element within the <sblognet /> element! To do this, the first step is to add a new <section /> element within the <configSections /> element in your web.config as shown below:

<configuration>
  <configSections>
    <!-- snip -->
    <section name="sblognet" type="ConfigSectionsSample.Configuration.SblogNetConfiguration, ConfigSectionsSample" />
  </configSections>

  <!-- snip -->
</configuration>

In the above listing, the name attribute specifies the name of our section, which is sblognet. Then the type attribute specifies the fully-qualified namespace of the type that would represent a strongly typed representation of our custom section followed by the assembly that would contain this type in a comma-seperated format. Now that the “wiring” is done, let me show you the class that represents the custom type itself!

    public class SblogNetConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("smtpAddress", DefaultValue = "")]
        public string SmtpAddress
        {
            get { return (string) this["smtpAddress"]; }
            set { this["smtpAddress"] = value; }
        }

        [ConfigurationProperty("smtpPassword", DefaultValue = "")]
        public string SmtpPassword
        {
            get { return (string)this["smtpPassword"]; }
            set { this["smtpPassword"] = value; }
        }

        [ConfigurationProperty("emailErrors", DefaultValue = false)]
        public bool EmailErrors
        {
            get { return (bool)this["emailErrors"]; }
            set { this["emailErrors"] = value; }
        }

        [ConfigurationProperty("blogTheme", DefaultValue = "PerfectBlemish")]
        public string BlogTheme
        {
            get { return (string)this["blogTheme"]; }
            set { this["blogTheme"] = value; }
        }

        [ConfigurationProperty("adminEmail", DefaultValue = "")]
        public string AdminEmail
        {
            get { return (string)this["adminEmail"]; }
            set { this["adminEmail"] = value; }
        }

        // -- snip --
    }

If you observe the listing above for SblogNetConfiguration class, you can immediately notice what’s going on! In listing 1, you noticed that the <sblognet /> element has a number of attributes with the corresponding values. The first attribute/value pair is smtpAddress with the value set to mail.mysite.net. This attribute is represented by the SmtpAddress property in this class, as shown below:

   [ConfigurationProperty("smtpAddress", DefaultValue = "")]
   public string SmtpAddress
   {
       get { return (string) this["smtpAddress"]; }
       set { this["smtpAddress"] = value; }
    }

Note that the property is decorated with the ConfigurationProperty annotation. This implies that this property maps to an attribute name "smtpAddress" in the section named <sblognet />. The get/set methods are pretty straight-forward by which the value in web.config is returned/set. The ConfigurationProperty annotation also has the DefaultValue property that can be used to set a default value, in case this attribute is not present in the <sblognet /> element, in this case I have set it to return an empty string.

Following this property there are other properties that represent other attributes such as smtpPassword, emailErrors, adminEmail, blogTheme and so on.

Remember, every attribute/ element within the custom section should have a corresponding property in your class, if not you will see errors on startup! Yes, I have not covered about “elements” within the custom section, that’s coming up next ;)


Now, obviously you noticed that the class does not contain any definition for the <logging /> element that is contained within the <sblognet /> element. That’s because complex elements like these have to be represented by another class themselves! Given below is the listing the highlights the property that maps to this element alone:

    public class SblogNetConfiguration : ConfigurationSection
    {
        // -- snip --

        [ConfigurationProperty("logging")]
        public LoggingElement Logging
        {
            get { return (LoggingElement) this["logging"]; }
            set { this["logging"] = value; }
        }
    }

Just like the other properties in the class, I have used ConfigurationProperty data annotation, but without the DefaultValue property, implying if not specified we will get a null. Notice the return type of this property – LoggingElement. This is another class that will represent the logging element within our custom section. The listing for this class is given below:

    public class LoggingElement : ConfigurationElement
    {
        [ConfigurationProperty("enabled", DefaultValue = false)]
        public bool Enabled
        {
            get { return (bool) this["enabled"]; }
            set { this["enabled"] = value; }
        }
    }

Note that this class inherits from the ConfigurationElement unlike the previous class, which inherited from the ConfigurationSection class. As the name implies, this class act as a representation of an element within a custom section. At this point, this element contains a single property called Enabled which is represented as shown above and is similar to other properties within the SblogNetConfiguration class! That’s it! You now have a created a custom section just for your application!!!

Let’s see how to put this in to use. Given below is a section from the HomeController class that utilzes this custom section!

    public class HomeController : Controller
    {
        private static readonly SblogNetConfiguration Configuration =
            ConfigurationManager.GetSection("sblognet") as SblogNetConfiguration;

        public ActionResult Index()
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
            ViewData["data"] = Configuration.BlogTheme;
            return View();
        }
    }

The above snippet deserves a very short explanation, even though it’s pretty straight forward. In line 3, I have used ConfigurationMananger.GetSection method provided by ASP.Net to get a reference to the section named “sblognet”. ASP.Net does all the heavy-weight-lifting for us and so we just have to cast it to SblogNetConfiguration. It’s now ready for use, which is proven by line 10 where the BlogTheme property is passed on to the view using ViewData. I am not going to present screenshots or the part where I display it and I am just going to delegate those things to you :)

Hope this post interested you a bit and for the sake of sanity, here is a link download a sample application that implements things explained in this post!

Happy coding!

Share

Custom Metadata Attributes in ASP.Net MVC

Hello! It’s been a long time since I posted anything and trust me it does not feel good :) So here I am with an interesting post! This post discusses about how I put custom metadata attributes in to use for describing static information for a certain field.

I was in a situation where in I have to talk to a WCF service to update certain information. It goes like this:

  • Get a list of items that represents users belonging to different roles
  • Display a view that lists all the users in a grid and let users update them
  • Once the user is done, he/she clicks a button which finalizes the update by sending in all the users for a certain role in a sequence (synchronous)

For this task, I had booleans in order to represent the access for a certain role for a user. This would translate in to check boxes in the view and I didn’t want to ‘n’ number of partial views and model binders by making a simple boolean in to a complex field. The information related to every role is a constant and so I wanted to leverage that! So, I wanted to use the custom metadata feature, but alas, I needed some information on hard-wiring it to the framework. I went googling and found this StackOverflow answer – http://stackoverflow.com/a/5548384/312219! My idea builds on this!

The following classes are straight from the answer referred about so I am not going to detail them! The first class is the abstract class that represents a custom metadata attribute.

    public abstract class MetadataAttribute : Attribute
    {
        public abstract void Process(ModelMetadata modelMetaData);
    }

Then there is a custom model metadata provider shown below:

    public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(
            IEnumerable<Attribute> attributes,
            Type containerType,
            Func<object> modelAccessor,
            Type modelType,
            string propertyName)
        {
            var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
            attributes.OfType<MetadataAttribute>().ToList().ForEach(x => x.Process(modelMetadata));
            return modelMetadata;
        }
    }

Which is associated to the framework as shown below in Global.asax.cs‘s Application_Start method

        protected void Application_Start()
        {
            // -- snip --

            ModelMetadataProviders.Current = new CustomModelMetadataProvider();
        }

Now that we have the wiring done, let me get to the core of this post!

My objective is to create an attribute that could hold a custom value. So I created the CustomValueAttribute class that inherits the MetadataAttribute class as shown below:

    public class CustomValueAttribute : MetadataAttribute
    {
        private readonly int _customValue;

        public CustomValueAttribute(int customValue)
        {
            _customValue = customValue;
        }

        public int CustomValue
        {
            get { return _customValue; }
        }

        public override void Process(ModelMetadata modelMetaData)
        {
            modelMetaData.AdditionalValues.Add("CustomValue", _customValue);
        }
    }

This class could now be used to decorate any property in a class. In my case I am using this attribute to decorate a couple of booleans.

    public class SampleEntry
    {
        public int Id { get; set; }
        public string Name { get; set; }

        [CustomValue(1)]
        public bool UserEnabled { get; set; }
        [CustomValue(2)]
        public bool NewsletterEnabled { get; set; }
    }

If you notice, UserEnabled and NewsletterEnabled are decorated with this attribute. Now, in my case the view handles the responsibility of displaying the checkboxes in a grid and I use a Session to hold all changes to an individual SampleEntry. Ignoring all those nitty gritty details, let me show how I am putting these CustomValueAttribute‘s to use.

Given below is the view model that includes a list of SamepleEntry items:

    public class SampleViewModel
    {
        public List<SampleEntry> Entries { get; set; }
    }

Here is the most interesting part! Given below is the action method that puts the custom attribute to use!

    public class SampleController : Controller
    {
        public ActionResult Index()
        {
            // Assume the view contains a list of "SampleEntry" items
            // Of which we just need the count of items that has "UserEnabled" to be true
            // And "NewsletterEnabled" to be true

            // Thus "UserEnabled" and "NewsletterEnabled" can be simple "checkboxes" in the view!
            // The reasoning is that in my case, the wcf service just needs the "id"'s of items
            // whose values are set to true

            // This would allow easy extensions and remove the necessity for if...else

            var model = GetModel();

            var requiredCustomValues = GetCustomValues();

            var props = typeof (SampleEntry).GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();

            foreach (var requiredCustomValue in requiredCustomValues)
            {
                var list = new List<int>();

                props.ForEach(prop =>
                {
                    var attr = prop.GetCustomAttribute<CustomValueAttribute>();
                    if (attr != null && requiredCustomValue == attr.CustomValue)
                    {

                        foreach (var i in model.Entries)
                        {
                            var value = prop.GetValue(i, null);
                            if ((bool)value)
                            {
                                list.Add(i.Id);
                            }
                        }
                    }
                });

                UpdateValues(list, requiredCustomValue);
            }

            return View();
        }

	// -- Snip --
}

Let me get to the fun part directly. The action method already contains some information on why I do this. GetCustomValues is a method that returns a list of values for which the wcf service expects id’s chosen by the user. In this example, it is just a dummy method that returns 2 integers as shown below:

        private List<int> GetCustomValues()
        {
            return new List<int> { 1,2 };
        }

Line 19 uses reflection to get all the properties of the SampleEntry class. Then as I said earlier for every value in GetCustomValues I loop through the properties that has CustomValue set to the required value and collect the id’s in a list. Finally, I call the UpdateValues method which would call the wcf service to report the selected values. For the sake of this post, this method does nothing:

        private void UpdateValues(List<int> list, int requiredCustomValue)
        {
            // This method would call the wcf service to update the values !!!
        }

I will be correcting this post as necessary, but, I guess you found this post interesting! I have to follow this method so as to not change the wcf service. But if I get a chance to update the service, I could find an easier way to do this!

Happy coding!

Share