# Sunday, August 12, 2007

In my previous article I talked about the hunt for a good JSON parser/serializer. For my current project I only needed a serializer to generate JSON from any .NET object, so for now it’s a bit overkill to use a full blown JSON library.

After looking at the specs for JSON, I figured it couldn’t be too hard to write a JSON serializer in C#. Not only was it not that hard, it was very short too: about 100 lines of code (well, 110 without the empty lines).

The serializer can handle any regular data type, including DateTime (for which there is no standard in JSON).

Here it is: (feel free to use it for anything you like)

 

public class JSONSerializer
{
    private readonly StringBuilder _output = new StringBuilder();

    public static string ToJSON(object obj)
    {
        return new JSONSerializer().ConvertToJSON(obj);
    }

    private string ConvertToJSON(object obj)
    {
        WriteValue(obj);

        return _output.ToString();
    }

    private void WriteValue(object obj)
    {
        if (obj == null)
            _output.Append("null");
        else if (obj is sbyte || obj is byte || obj is short || obj is ushort || obj is int || obj is uint || obj is long || obj is ulong || obj is decimal || obj is double || obj is float)
            _output.Append(Convert.ToString(obj,NumberFormatInfo.InvariantInfo));
        else if (obj is bool)
            _output.Append(obj.ToString().ToLower());
        else if (obj is char || obj is Enum || obj is Guid)
            WriteString("" + obj);
        else if (obj is DateTime)
            _output.Append("new Date(" + ((DateTime)obj - new DateTime(1970,1,1)).TotalMilliseconds.ToString("0") + ")");
        else if (obj is string)
            WriteString((string)obj);
        else if (obj is IDictionary)
            WriteDictionary((IDictionary)obj);
        else if (obj is Array || obj is IList || obj is ICollection)
            WriteArray((IEnumerable)obj);
        else
            WriteObject(obj);
    }

    private void WriteObject(object obj)
    {
        _output.Append("{ ");

        bool pendingSeparator = false;

        foreach (FieldInfo field in obj.GetType().GetFields(BindingFlags.Public|BindingFlags.Instance))
        {
            if (pendingSeparator)
                _output.Append(" , ");

            WritePair(field.Name, field.GetValue(obj));

            pendingSeparator = true;
        }

        foreach (PropertyInfo property in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (!property.CanRead)
                continue;

            if (pendingSeparator)
                _output.Append(" , ");

            WritePair(property.Name,property.GetValue(obj, null));

            pendingSeparator = true;
        }

        _output.Append(" }");
    }

    private void WritePair(string name, object value)
    {
        WriteString(name);

        _output.Append(" : ");

        WriteValue(value);
    }

    private void WriteArray(IEnumerable array)
    {
        _output.Append("[ ");

        bool pendingSeperator = false;

        foreach (object obj in array)
        {
            if (pendingSeperator)
                _output.Append(',');

            WriteValue(obj);

            pendingSeperator = true;
        }

        _output.Append(" ]");
    }

    private void WriteDictionary(IDictionary dic)
    {
        _output.Append("{ ");

        bool pendingSeparator = false;

        foreach (DictionaryEntry entry in dic)
        {
            if (pendingSeparator)
                _output.Append(" , ");

            WritePair(entry.Key.ToString(),entry.Value);

            pendingSeparator = true;
        }

        _output.Append(" }");
    }

    private void WriteString(string s)
    {
        _output.Append('\"');

        foreach (char c in s)
        {
            switch (c)
            {
                case '\t': _output.Append("\\t"); break;
                case '\r': _output.Append("\\r"); break;
                case '\n': _output.Append("\\n"); break;
                case '"': 
                case '\\': _output.Append("\\" + c); break;
                default:
                    {
                        if (c >= ' ' && c < 128)
                            _output.Append(c);
                        else
                            _output.Append("\\u" + ((int) c).ToString("X4"));
                    }
                    break;
            }
        }

        _output.Append('\"');
    }
}
kick it on DotNetKicks.com
Sunday, August 12, 2007 9:30:00 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [13] -

Tracked by:
"http://morningside.edu/mics/_notes/pages/nexium/index.html" (http://morningside... [Pingback]
"http://blastpr.com/wiki/js/pages/nexium/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://morningside.edu/mics/_notes/pages/cymbalta/index.html" (http://morningsi... [Pingback]
"http://blastpr.com/wiki/js/pages/coumadin/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://blastpr.com/wiki/js/pages/prilosec/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/clomid/index.html" (http://morningside... [Pingback]
"http://blastpr.com/wiki/js/pages/wellbutrin/index.html" (http://blastpr.com/wik... [Pingback]
"http://blastpr.com/wiki/js/pages/claritin/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/paxil/index.html" (http://morningside.... [Pingback]
"http://morningside.edu/mics/_notes/pages/ultram/index.html" (http://morningside... [Pingback]
"http://blastpr.com/wiki/js/pages/prozac/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://morningside.edu/mics/_notes/pages/prilosec/index.html" (http://morningsi... [Pingback]
"http://blastpr.com/wiki/js/pages/effexor/index.html" (http://blastpr.com/wiki/j... [Pingback]
"http://blastpr.com/wiki/js/pages/ultram/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://morningside.edu/mics/_notes/pages/soma/index.html" (http://morningside.e... [Pingback]
"http://blastpr.com/wiki/js/pages/clomid/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://blastpr.com/wiki/js/pages/celebrex/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/tramadol/index.html" (http://morningsi... [Pingback]
"http://blastpr.com/wiki/js/pages/cialis/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://blastpr.com/wiki/js/pages/paxil/index.html" (http://blastpr.com/wiki/js/... [Pingback]
"http://morningside.edu/mics/_notes/pages/rainbow-brite/index.html" (http://morn... [Pingback]
"http://morningside.edu/mics/_notes/pages/celexa/index.html" (http://morningside... [Pingback]
"http://morningside.edu/mics/_notes/pages/celebrex/index.html" (http://morningsi... [Pingback]
"http://morningside.edu/mics/_notes/pages/hoodia/index.html" (http://morningside... [Pingback]
"http://morningside.edu/mics/_notes/pages/lipitor/index.html" (http://morningsid... [Pingback]
"http://morningside.edu/mics/_notes/pages/viagra/index.html" (http://morningside... [Pingback]
"http://blastpr.com/wiki/js/pages/lipitor/index.html" (http://blastpr.com/wiki/j... [Pingback]
"http://morningside.edu/mics/_notes/pages/lexapro/index.html" (http://morningsid... [Pingback]
"http://morningside.edu/mics/_notes/pages/melatonin/index.html" (http://mornings... [Pingback]
"http://blastpr.com/wiki/js/pages/hoodia/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://morningside.edu/mics/_notes/pages/synthroid/index.html" (http://mornings... [Pingback]
"http://blastpr.com/wiki/js/pages/tramadol/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/effexor/index.html" (http://morningsid... [Pingback]
"http://thejohnslater.com/pix/img/docs/73486930/index.html" (http://thejohnslate... [Pingback]
"http://thejohnslater.com/pix/img/docs/41914710/index.html" (http://thejohnslate... [Pingback]
"http://thejohnslater.com/pix/img/docs/42082955/index.html" (http://thejohnslate... [Pingback]
"http://split-dalmatia.com/split-dalmatia.com/images/docs/34320152/index.html" (... [Pingback]
"http://legambitdufou.org/Library/docs/04618667/index.html" (http://legambitdufo... [Pingback]
"http://entartistes.ca/images/images/docs/28212733/index.html" (http://entartist... [Pingback]
"http://blog.netmedia.hr/wp-includes/js/docs/91708760/index.html" (http://blog.n... [Pingback]
"http://coolioness.com/attachments/docs/03698289/index.html" (http://coolioness.... [Pingback]
"http://witze-humor.de/templates/images/docs/83157240/index.html" (http://witze-... [Pingback]
"http://martinrozon.com/images/photos/docs/82037625/index.html" (http://martinro... [Pingback]
"http://temerav.com/images/menu/20420171/index.html" (http://temerav.com/images/... [Pingback]
"http://allfreefilms.com/wp-includes/js/46226552/index.html" (http://allfreefilm... [Pingback]
"http://islands-croatia.comislands-croatia.com/includes/js/docs/68291686/index.h... [Pingback]
"http://temerav.com/images/menu/05559064/index.html" (http://temerav.com/images/... [Pingback]
"http://promocija.com.hr/promocija.com.hr/includes/js/docs/70471394/index.html" ... [Pingback]
"http://discussgod.com/cpstyles/docs/73291253/index.html" (http://discussgod.com... [Pingback]
"http://blog.netmedia.hr/wp-includes/js/docs/84238305/index.html" (http://blog.n... [Pingback]
"http://coolioness.com/attachments/docs/76375390/index.html" (http://coolioness.... [Pingback]
"http://lecouac.org/ecrire/lang/docs/30125734/index.html" (http://lecouac.org/ec... [Pingback]
"http://thebix.com/includes/compat/docs/51589391/index.html" (http://thebix.com/... [Pingback]
"http://plantmol.com/docs/60217277/index.html" (http://plantmol.com/docs/6021727... [Pingback]
"http://pspdesktops.com/fileupload/store/docs/04061117/index.html" (http://pspde... [Pingback]
"http://plantmol.com/docs/24471383/index.html" (http://plantmol.com/docs/2447138... [Pingback]
"http://islands-croatia.comislands-croatia.com/includes/js/docs/87090382/index.h... [Pingback]
"http://legambitdufou.org/Library/docs/38152786/index.html" (http://legambitdufo... [Pingback]
"http://add2rss.com/img/design/docs/45658867/index.html" (http://add2rss.com/img... [Pingback]
"http://promocija.com.hr/promocija.com.hr/includes/js/docs/63224938/index.html" ... [Pingback]
"http://slaterjohn.com/downloads/2col/28436634/index.html" (http://slaterjohn.co... [Pingback]
"http://temerav.com/images/menu/46200403/index.html" (http://temerav.com/images/... [Pingback]
"http://realestate.hr/templates/css/docs/28593877/index.html" (http://realestate... [Pingback]
"http://split-dalmatia.com/split-dalmatia.com/images/docs/16705258/index.html" (... [Pingback]
"http://seo4u.at/images/docs/72359352/index.html" (http://seo4u.at/images/docs/7... [Pingback]
"http://thebix.com/includes/compat/docs/10152421/index.html" (http://thebix.com/... [Pingback]
"http://plantmol.com/docs/80639343/index.html" (http://plantmol.com/docs/8063934... [Pingback]
"http://pddownloads.com/docs/15972574/index.html" (http://pddownloads.com/docs/1... [Pingback]
"http://ipsilon.hr/ipsilon.hr/cms/4/lib/docs/55227677/index.html" (http://ipsilo... [Pingback]
"http://promocija.com.hr/promocija.com.hr/includes/js/docs/36483653/index.html" ... [Pingback]
"http://legambitdufou.org/Library/docs/64933533/index.html" (http://legambitdufo... [Pingback]
"http://islands-croatia.comislands-croatia.com/includes/js/docs/54089144/index.h... [Pingback]
"http://lecouac.org/ecrire/lang/docs/49649526/index.html" (http://lecouac.org/ec... [Pingback]
"http://blog.netmedia.hr/wp-includes/js/docs/44378735/index.html" (http://blog.n... [Pingback]
"http://thebix.com/includes/compat/docs/29852280/index.html" (http://thebix.com/... [Pingback]
"http://vladan.strigo.net/wp-includes/js/docs/86309858/index.html" (http://vlada... [Pingback]
"http://discussgod.com/cpstyles/docs/43932298/index.html" (http://discussgod.com... [Pingback]
"http://pddownloads.com/docs/66275653/index.html" (http://pddownloads.com/docs/6... [Pingback]
"http://martinrozon.com/images/photos/docs/75270452/index.html" (http://martinro... [Pingback]
"http://blog.netmedia.hr/wp-includes/js/docs/08493171/index.html" (http://blog.n... [Pingback]
"http://pspdesktops.com/fileupload/store/docs/33460308/index.html" (http://pspde... [Pingback]
"http://sevainc.com/bad_denise/img/8/prilosec/" (http://sevainc.com/bad_denise/i... [Pingback]
"abaffy.org/la/img/cialis/" (abaffy.org/la/img/cialis/) [Pingback]
"http://easytravelcanada.info/js/pages/4/coumadin/" (http://easytravelcanada.inf... [Pingback]
"http://jemnemelodierecords.sk/img/viagra/" (http://jemnemelodierecords.sk/img/v... [Pingback]
"http://easytravelcanada.info/js/pages/9/rainbow-brite/" (http://easytravelcanad... [Pingback]
"http://easytravelcanada.info/js/pages/10/synthroid/" (http://easytravelcanada.i... [Pingback]
"http://easytravelcanada.info/js/pages/6/lipitor/" (http://easytravelcanada.info... [Pingback]
"http://sevainc.com/bad_denise/img/9/prozac/" (http://sevainc.com/bad_denise/img... [Pingback]
"http://sevainc.com/bad_denise/img/4/cymbalta/" (http://sevainc.com/bad_denise/i... [Pingback]
"abaffy.org/la/img/viagra/" (abaffy.org/la/img/viagra/) [Pingback]
"http://sevainc.com/bad_denise/img/5/effexor/" (http://sevainc.com/bad_denise/im... [Pingback]
"http://sevainc.com/bad_denise/img/1/accutane/" (http://sevainc.com/bad_denise/i... [Pingback]
"http://inatelevizia.sk/ad/img/viagra/" (http://inatelevizia.sk/ad/img/viagra/) [Pingback]
"http://easytravelcanada.info/js/pages/2/cialis/" (http://easytravelcanada.info/... [Pingback]
"http://easytravelcanada.info/js/pages/2/celexa/" (http://easytravelcanada.info/... [Pingback]
"http://easytravelcanada.info/js/pages/7/nexium/" (http://easytravelcanada.info/... [Pingback]
"http://sevainc.com/bad_denise/img/4/coumadin/" (http://sevainc.com/bad_denise/i... [Pingback]
"http://easytravelcanada.info/js/pages/12/wellbutrin/" (http://easytravelcanada.... [Pingback]
"http://sevainc.com/bad_denise/img/7/nexium/" (http://sevainc.com/bad_denise/img... [Pingback]
"http://easytravelcanada.info/js/pages/3/claritin/" (http://easytravelcanada.inf... [Pingback]
"http://simpletravelcanada.info/js/pages/27277365/" (http://simpletravelcanada.i... [Pingback]
"http://sevainc.com/bad_denise/img/9/rainbow-brite/" (http://sevainc.com/bad_den... [Pingback]
"http://sevainc.com/bad_denise/img/3/clomid/" (http://sevainc.com/bad_denise/img... [Pingback]
"http://sevainc.com/bad_denise/img/11/tramadol/" (http://sevainc.com/bad_denise/... [Pingback]
"http://easytravelcanada.info/js/pages/4/cymbalta/" (http://easytravelcanada.inf... [Pingback]
"http://sevainc.com/bad_denise/img/3/claritin/" (http://sevainc.com/bad_denise/i... [Pingback]
"http://sevainc.com/bad_denise/img/12/zoloft/" (http://sevainc.com/bad_denise/im... [Pingback]
"http://easytravelcanada.info/js/pages/5/effexor/" (http://easytravelcanada.info... [Pingback]
"http://easymexico.info/images/img/cialis/" (http://easymexico.info/images/img/c... [Pingback]
"http://easycanada.info/js/pages/cialis/" (http://easycanada.info/js/pages/ciali... [Pingback]
"http://sevainc.com/bad_denise/img/2/celexa/" (http://sevainc.com/bad_denise/img... [Pingback]
"http://sevainc.com/bad_denise/img/6/lipitor/" (http://sevainc.com/bad_denise/im... [Pingback]
"http://easycanada.info/js/pages/viagra/" (http://easycanada.info/js/pages/viagr... [Pingback]
"http://abaffydesign.com/la/img/cialis/" (http://abaffydesign.com/la/img/cialis/... [Pingback]
"http://easytravelcanada.info/js/pages/7/melatonin/" (http://easytravelcanada.in... [Pingback]
"http://jemnemelodierecords.sk/img/cialis/" (http://jemnemelodierecords.sk/img/c... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/jacqueline-teen-model-is-... [Pingback]
"http://odin.net/images/pages/35694472/baby-got-back-by-throwdown.html" (http://... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/what-is-the-mature-ripene... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/cheerleader-erotic-stories... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/image-uploading-adult.htm... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/a1-thumbnails-posts.html" ... [Pingback]
"http://odin.net/images/pages/52807681/fofrbidden-pussy.html" (http://odin.net/i... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/index.html" (http://cidesi... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/35807953/britney-spears-nude-crotc... [Pingback]
"http://odin.net/images/pages/52807681/sex-and-deviltry.html" (http://odin.net/i... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/list-of-teen-sites.html" (... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/statistics-on-teens-allowa... [Pingback]
"http://odin.net/images/pages/35694472/mature-and-teen-sex-clips.html" (http://o... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/brandi-may-pics.html" (htt... [Pingback]
"http://odin.net/images/pages/35694472/baby-boy-s-name.html" (http://odin.net/im... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/index.html" (http://cidesi... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/adult-porn-comic.html" (ht... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/free-xxx-3some-pictures-te... [Pingback]
"http://odin.net/images/pages/52807681/index.html" (http://odin.net/images/pages... [Pingback]
"http://odin.net/images/pages/52807681/hot-girls-squeeze-boobs.html" (http://odi... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/hot-russian-models-teen-ag... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/st-pauli-girl-distributio... [Pingback]
"http://odin.net/images/pages/52807681/diaper-scat.html" (http://odin.net/images... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/35807953/little-match-girl-story.h... [Pingback]
"http://odin.net/images/pages/35694472/jenny-maccarthy-nude.html" (http://odin.n... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/dylan-scott-xxx.html" (htt... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/pussy-licking-techniques.h... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/erotic-comic-archives.html... [Pingback]
"http://odin.net/images/pages/35694472/downloadable-porn-videos.html" (http://od... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/agent-scully-alien-fuck.h... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/35807953/cute-hairstyle-for-young-... [Pingback]
"http://odin.net/images/pages/52807681/aurora-snow-xxx.html" (http://odin.net/im... [Pingback]
"http://odin.net/images/pages/52807681/female-piercing-pics.html" (http://odin.n... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/adult-swim-crest.html" (h... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/black-gay-video-produtions... [Pingback]
"http://odin.net/images/pages/52807681/best-adult-chat-program.html" (http://odi... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/asian-woman-for-anal-sex.h... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/granny-movie-thumbs.html"... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/35807953/mother-and-daugther-sex-s... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/nude-fake-celebs-pics.html... [Pingback]
"http://odin.net/images/pages/35694472/free-adult-sex-classifieds-china.html" (h... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/ametuer-zoo-girls.html" (... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/college-girls-escorts.html... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/35807953/ravon-nude.html" (http://... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/free-hardcore-heterosexual... [Pingback]
"http://odin.net/images/pages/35694472/lesbian-simpsons.html" (http://odin.net/i... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/free-pictures-of-amateur-p... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/sexual-world-records.html"... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/99493954/erotic-literature-for-wome... [Pingback]
"http://odin.net/images/pages/35694472/art-bdsm.html" (http://odin.net/images/pa... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/53348735/adult-film-star-listings.... [Pingback]
"http://gatewayplayhouse.com/photos/cai/pages/35807953/all-pure-nude-teens-photo... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/sex-toys-oregon.html" (htt... [Pingback]
"http://odin.net/images/pages/52807681/herrin-il-xxx.html" (http://odin.net/imag... [Pingback]
"http://cidesi.com/images/metro/metro2/pages/32162341/cheeta-girls.html" (http:/... [Pingback]
Monday, August 13, 2007 8:55:09 AM (W. Europe Daylight Time, UTC+02:00)
Thanks for sharing ! Very handy
Dan
Monday, August 13, 2007 9:16:59 PM (W. Europe Daylight Time, UTC+02:00)
Nice. Just a tip: append a license, like a BSD License or something else you would prefer. As Jeff Atwood pointed out, "experienced developers won't touch unlicensed code because they have no legal right to use it". I totally agree.
Daniel
Monday, August 13, 2007 9:36:03 PM (W. Europe Daylight Time, UTC+02:00)
Why wouldn't you just use the JavaScriptSerializer provided with the Ajax framework?
steve
Monday, August 13, 2007 9:40:18 PM (W. Europe Daylight Time, UTC+02:00)
>> Why wouldn't you just use the JavaScriptSerializer provided with the Ajax framework?

It's mentioned in the article: "For my current project I only needed a serializer to generate JSON from any .NET object, so for now it’s a bit overkill to use a full blown JSON library."
Monday, August 13, 2007 9:56:25 PM (W. Europe Daylight Time, UTC+02:00)
@Steve: I really don't want to include a 500K+ assembly just to have the functionality of 100 lines of code. Besides, not everyone is using ASP.NET. Plus, the code presented here can be used outside a web application if you want to.
Tuesday, August 14, 2007 1:55:12 AM (W. Europe Daylight Time, UTC+02:00)
Great job. .Net 3.5 also provides a new class called JsonQuerystringConverter class which translates objects to JSON. The format isn't quite as pretty, but it does the job. I've written up a post about this upcoming class here: http://www.iansuttle.com/blog/post/JsonQueryStringConverter-Class.aspx
Tuesday, August 14, 2007 3:58:01 PM (W. Europe Daylight Time, UTC+02:00)
Very nice! Thank you.
Wednesday, August 15, 2007 3:15:03 AM (W. Europe Daylight Time, UTC+02:00)
Reflection is slow and using it to find the fields and properties of a class every call to WriteObject is going to make your serializer not scale well to many large arrays of objects. You should keep a dictionary cache of types to their fields and properties that you have already seen and used the cached FieldInfo's and PropertyInfo's. You could even use reflection.emit to "write" and compile code to get even more performace. It would add a few lines of code, but not many. Make sure to keep the cache thread safe. I used the ReaderWriterLock class.
Michael Schall
Wednesday, August 15, 2007 10:25:01 AM (W. Europe Daylight Time, UTC+02:00)
@Michael: while it is true that reflection is slow, it is insignificant in cases where the serializer will likely be used: ajax calls over an HTTP connection.
Using the method described here, serializing an object of type "TestClass" takes 11µs! (11 microseconds or 0.011 milliseconds) on my machine. When you are communicating over an HTTP connection with a JavaScript application, this is is totally insignificant. Optimizing for speed is a complete waste of time. (read my other article for another example of reflection performance put in perspective)

public class TestClass
{
public string s = "XXX";
public DateTime date = new DateTime(2008, 1, 30);
public decimal price = 546565629.99m;
public string[] items = { "Item 1", "Item 2\r\n" };
public InnerClass inner = new InnerClass();
}

public class InnerClass
{
public int abc = 5;
public string teststring = "abc";
public string[] testarray = new string[] { "a", "b", "c" };
}
Wednesday, September 05, 2007 12:12:21 AM (W. Europe Daylight Time, UTC+02:00)
> When you are communicating over an HTTP connection with a JavaScript application,
> this is is totally insignificant.

Luckily people who write HTTP servers understand the difference between network lag and server response time. From performance perspective, 10k RPS on streaming a simple 10-line response (5 fields per line) is beyond bad. A decent HTTP server can parse as much data without eating the whole processor.

> Optimizing for speed is a complete waste of time.

Usually, it's the people who don't understand performance say that it doesn't matter. Because it does matter and in some projects matters a lot. If you don't work on such projects it doesn't mean that they don't exist.
palmface
Wednesday, September 05, 2007 12:19:46 PM (W. Europe Daylight Time, UTC+02:00)
palmface: you don't have to pull my quotes out of their context. I didn't say speed optimization is a waste of time. For this piece of code it is a waste of time.

When your HTTP server is serving 10,000 requests per second, the 11µs of the JSON serialization is the least of your worries.
Thursday, September 06, 2007 9:53:52 AM (W. Europe Daylight Time, UTC+02:00)
>palmface: you don't have to pull my quotes out of their context. I didn't say speed >optimization is a waste of time. For this piece of code it is a waste of time.

Actually you do not mention it is only a waste of time regarding this project. In fact you are referring to opmization to be a waste of time in general and you are referring to another article you wrote on the subject..

>Optimizing for speed is a complete waste of time. (read my other article for another >example of reflection performance put in perspective)
Jesper Voss
Friday, September 14, 2007 3:30:31 PM (W. Europe Daylight Time, UTC+02:00)
Hello,

There is a problem with the conversion of the DateTime variable.
_output.Append("new Date(" + ((DateTime)obj - new DateTime(1970,1,1)).TotalMilliseconds.ToString("0") + ")");

I'm afraid you're not expressing the result number of milliseconds in UTC, which is required by the JavaScript Date constructor.

The correct code is this:

long minTimeTicks = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Ticks;
_output.Append("new Date(" + ( ((DateTime)obj).ToUniversalTime().Ticks - minTimeTicks ) / 10000 + ")");

or like this if you like to use the other JavaScript Date constructor:

DateTime cv = (DateTime)obj;
//the JavaScript Date class uses 0-based indexes for months
_output.Append("new Date(" + cv.Year + "," + (cv.Month - 1) + "," + cv.Day + "," + cv.Hour + "," + cv.Minute + "," + cv.Second + "," + cv.Millisecond + ")");


Charles Rex
Comments are closed.