Tuesday, March 31, 2009

JSON and C# using Generics and Delegates

JSON or JavaScript Object Notation, is a method for transferring data, similar to XML and other formats. There are many advantages to using this method. It is human readable, and it translates easily to objects on the client side of the browser.

With JSON, I can declare an array like this:

var myArray = ["this","that","the other"]; 

The object notation is even simpler. Imagine a C# "Person" class:

public class Person 
{
   public int ID { get; set; } 
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string SSN { get; set; }
}

If I want to express this data to the client, I can do something like this:

var person = { 
   "ID" : "1", 
   "FirstName" : "Jeremy",
   "LastName" : "Likness",
   "SSN" : "111-222-3333" 
};
alert("My name is " + person.FirstName + " " + person.LastName); 

One criticism of the WebForms view engine (the one most of you are using in .NET ... while other view engines such as NVelocity have existed as part of the MonoRail project, Microsoft only recently released the MVC release candidate which introduces the Model-View-Controller view engine) is that it overburdens the client when rendering simple tags. If you have compared <input type="text"> with an <asp:TextBox>, you get the point.

Furthermore, developers tend to get lost in the "ease" of the AJAX framework and often fail to consider the performance implications of wrapping, say, cascading drop downs in an update panel. A much easier method is to serialize the values and bind them using a third-party tool like JQuery instead.

While I was working on this framework I realized it would be quite simple to serialize my domain objects for JSON. I wanted something generic, that didn't rely on reflection for abstraction, and gave me full control over which attributes to render without having to dirty my domain model with attributes or other declarations for something that is entirely UI-related.

The result? A "JSONObject" with a Serialize() method that emits the JSON code. Here is the class:

namespace MyJSON 
{
    /// <summary>
    ///     Delegate to determine how a value is pulled from the object
    /// </summary>
    /// <param name="instance">The instance to pull the property from</param>
    /// <param name="property">The value of the instance</param>
    /// <returns>The string representation of the value for that property</returns>
    public delegate string PropertyValue(T instance, string property);

    /// <summary>
    ///     Class to help serialize objects to the client
    /// </summary>
    public class JSONObject<T> 
    {        
        /// <summary>
        ///     The object to serialize
        /// </summary>
        private readonly T _object;

        /// <summary>
        ///     A list of properties to serialize
        /// </summary>
        private readonly List _properties;

        /// <summary>
        ///     Reference to delegate to parse the value
        /// </summary>
        private readonly PropertyValue _propValue; 
               
        /// <summary>
        ///     Constructor for JSON object
        /// </summary>
        /// <param name="instance">The entity instance</param>
        /// <param name="properties">The list of properties to serialize</param>
        /// <param name="propValue">The method to extract the property value</param>
        public JSONObject(T instance, IEnumerable<string> properties, PropertyValue<T> propValue)
        {
            _object = instance;
            _properties = new List(properties);
            _propValue = propValue; 
        }

        /// <summary>
        ///     Serialize to the JSON representation
        /// </summary>
        /// <returns>The JSON representation</returns>
        public string Serialize()
        {
            StringBuilder json = new StringBuilder();

            json.Append("{");

            bool first = true;

            foreach(string prop in _properties)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    json.Append(","); 
                }
                string value = _propValue(_object, prop);
                json.Append(string.Format("\"{0}\":{1}", prop, EncodeJsString(value))); 
            }

            json.Append("}"); 

            return json.ToString(); 
        }
   }
}

The JSON object takes a type of T which can be anything. The constructor takes in "T", along with an array and a delegate. The array is a list of strings describing the properties I am interested in. For example, I may only want to send id and last name because I don't use the other attributes in my client script. Finally, the delegate. The signature is simple: given the attribute and the entity, what is the value as a string? This allows me to inject the logic to map the UI attributes to the domain attributes. The easiest way to send the data is to realize it as a string and then manipulate it appropriately on the client. After all, JavaScript itself doesn't "know" about any of our complex objects.

The simplest use would be simply to send one of my Person objects and show the name. For example:

<b>ID: </b> <span id="personId"> </span>
<b>Name: </b> <span id="personName"> </span>
In my own script I simply make my JSON object and serialize it out:
JSONObject<Person> jsonPerson = new JSONObject<Person>(
   new Person { ID = 1, LastName="Likness" },
   new[] { "id", "name" }, 
   (entity,property) => property.Equals("id") ? entity.ID : entity.LastName
);
Page.ClientScript.RegisterClientScriptBlock(GetType(),GetType(),
   string.Format("var person={0}",jsonPerson.Serialize()),true);  

Finally, I need something to wire it in for me, I'll choose JQuery ...

<script type="text/javascript">
   $(document).ready(function(){
      $("#personId").html(person.id);
      $("#personName").html(person.name); 
   });
</script>

The script block takes a type (I'm just using the type of the page or control I'm in), a key (this should be unique per script block ... I'm using the type again here but could have it strongly typed or set as a const, etc), the JavaScript to emit (from our serialize method on the JSON object), and then the true tells it to wrap my script tags because I haven't done it myself.

These objects can come back as the result of a callback (just assign them to the window.var object so they are globally accessible and use an eval) for dynamic binding, or you might simply render an array of objects and then do something like this:

for (var x = 0; x < window.json_options.length; x++) {
            var option = window.json_options[x];
            $("#selBox").append("<option value=\"" +
                option.id + "\"" + +(first ? " checked=\"checked\"" : "") + ">" + option.value + "</option>");
        }

Which will bind the drop down list. If you are fighting with the urge to cry "hack" because we're wiring in HTML ... remember, this is what ASP.NET does under the covers for you. In the end, controls are complex text rendering engines that emit fragments the browser can manage.

Of course, the next step was to make a JSONList<T> and I purposefully left the encode script out, you can google some solutions for that.

Jeremy Likness

Monday, March 30, 2009

IUnity

One important aspect of using a container is that you know multiple layers of the application will be getting information from the container. For this reason, it makes sense to inject the container so that some "higher" level can configure it and pass it around.

For this reason, my business objects take it in the constructor, like this:

public class MyClass : IClass
{
   public MyClass(IUnity container) 
   {
    ...
   }
}

So how does the container get there? Of course, something has to instantiate and configure it. In a test class, how about the "setup" section? In a web application, what about Global?

At any rate, there is no need to explicitly inject it to the subsequent layers. Configure it, register it, and forget about it.

IUnityContainer container = new UnityContainer();
container.RegisterType<IClass, MyClass>(); 
container.RegisterInstance<IUnityContainer>(container); 

Unity understands that MyClass needs an IUnityContainer because of the signature of the constructor. By registering the instance of the container itself, when I ask for an IClass, it will reference MyClass and then pass container to satisfy IUnityContainer.

Jeremy Likness

Friday, March 27, 2009

Fix for IE 6.0

Quick post related to my last one... turns out IE 6.0 doesn't read the "onclick" attribute as an "onclick" event, so the call was failing when we evaluated the original event. IE 6.0 likes to call the function "anonymous," so the following code handles that case:

eval(window.criteria_postback + 
   ";try{onclick(window.criteria_event);}catch(e){anonymous();}");

Thursday, March 26, 2009

Using JQuery to intercept the click of an asp:Button

I was working on an interesting problem today. The architecture of a different project I am working on does not use MVC, but ASP.NET controls. We have separated them into a control/controller model so that business logic interacts with a controller, which passes POCOs to a control, and the control knows how to render them. The control knows no business logic, security, etc, while the controller doesn't understand anything about the UI domain EXCEPT for the fact that it is interacting with something derived from "Control" that lives in Web.UI.

Many of the examples in JQuery show you how to "unbind" and event, but I quickly found this wasn't working for me. What I wanted to do was place a traditional ASP.NET button on the page (quite frankly, the button was already buried in another control, so I wanted to work with this rather than come up with a hack to do a lightweight input button). I needed to intercept the click event, perform a call back, and then based on the result either display an error or allow the originally intended event (a postback) to fire.

After lots of searching I finally settled with decorating my functions with alerts until I figured out exactly what was going on. So let's get started.

First, the button: easy enough.

   <asp:Button ID="btnExample" runat="server" Text=" Click Me "/>

On the server side, we can do this:

   btnExample.OnClick += MyClickHandler; 
   ...
   protected void MyClickHandler(object sender, EventArgs e)
   {
       // do something IF all is well 
   }

Of course the server should ALSO check what I'm wiring in for validation, but I'm simplifying this for now. Now the fun part. What we want to do is find the button (I'll leave the JQuery up to you - you can search on the button, emit the client id and go on that, etc. In my case, it's the third button in a div with class "buttonBar"). Let's wire this up:

 $(document).ready(function() {
        var nextButton = $(".buttonBar input:button:eq(2)");
        window.criteria_postback = $(nextButton).attr("onclick");        
        $(nextButton).removeAttr("onclick");
        $(nextButton).unbind().click(function(event) {

            window.criteria_event = event;
            
            event.preventDefault();
        
            $(this).attr("disabled", "disabled");
            $(this).val(" Please wait... ");

            //load cmdString with something useful for the server 

            WebForm_DoCallback('__Page', cmdString, window.Criteria_CallbackHandler, null, null, false);          
            
        });

So let's walk through this. I found for some reason (probably documented somewhere that I just didn't find) that unbinding the click event wasn't working. So instead, I decided to save the existing click event (window.criteria_postback). The reason I save it to the window is because I need to reference it in an eval() expression later on. Microsoft sandboxes evals so they can't see variables unless they are explicitly scoped to global.

Next, we get rid of the attribute (this prevents the event from firing).

Then I wire in my own click event. I SAVE the event to the global space, prevent the default (going through with it), then disable my button so the user doesn't double click.

Finally, I wire in the callback. A few interesting things about callbacks. First, if this code was embedded in a control, I'd need to have a reference to the control instead of the __Page for the control to pick it up. Second, and most importantly, even when you wire your own callback, you MUST let the ClientScript KNOW to listen!. In other words, I told my page to implement ICallbackHandler which exposes:

 public void RaiseCallbackEvent(string eventArgument)
 {
   // do something with the event from the client
 }
 ...
 public string GetCallbackResult() 
 {
   // return a result to the client
 }

Some people mistakenly believe this is enough to be able to capture callbacks, but unless you actually ask for the callback reference, the page/control won't listen! So it's important that even if you don't use the result, you at least make a call like this:

// generate the callback handlers 
Page.ClientScript.GetCallbackEventReference(this, "args", string.Empty, string.Empty);

Now it is happy and listening. We're almost done ... we've intercepted the original postback and saved it, and we've wired in our own callback. In my case, I have a select grid that is harvesting check boxes, so I want to build a light weight list of identifiers. I build that list on the client, then use the callback to send it down and store it on the server for later. A pattern that works well for me with the call back is like this:


private string _callbackResult; 

public void RaiseCallbackEvent(string eventArgument)
{
   try
   {
      ...
      _callbackResult = string.Empty;
   }
   catch(Exception ex) 
   {
     _callbackResult = ex.Message;
   }
}

public string GetCallbackResult()
{
   return _callbackResult; 
}

And now we come back to the client side. Part of the Callback is a delegate to handle the return. In our case, we passed in window.Criteria_CallbackHandler. Here is how we "catch" the result:

window.Criteria_CallbackHandler = function(result, context) {

    if (result == null || result == '') {
        eval(window.criteria_postback + ";onclick(window.criteria_event);");
        return; 
    }
    else {
        alert(result);
    }

    var nextButton = $(".buttonBar input:button:eq(2)");
    
    $(nextButton).val(" Next ");
    $(nextButton).removeAttr("disabled");

}

So what is going on? If I had no issues, I do something interesting. When I saved the "onclick" earlier, you'll find the ASP.NET page wired it in like this:

void onclick(event) { blah; }

So I am basically spitting the function back out in my "eval", then immediately calling it with the event that I saved earlier! This has the result of "business as usual" which in my case is to post to a new page and pick off the list I persisted in the callback to do something with it. Otherwise, I alert the error to the customer (a prettier solution may be to have a div for errors and just write this into the div instead of using the generic alert box), and then regardless, I restore my button so it can be clicked again.

There you go ... buttons, JQuery, and callback handlers all in one post!

Jeremy Likness

Tuesday, March 24, 2009

SharpDevelop, NUnit, and Visual Studio Express

At my software company we have access to some incredible tools and technologies. I can load up my copy of Visual Studio 2008 (Team System), publish documents to our SharePoint server, refactor code with ReSharper and then suck it into Enterprise Architect to make class diagrams. At home, however, my budget is not so grand. I'm using TortoiseSVN for Source Control, OpenOffice for more document processing needs ... and then there's the development environment.

Visual Studio Express provides most of what you will need to write applications, including a robust copy of SQL 2008 Express. The one thing it does not have is source code integration nor the testing framework. Understanding this, I set out to see what other solutions were available. I was amazed at the functionality provided by #develop, but it came with one major setback: no web support! As my "pet project" is a web application, that sort of put a damper on things ... or did it?

It turns out that I found a very workable solution that lets me develop, publish, and test my web application using a testing framework.

NUnit is an open source testing framework. You click and download it. I made the mistake of installing the binaries on Vista x64 and then had trouble launching tests. Download the source and compiling it solved that problem.

I develop my application in Visual Studio Express, which lets me do just about everything but run the tests. Of course, I can launch the NUnit GUI and test run them from there, but I like a more integrated approach.

It turns out the solution is quite simple. I created a solution that contains all of my main projects, here:

Then, I turn around and launch SharpDevelop, and create my test solution. I reference my non-web projects and test projects there:

Because NUnit is integrated right out of the box, I can simply expand my "test" menu now and hit "play" then watch the beautiful green lights ...

If there are issues, I simply double-click and I'm right there to edit the code. Subversion will pick up any changes and then it's a simple right-click to check it all back in!

Jeremy Likness

NHibernate and Complex Types for Native Keys

Primary keys may take several forms: guid, integer, long, etc. It often makes sense to represent the key field as a POCO rather than it's native type.

Why would I do this?

First, it hides the implementation. I don't have to worry about whether the key is an integer or a long, instead, I interact with my complex type.

It allows me to do some more interesting things with a key, too. For example, let's say I did choose to use identity fields (integers) so one implementation of my key is a "CoreKey" that contains an "ID" of type Integer.

It is common to see people use 0 or -1 as a "null" or "uninitialized" value for this type of key. With my class, I can do a little more and define it like this:

    /// <summary>
    ///     CoreKey provides the unique identifier for classes in the system
    /// </summary>
    [Serializable]
    public class CoreKey : IComparable<CoreKey>, IEquatable<CoreKey>, ICloneable 
    {
        /// <summary>
        ///     Represents value when not initialized
        /// </summary>
        private const int NOT_INITIALIZED = -1;

        /// <summary>
        ///     Unique identifier
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        ///     Represents an "empty" or unitialized key
        /// </summary>
        public static CoreKey Empty
        {
            get
            {
                return new CoreKey(NOT_INITIALIZED); 
            }
        }

        /// <summary>
        ///     Default -1
        /// </summary>
        public CoreKey()
        {
            ID = NOT_INITIALIZED;
        }

        /// <summary>
        ///     Initialize with id
        /// </summary>
        /// <param name="id">The unique identifier</param>
        public CoreKey(int id)
        {
            ID = id;
            _Initialize();
        }

        /// <summary>
        ///     Initializes properties to valid values
        /// </summary>
        private void _Initialize()
        {
            if (ID <= 0)
            {
                ID = NOT_INITIALIZED;
            }
        }

        /// <summary>
        ///     Tests to see whether the key is initialized
        /// </summary>
        /// <param name="coreKey">The instance of <seealso cref="CoreKey"/> to test</param>
        /// <returns>True if null or empty</returns>
        public static bool IsNullOrEmpty(CoreKey coreKey)
        {
            return coreKey == null || coreKey.ID.Equals(NOT_INITIALIZED);
        }

        /// <summary>
        ///     Attempt to parse a value to the key. Returns true if the
        ///     attempt succeeded.
        /// </summary>
        /// <param name="value">The value to try to case as a key</param>
        /// <param name="coreKey">A <seealso cref="CoreKey"/>instance to case the value to</param>
        /// <returns>True if the cast succeeded</returns>
        public static bool TryParse(string value, out CoreKey coreKey)
        {
            bool retVal = false; 

            int id; 
            if (int.TryParse(value, out id))
            {
                coreKey = new CoreKey(id);
                retVal = true;
            }
            else
            {
                coreKey = null;
            }

            return retVal; 
        }

Notice that when I create a key (CoreKey key = new CoreKey()) it is immediately initialized to CoreKey.Empty, a special value I can check for. Instead of "if id < 1" I can use "CoreKey.IsNullOrEmpty" and I can even TryParse this.

This is all and well until you try to wire the class into NHibernate. The classic example for an NHibernate mapping file goes something like this:


<?xml version="1.0" encoding="utf-8"?>
<nhibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="MyApp.Widget,MyApp" table="widgets">
    <id name="Id" column="WidgetId">
      <generator class="native"/>
    </id>
    <property name="WidgetName" column="name" type="String" length="40"/>
  </class>
</nhibernate-mapping>

That's all good and well, but our widget uses a CoreKey, right? So what now? Try to reference the type, and you start to have problems:

<id name="Id" column="WidgetId" type="Framework.CoreKey,MyApp"/>

Of course, this will blow up. Why? Because the type coming from the database is an integer, and our CoreKey is NOT an integer. So what do we do?

This seems like it should be a simple problem to solve, but I searched far and wide to find a solution. I was trying components and composite keys and everything in between. I finally found an example that mentioned using the special interface IUserType supplied by NHibernate to, well, create our own types.

Unfortunately, the example included referencing NHibernate, my "persistence engine" or data layer, and then applying the interface to my domain object ("business entity"). Can you imagine dirtying your entity layer with ugly references to the implementation of your data store? Shouldn't, couldn't, and wouldn't happen.

Fortunately, the solution was rather simple and straightforward. Thanks to C# and inheritance, my domain objects only have to know about a CoreKey. However, my data layer can interact with something smarter, something that implements the IUserType interface AND talks the language of CoreKey.

Introducing CoreKeyProxy, an object defined in the data layer of the application. Here is the meat ... I've edited out comments and some of the other methods, and included the key items that map the database values to the custom type:

   public class CoreKeyProxy : CoreKey, IUserType
    {

        public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
        {
            object r = rs[names[0]];
            if (r == DBNull.Value)
                return null;
            return new CoreKey((int)r);  
        }

        public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
        {
            IDataParameter parameter = (IDataParameter)cmd.Parameters[index];
            parameter.Value = value == null ? null : (object)((CoreKey)value).ID;  
        }


        public Type ReturnedType
        {
            get { return typeof(CoreKey); }
        }

        public global::NHibernate.SqlTypes.SqlType[] SqlTypes
        {
            get { return new[] { new SqlType(DbType.Int32) }; }
        }

    }

Now I simply define my id as type="CoreKeyProxy" and voila! I'm able to integrate it seamless with my key class.

Jeremy Likness