Saturday, March 12, 2011

Nice syntax to read JSon in C#

I am working on a prototype involving MongoDB and HTML5, so it is going to be a lot about JavaScript.
So I want to able to define my configuration files in JavaScript/JSON, rather than using IronPython, like I did in the past. I turned to Json.NET to parse the JSon and came up with this idea.

My JSON File
{
  'Name'    : 'Apple',
  'Expiry'  : '2000-01-02T00:00:00.000Z',
  'Price'   : 3.99,
  'Quantity': 123,
  'Sizes'   : ['Small','Medium','Large']
}
My C# Syntax to get access to the properties of my instance
dynamic config  = new JSonConfiguration(JSon_TestString);

    DateTime expiry = config.Expiry;
    string name     = config.Name;
    double price    = config.Price;            
    int quantity    = config.Quantity;
    string size0    = config.Sizes[0]; 
  
    int? quantity2  = config.Quantity2;
If a property does not exist the value returned is null. Date are supported as described, as you may not know JSON does not support Date, so they is no real standard.
While I was at it I also added this syntax:
dynamic config  = new JSonConfiguration(JSon_TestString);

    DateTime expiry = config["Expiry"];
    string name     = config["Name"];
    double price    = config["Price"];
    int quantity    = config["Quantity"];
    string size0    = config["Sizes"][0];

    int? quantity2  = config["Quantity2"];     
The class JSonConfiguration, does not support nested objects, it is just a simple config file reader.
Here is the magic class.
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using DynamicSugarSharp;
using System.Dynamic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public class JSonConfiguration : DynamicObject {

        JObject _jSonObject = null;

        public JSonConfiguration(string json){

            _jSonObject = JObject.Parse(json); 
        }
        public override bool TryGetIndex(GetIndexBinder binder, Object[] indexes, out Object result){
            
            return __TryGetMember(indexes[0].ToString(), out result);
        }
        public override bool TryGetMember(GetMemberBinder binder, out object result) {
            
            return __TryGetMember(binder.Name, out result);
        }
        private bool IsDate(string s) {

            // "2000-12-15T22:11:03.055Z"
            var rx = @"^""\d{2,4}-\d{1,2}-\d{1,2}T\d{1,2}:\d{1,2}:\d{1,2}.*Z""$";
            return System.Text.RegularExpressions.Regex.IsMatch(s,rx);            
        }
        private bool __TryGetMember(string Name, out object result) {

            result = _jSonObject[Name];

            if(result!=null){

                if(IsDate(result.ToString())){ // Date

                    result = JsonConvert.DeserializeObject<DateTime>(result.ToString(), new IsoDateTimeConverter());
                }
            }
            return true;
        }
    }

No comments:

Post a Comment