About Jordan

AI/computer science graduate, senior software developer at Tech13 Ltd and web developer. Contact me on jordan@jordanwallwork.co.uk

I have various forms on my application and I wanted to be able to see how much had been filled filled out, so I wrote this helper class that I could use to measure how much of the pages view model had been completed.

It uses reflection to check each of the fields in turn, simply checking whether the field is null or not. It’s a bit rough around the edges, and doesn’t really have a strategy for dealing with nullable data types (it simply ignores them) but it worked, and stopped me needing to write 10 different classes to measure 1 different view models so I was happy! It also ignores fields ending with Id, and the ignore rules can be easily extended. The other thing it does is keep track of any ignored fields, and any that it wasn’t able to count (ie. nullables). I never actually used these lists, but they come in pretty helpful during debugging I find.

public class ViewModelProgressHelper
{
    public static ViewModelProgressReport Process(TModel model)
    {
        var report = new ViewModelProgressReport();
        var fields = model.GetType().GetProperties();
        foreach (var field in fields)
        {
            if (Ignore(field.Name)) report.IgnoredFields.Add(field.Name);
            else if (field.PropertyType.IsGenericType && field.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                report.NumberOfFields++;
                if (field.GetValue(model, null) != null) report.FieldsCompleted++;
            }
            else if (field.PropertyType == typeof(string))
            {
                report.NumberOfFields++;
                if (!string.IsNullOrEmpty((string)field.GetValue(model, null)))
                    report.FieldsCompleted++;
            }
            else if (field.GetValue(model, null) == null)
                report.NumberOfFields++;
            else if (field.PropertyType.IsValueType)
            {
                var defaultValue = Activator.CreateInstance(field.PropertyType);
            }
            else report.UnrecognisedFields.Add(string.Format("{0} ({1})", field.Name, field.GetType().Name));
        }
        return report;
    }

    private static bool Ignore(string name)
    {
        return (name.EndsWith("Id")); // Ignore primary/foreign keys
    }
}

public class ViewModelProgressReport
{
    public ViewModelProgressReport()
    {
        IgnoredFields = new List();
        UnrecognisedFields = new List();
    }
    public int NumberOfFields { get; set; }
    public int FieldsCompleted { get; set; }
    public double Percent { get { return NumberOfFields > 0 ? ((double)FieldsCompleted / NumberOfFields) * 100 : 0; } }
    public List IgnoredFields { get; set; }
    public List UnrecognisedFields { get; set; }
}
UPDATE: With the release of SignalR 4.0, some of the information in the article may be out of date

I recently had to implement an ASP.NET MVC application using long polling to handle asynchronous communication not only from client from server (as you might traditionally do using ajax), but also server to client. I began looking into long polling solutions, and soon stumbled across SignalR, which describes itself as an async signaling library for ASP.NET to help build real-time, multi-user interactive web applications, which was pretty much exactly what I needed!

SignalR is a really brilliant solution. It’s one downfall, however, is the lack of documentation. Scott Hanselman wrote a nice post that gives a nice overview, with a code snippet that shows how easy it can be to use SignalR, but unfortunately there isn’t really much else (except for that one snippet, which seemed to appear everywhere!). Looking through the samples is also helpful, but some things I had to puzzle out on my own, and so I wanted to share some of what I learned. I’m not going to bother giving ‘real world’ type examples, simply show the different types of client/server communication SignalR is capable of, the building blocks. Once you know how to send data/call functions client to server, and vice versa, it really isn’t much of a leap to work out how to put it all together…

So there are two ways to use SignalR: you can access it at a low level by overriding it’s PersistentConnection class, which gives you a lot of control over it; or you can let SignalR do all of the heavy lifting for you, by using the high level ‘Hubs’.

SignalR Hubs

It’s so easy to set up a hub in your application. First, use Nuget to grab SignalR and it’s dependencies. In the root of your application, add a class, MyHub.cs that implements the SignalR class Hub. On your page, include jQuery and jquery.signalR, and then:

<script type="text/javascript" src="/signalr/hubs"></script><script type="text/javascript">// <![CDATA[
       $(function() {           var myConnection = $.connection.myHub;           $.connection.hub.start();       });
// ]]></script>

Rather awesomely, this is all you need to do to establish a connection between the client and server, which you can see if you crack open firebug. You’ll also notice that /signalr/hubs doesn’t actually exist in your project, which Resharper won’t like! This is really neat, as the hubs javascript is autogenerated by SignalR. Whilst we might have a connection established, it currently does nothing. Time to add some functionality.

Calling Server-side Functions from the Client

Everything with SignalR is basic, but this is probably the most basic of all. All you need to do is create the method in MyHub.cs, and then in your javascript simply call:

myConnection.voidFunction();

That really is it! If you build the solution and go to the source of /signalr/hubs, you’ll notice that it has been updated to include the new method. To pass some data, simply add values as you would in any other function:

myConnection.voidFunctionWithParams(1, "a string");

The methods don’t have to be void either. Say you have a function Increment:

public int Increment(int input) {
    return input++;
}

You call it simply by:

connection.returnInt(0)
          .done(function (returnedVal) {
              // Handle returned val (in this case, returnedVal = 1)
          });

As well as simple data types, you can also pass json to the server, and SignalR will automatically handle the conversion to objects. For example, if we have define a class MyObject:

public class MyObject {
    public int objId { get; set; }
    public string objVal { get; set; }
}

We can send it to the server like this:

var jsonMyObject = {
    "objId" : 1,
    "objVal" : "some text"
};
connection.receiveObject(jsonMyObject);

The reverse of this is true also, so returned objects from the server will be converted to their json equivalent.

Note: Static Variables

The hub class that you create will be instantiated at every request, so if you declare variables then they will be lost unless you make them static. This is useful for data that you want to persist, but not store in the database, as can be seen in the SignalR chat hub sample, which uses static collections to maintain the list of rooms.

Invoking client-side functions from the Server

So far I’ve only covered requests from client to server, which really is not a lot more useful than Ajax, albeit with some extra niceties such as object casting. The real usefulness of SignalR, however, comes with being able to call javascript functions from the server. I hope you won’t be surprised to learn, this is really easy to do! SignalR maintains a list of client side connections into the hub, rather conveniently named Clients. Client side functions must be defined in the initialisation code, for instance:

$(function() {
    var myConnection = $.connection.myHub;
    myConnection.alertMessage = function(stringParam) {
        alert(stringParam);
    };
    $.connection.hub.start();
});

This code simply creates an alert box that echoes the data passed to it, and is called by using

Clients.alertMessage("test");

Again, you can pass not only simple data types in here but C# objects and SignalR will handle the conversion. Taking this idea a little further we can pass in a list of MyObjects and iterate through them like this:

myConnection.receiveComplex = function(complexList) {
    complexList.each(function(index, complexObject) {
        var id = complexObject.objId;
        var value = complexObject.objVal;
    });
};

Invoking Client-side Functions from out of the Hub

Bouncing data back and forth between is cool, but the final useful thing you can do is to invoke javascript from outside the hub simply by:

var clients = Hub.GetClients();
clients.alertMessage("external test");

And there we have it! Asynchronous server/client messaging made easy!

I guess this is the natural way to start a blog like this; hi to anyone reading! My name’s Jordan, senior software developer at Tech13 Ltd, C#/web development enthusiast. I’ve started this blog really to share some of my experiences working as a software developer, and also in the hope that I can cover issues that I’ve come across that were perhaps not quite solvable through stackoverflow or googling alone!

So maybe some quick facts about me?

  • Well, I just started as a senior software developer last month. It’s my first project management experience, currently only leading a small team but one that’s expected to grow over the next year. I’m hugely grateful to my bosses for the chance!
  • I’ve got a BSc in Artificial Intelligence and Computer Science from the University of Birmingham
  • I’ve got an HTC HD7 running Windows Phone 7, and it makes me pretty damn sad that fewer people are using WP7! I love my phone…
  • I’m from Devon, but currently living in Birmingham with my fiancé, who I owe the world to
Right then, enough of that, hopefully I can get back here soon and get some actual posts written!