Zleek 2.0 is here!

23 09 2009

Zleek Logo

Zleek 2.0 has released!

Check it out at http://zleek.com.

Here are the new features:

  • Completely new design and flow – much easier to use.
  • Customizable albums (page color, border color, border sizes, etc)
  • Video support
  • Facebook integration (login and stream posts)

Those are the “new” features from the 1,000-foot level. In reality, the entire site was rewritten from scratch using new technologies and optimized workflows.

Here is the breakdown of what it’s using:

Check it out today!

ComponentArt Silverlight Competition

Please vote for us in the ComponentArt Summer Silverlight Coding Competition!

Agnition.Utils Code Drop

Due to the release, there is a new drop of the Agnition.Utils library containing our final production code. Get it now!

Fish Eye Menu Control

12 05 2009

For the new version of Zleek, I wanted to create an intuitive page menu for the bottom of the albums. I wanted to go with an OS X – style menu.

Here is what I came up with.

You can add any FrameworkElement as a menu item, so primitive shapes up to User Controls are all fine.

This control is part of the Agnition.Utils library, which has been updated.

Get it here!

New Agnition.Utils Code Drop

7 05 2009

There is a new version of the Agnition.Utils libraries available containing some updates (mostly new functionality). In short, there has been a migration from some of the unpublished Zleek-specific code into the general base classes, most notable in the authentication pieces. There have also been a few bug fixes.

If you’re using this library for anything, I strongly suggest upgrading. Get it here.

JQuery, JSON, and the REST Starter Kit

7 05 2009

The new version of Zleek will be retrieving all of its data from a RESTful WCF Service that serves up JSON data. It also makes heavy use of the JQuery 1.3 libraries with the JQuery JSON 1.3 plugin. Are they interoperable?

If you’ve worked with the REST Starter Kit on the server and JQuery on the client, you probably already know the answer: almost.

The problem lies in date serialization. Say you have the date 5/6/2009 and you want to pass it to your RESTful WCF service as JSON. Here is how JQuery serializes it:


And here is how the MicrosoftAjax.js library serializes it:


Your WCF service will only be able to deserialize dates in the Microsoft format and will throw an exception otherwise. You will also have the same problem going the other way. If your WCF service returns a DateTime object, it will be deserialized by JQuery as a string. Luckily, due to the nature of JSON (de)serialization, both of these issues are easy problems to fix.

I only wish I had seen Rick Strahl’s excellent posts from a year ago on this issue prior to tackling it. Apparently I’m Google-inept…

Situation 1: Transmitting dates from a JQuery client to a WCF service

For those of you new to JavaScript development, JavaScript is a dynamically typed language. Your prototype object can have a date property that you can change to a string or a number at any time without any issues. This property of JavaScript can be leveraged to fix our problem.

Prior to calling the JQuery library and issuing the request to the WCF service, you can change it to a string that will be serialized like the way MicrosoftAjax serializes dates. To get an output of:


We need an input of:


Here is a function you can use to do just that. It takes a JavaScript Date object and turns it into a string that JQuery will then serialize into the MicrosoftAjax date serialization format.

   1: Agnition.Serialization.SerializeDate = function(date) {

   2:     /// <summary>

   3:     ///    JQuery cannot serialize a Date object so that .NET can read it, this fixes its attempt by calling

   4:     ///    the MS AJAX serializer. JQuery will then serialize a string correctly.

   5:     /// </summary>

   6:     /// <param name="date">The date to serialize</param>

   7:     /// <returns>A JSON serialized date formatted for .NET</returns>

   8:     var dateString = Sys.Serialization.JavaScriptSerializer.serialize(date);

   9:     dateString = dateString.substring(2);

  10:     dateString = dateString.substring(0, dateString.length - 3) + "\/";

  11:     return dateString;

  12: };

Here is an example of it in use:

   1: this.CreateBook = function(successCallback, errorCallback) {

   2:     /// <summary>Attempts to register the user</summary>

   3:     /// <param name="successCallback">The callback fired if the request is successful</param>

   4:     /// <param name="errorCallback">The callback fired if the request failed</param>


   6:     var albumData = this.AlbumData;

   7:     var svcAddress = this.ServiceAddress;


   9:     albumData.LastUpdated = Agnition.Serialization.SerializeDate(albumData.LastUpdated);

  10:     var jsonRequest = new Agnition.Net.WebRequest();

  11:     var url = svcAddress + "/Album/new?includeMedia=false";

  12:     jsonRequest.PutJson(url, albumData, successCallback, errorCallback, null);

  13: };

Situation 2: Receiving dates from a WCF service in a JQuery client

This issue is basically the reverse of Situation 1. Your WCF service will serialize a DateTime object in the MicrosoftAjax format. JQuery will see this and deserialize it as a string. All we have to do is modify this string to put it back into the MicrosoftAjax format, and then use the MicrosoftAjax library to deserialize it. Here is what JQuery will deserialize the response as (notice it’s a string):


Here is a function that will perform the translation for you:

   1: Agnition.Serialization.FixJQueryDate = function(dateString) {

   2:     /// <summary>

   3:     ///    JQuery cannot deserialize the .NET dateTime object, so this fixes its attempt by reconstructing

   4:     ///    the string and calling the MS AJAX deserializer.

   5:     /// </summary>

   6:     /// <param name="dateString">The JQuery deserialized date string</param>

   7:     /// <returns>A JavaScript date object</returns>

   8:     dateString = dateString.substring(1);

   9:     dateString = dateString.substring(0, dateString.indexOf("\/"));

  10:     dateString = "\"\\\/" + dateString + "\\\/\"";

  11:     var date = Sys.Serialization.JavaScriptSerializer.deserialize(dateString);

  12:     return date;

  13: };

And here is an example of it in use:

   1: $(document).ready(function() {

   2:     var request = new Agnition.Zleek.Web.Service.PagedDataRequest(bookUrl, BOOK_PAGE_SIZE, BOOK_MAX_RECORDS);

   3:     request.GetPage(BOOK_CURRENT_PAGE,

   4:             function(data, statusText) {

   5:             /* snip */

   6:                 for (var i = 0; i < numAlbums; i++) {

   7:                     var album = data.Albums[i];

   8:                     album.LastUpdated = Agnition.Serialization.FixJQueryDate(album.LastUpdated);

   9:             /* snip */

  10: };

Now, assuming all of the dates in our service are UTC dates, this function will perform the conversion from UTC to the browser’s local time, and then we can create a new method which fixes both the date serialization and performs the time conversion:

   1: Agnition.ConvertUTCToLocalTime = function(date) {

   2:     /// <summary>Converts a UTC date to local time</summary>

   3:     /// <param name="date">The date object to convert</param>

   4:     /// <returns>The resulting local time</return>

   5:     var utcTime = date.getTime();

   6:     var localOffset = date.getTimezoneOffset() * 60000; // Get offset in milliseconds

   7:     var localTime = utcTime - localOffset;

   8:     return new Date(localTime);

   9: };


  11: Agnition.Serialization.GetJQueryDateAsLocalTime = function(dateString) {

  12:     /// <summary>

  13:     ///    JQuery cannot deserialize the .NET dateTime object, so this fixes its attempt by reconstructing

  14:     ///    the string and calling the MS AJAX deserializer. The resulting date is then converted to local

  15:     ///    time from UTC time.

  16:     /// </summary>

  17:     /// <param name="dateString">The JQuery deserialized date string</param>

  18:     /// <returns>A JavaScript date object, converted from UTC to local time</returns>

  19:     return Agnition.ConvertUTCToLocalTime(Agnition.Serialization.FixJQueryDate(dateString));

  20: };

Caveat Emptor

Because there is no standard date literal in JavaScript, Microsoft AJAX and JQuery may change their respective JSON date serialization formats in the future. So if you’re using this solution (and hopefully created a single function to perform the translations), you may have to modify your translation code when using future releases of JQuery or MS AJAX. In fact, Microsoft has already changed their format once before, and may do so again in the future.