Wednesday, November 23, 2011

Serializing dates in MVC (update)

As I was falling asleep in bed last night, a thought went through my mind: "Since I'm using this Regular Expression every time I load the page, isn't it rather wasteful to be compiling it every time?" So when I got up this morning, I looked up "Compiled Regular Expressions", and read through this page: http://www.dijksterhuis.org/regular-expressions-advanced/. Not only did I pick up some tips on compiling regular expressions, I also discovered a much simpler (and likely quite more efficient) way of replacing the MS-formatted date with my date string. In my previous method, I was casting the Regex matches to an IENumerable and using Linq to iterate through them; in the updated version, the iterative process is handled internally by the Regex object. All I have to do is tell it to use my FixDates method whenever it encounters a match. In the process of updating my code, I also added support for custom Date Formats and set the default to "yyyy-MM-dd".
private static readonly Regex DateRegex = new Regex(@"\\/Date\((?<ticks>\d+)?\)\\/", RegexOptions.Compiled);
/// <summary>
/// If true, date-specific serialization code will be run;
/// If false, date-specific serialization code will not be run.
/// </summary>
public bool HasDates { get; set; }
/// <summary>
/// The date format string to be applied. Defaults to "yyyy-MM-dd".
/// </summary>
public string DateFormatString { get; set; }

/// <summary>
/// Replaces MS-formatted dates with date strings
/// </summary>
/// <param name="match"></param>
/// <returns></returns>
public string FixDates(Match match)
{
    return new DateTime(1970, 1, 1)
        .AddMilliseconds(long.Parse(match.Groups["ticks"].Value))
        .ToString(DateFormatString);
}

/// <summary>
/// Serialize the object to JavaScript and
/// perform extra formatting on the serialized string as necessary
/// </summary>
/// <returns></returns>
public string Serialize()
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    var serializedData = serializer.Serialize(Data);
    if (HasDates)
        serializedData = DateRegex.Replace(serializedData, FixDates);

    return serializedData;
}
Click here to download the updated code.

No comments:

Post a Comment