Wednesday, August 08, 2007

WCF Performance

JSON Date deserialization fails at client
Some time ago I've developed a Comet infrastructure for the ASP.NET Ajax. As part of its possibilities - it enables to serialize server-side objects and stream them to the handling function at client side. It was working like a breeze, until Ive streamed some object with Date field, say something like that:        
public class TestMessage        
{            
public string _s1 = "s1";            
public int _i1 = 1;            
public DateTime _t1 = DateTime.Now;        
}


Now, an instance of this TestMessage was correctly deserialized into JS object, exclude its DateTime fields, which was appearing in following form:
{...}
_i1: 1
_s1: "s1"
_t1: "/Date(777)/"


If youre affected by similar problem here is the reason:
1) JSON representation for the string was changed from @777@ to \/777\/ in the latest Ajax release (to prevent serialization of strings that looks like date into Date format), where 777 is num of milliseconds since January 1, 1970 UTC.
2) Currently - at the server side DateTime object is serialized as "_t1":"\/Date(777)\/"
3) If you stream it as-is to the client-side JS recognizes single \ as escape character and your date actually became /Date(777)/, which is wrong format for deserialization.

So, if you want to stream your objects correctly you here is small RegEx-based utility Ive did for it:        

private static class ReplaceDateOrchestrationRegularExpression        
{            
private const string _regex =                
"(?\")(?\\\\)(?/Date\\([\\d]+\\))(?\\\\)(?<" + "postfix>/\")";            
private static readonly RegexOptions _options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase);            

public static readonly Regex Expression = new Regex(_regex, _options);            
public const string ReplaceOptions =                
@"${prefix}${firstDateSlash}\${body}${secondDateSlash}\${postfix}";        
}        


private static string ConvertToClientSideJson( string jsonedArgument )        
{            

return ReplaceDateOrchestrationRegularExpression.Expression.Replace(
jsonedArgument,
ReplaceDateOrchestrationRegularExpression.ReplaceOptions);        
}

No comments: