Wednesday, May 22, 2013

DynamicJsonConverter


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;

private sealed class DynamicJsonConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
    }

    #region Nested type: DynamicJsonObject

    private sealed class DynamicJsonObject : DynamicObject
    {
        private readonly IDictionary<string, object> _dictionary;

        public DynamicJsonObject(IDictionary<string, object> dictionary)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");
            _dictionary = dictionary;
        }

        public override string ToString()
        {
            var sb = new StringBuilder("{");
            ToString(sb);
            return sb.ToString();
        }

        private void ToString(StringBuilder sb)
        {
            var firstInDictionary = true;
            foreach (var pair in _dictionary)
            {
                if (!firstInDictionary)
                    sb.Append(",");
                firstInDictionary = false;
                var value = pair.Value;
                var name = pair.Key;
                if (value is string)
                {
                    sb.AppendFormat("{0}:\"{1}\"", name, value);
                }
                else if (value is IDictionary<string, object>)
                {
                    new DynamicJsonObject((IDictionary<string, object>)value).ToString(sb);
                }
                else if (value is ArrayList)
                {
                    sb.Append(name + ":[");
                    var firstInArray = true;
                    foreach (var arrayValue in (ArrayList)value)
                    {
                        if (!firstInArray)
                            sb.Append(",");
                        firstInArray = false;
                        if (arrayValue is IDictionary<string, object>)
                            new DynamicJsonObject((IDictionary<string, object>)arrayValue).ToString(sb);
                        else if (arrayValue is string)
                            sb.AppendFormat("\"{0}\"", arrayValue);
                        else
                            sb.AppendFormat("{0}", arrayValue);

                    }
                    sb.Append("]");
                }
                else
                {
                    sb.AppendFormat("{0}:{1}", name, value);
                }
            }
            sb.Append("}");
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (!_dictionary.TryGetValue(binder.Name, out result))
            {
                // return null to avoid exception.  caller can check for null this way...
                result = null;
                return true;
            }

            var dictionary = result as IDictionary<string, object>;
            if (dictionary != null)
            {
                result = new DynamicJsonObject(dictionary);
                return true;
            }

            var arrayList = result as ArrayList;
            if (arrayList != null && arrayList.Count > 0)
            {
                if (arrayList[0] is IDictionary<string, object>)
                    result = new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x)));
                else
                    result = new List<object>(arrayList.Cast<object>());
            }

            return true;
        }
    }

    #endregion
}



string json = ...;

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

dynamic obj = serializer.Deserialize(json, typeof(object));
So, given a JSON string:
{
  "Items":[
    { "Name":"Apple", "Price":12.3 },
    { "Name":"Grape", "Price":3.21 }
  ],
  "Date":"21/11/2010"
}
The following code will work at runtime:
var data = serializer.Deserialize(json, typeof(object));

data.Date; // "21/11/2010"
data.Items.Count; // 2
data.Items[0].Name; // "Apple"
data.Items[0].Price; // 12.3 (as a decimal)
data.Items[1].Name; // "Grape"
data.Items[1].Price; // 3.21 (as a decimal)
Ref
http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object?answertab=votes#tab-top

Monday, May 20, 2013

JSON Examples


JSON Examples

Array
Array typically consist of number, string, boolean, or null values and can also include nested arrays and nested objects. An array's elements are comma-delimited and are contained in brackets.

var newArray = [ "Text goes here", 29, true, null ]
var otherArray = [ [...], {...} ]
console.log( newArray[2] );true
Array with objects
This array consists of comma-delimited, nested objects which ceach ontain multiple key/value pairs- also comma-delimited. These objects can be accessed using the array's variable name and an index.

var newArray = [
 { "name": "Dagny Taggart", "age": 39 },
 { "name": "Francisco D'Anconia", "age": 40 },
 { "name": "Hank Rearden", "age": 46 }
]
console.log( newArray[0].name );Dagny Taggart
Object
This object consists of several key/value pairs. These 'properties' can be accessed using the the object's variable name followed by a period and property name -or- can be accessed like an array using the property name in quotes (in place of an index).

newObject = {
 "first": "Jimmy",
 "last": "James",
 "age": 29,
 "sex": "M",
 "salary": 63000,
 "registered": false
}
console.log( newObject.salary );63000

console.log( newObject["salary"] );63000
Object with nested array
This object contains comma-delimited key/value pairs and a nested array. The nested array can be accessed with the object name, property or 'key' containing the array and an array index.

newObject = {
 "first": "John",
 "last": "Doe",
 "age": 39,
 "sex": "M",
 "salary": 70000,
 "registered": true,
 "interests": [ "Reading", "Mountain Biking", "Hacking" ]
}
console.log( newObject.interests[0] );Reading

console.log( newObject["interests"][0] );Reading
Object with nested object
This object contains multiple comma-delimited key/value pairs and a nested object. To access an object within an object, property names or 'keys' can be chained together -or- property names can be used like an array in place of indexes.

newObject = {
 "first": "John",
 "last": "Doe",
 "age": 39,
 "sex": "M",
 "salary": 70000,
 "registered": true,
 "favorites": {
  "color": "Blue",
  "sport": "Soccer",
  "food": "Spaghetti"
 }
}
console.log( newObject.favorites.food );Spaghetti

console.log( newObject["favorites"]["food"] );Spaghetti
Object with nested arrays and objects
This object is more complex and typical of what might come from an API. It contains key/value pairs, nested arrays and nested objects. Any of its elements can be accessed with a combination of the above techniques.

newObject = {
 "first": "John",
 "last": "Doe",
 "age": 39,
 "sex": "M",
 "salary": 70000,
 "registered": true,
 "interests": [ "Reading", "Mountain Biking", "Hacking" ],
 "favorites": {
  "color": "Blue",
  "sport": "Soccer",
  "food": "Spaghetti"
 },
 "skills": [
  {
   "category": "PHP",
   "tests": [
    { "name": "One", "score": 90 },
    { "name": "Two", "score": 96 }
   ]
  },
  {
   "category": "CouchDB",
   "tests": [
    { "name": "One", "score": 32 },
    { "name": "Two", "score": 84 }
   ]
  },
  {
   "category": "Node.js",
   "tests": [
    { "name": "One", "score": 97 },
    { "name": "Two", "score": 93 }
   ]
  }
 ]
}
console.log( newObject.skills[0].category );PHP

console.log( newObject["skills"][0]["category"] );PHP

console.log( newObject.skills[1].tests[0].score );32

console.log( newObject["skills"][1]["tests"][0]["score"] );32

Ref  http://www.jsonexample.com/#array-with-objects

8 ways to query json structures



8 ways to query json structures
Do you get bored by complex JSON structure traversing to find just a bunch of matching entries ?

Here are 8 different ways to do it :
JsonSQL

JsonSQL implements SQL select statements over json structures.

Example:

jsonsql.query("select * from json.channel.items order by title desc",json);

Homepage: http://www.trentrichardson.com/jsonsql/
JSONPath

JSONPath is like XPath for JSON structures.

Example :

jsonPath( books, '$..book[(@.length-1)]')

Homepage: http://goessner.net/articles/JsonPath/
jfunk

jFunk will allow you to retrieve (and soon, manipulate) objects within complex JSON or Javascript objects. The design of the jFunk API will closely parallel the jQuery API, replicating it exactly except where the differences between DOM and Javascript make replication nonsensical

Example:

Jf("> vegetables > *[color=Orange]",Food).get();

Homepage: http://code.google.com/p/jfunk/
TaffyDB

How you ever noticed how JavaScript object literals look a lot like records? And that if you wrap a group of them up in an array you have something that looks a lot like a database table? TaffyDB is a libary to bring powerful database funtionality to that concept and rapidly improve the way you work with data inside of JavaScript.

var kelly = friends({id:2}).first();

Homepage: http://www.taffydb.com/
linq.js

linq.js - LINQ for JavaScript

var queryResult2 = Enumerable.From(jsonArray)
    .Where("$.user.id < 200")
    .OrderBy("$.user.screen_name")
    .Select("$.user.screen_name + ':' + $.text")
    .ToArray();
Homepage: http://linqjs.codeplex.com/

Homepage: http://neue.cc/reference.htm
objeq

objeq is a simple library that allows POJSO's (Plain-Old JavaScript Objects) to be queried in real-time.
var res = $objeq(data, "age > 40 && gender == 'female' -> name");
// --> Returns ['Jessica']
Homepage: https://github.com/agilosoftware/objeq
json:select()

CSS-like selectors for JSON.

.lang:val("Bulgarian") ~ .level

Homepage: http://jsonselect.org/#tryit
Javascript Array Filtering from Paul's Programming Pearls

var a = [1,2,3,4,5,6,7,8,9,10];
    // return everything
    a.where( "( ) => true" ) ;
        --> [1,2,3,4,5,6,7,8,9,10]
    // return even numbers
    a.where( "( n, i ) => n % 2 == 0" ) ;
        --> [2,4,6,8,10]
    // query first 6 products whose category begins with 'con' using extra param and regular expression
    products.where( "( el, i, res, param ) => res.length <= 6 && param.test( el.cat )", /^con/i);
    // using customer table data from SQL Server's northwind database...  
    customers.where( "( el, i, res, param ) => el.country == param", "USA" );


Homepage: http://www.paulfree.com/28/javascript-array-filtering/#more-28

Javascript Array Filtering from Paul's Programming Pearls is currently my favorite - its extremely small footprint and blazing fast result speak for itself.

The idea behind is similar to John Resig's JavaScript Micro-Templating effort - a very simple piece of code transforming a string into a Javascript function utilizing Regexp power.

Yes, sure - there are more powerful solutions in the list. Paul's implementation prototype lacks syntax checking of the filter expression but I am sure you can handle javascript syntax checking by yourself.

At the end you must decide which one is best for your project.

Monday, May 6, 2013

Chromium debugger

don't know what version of Chrome you're using. I'm using Chromium 17 and the Javascript debugger looks like this when hitting a breakpoint (emphasis mine):

Chromium call stack

Immediate window


One nice feature of the Immediate Window in Visual Studio is its ability to evaluate the return value of a method particularly if it is called by your client code but it is not part of a variable assignment. In Debug mode, as mentioned, you can interact with variables and execute expressions in memory which plays an important role in being able to do this.

For example, if you had a static method that returns the sum of two numbers such as:

private static int GetSum(int a, int b)
{
    return a + b;
}
Then in the Immediate Window you can type the following:

? GetSum(2, 4)
6
As you can seen, this works really well for static methods. However, if the method is non-static then you need to interact with a reference to the object the method belongs to.

For example, let’s say this is what your class looks like:

private class Foo
{
    public string GetMessage()
    {
        return "hello";
    }
}
If the object already exists in memory and it’s in scope, then you can call it in the Immediate Window as long as it has been instantiated before your current breakpoint (or, at least, before wherever the code is paused in debug mode):

? foo.GetMessage(); // object ‘foo’ already exists
"hello"
In addition, if you want to interact and test the method directly without relying on an existing instance in memory, then you can instantiate your own instance in the Immediate Window:

? Foo foo = new Foo(); // new instance of ‘Foo’
{temp.Program.Foo}
? foo.GetMessage()
"hello"
You can take it a step further and temporarily assign the method's results to variables if you want to do further evaluations, calculations, etc.:

? string msg = foo.GetMessage();
"hello"
? msg + " there!"
"hello there!"
Furthermore, if you don’t even want to declare a variable name for a new object and just want to run one of its methods/functions then do this:

? new Foo().GetMessage()
"hello"
A very common way to see the value of a method is to select the method name of a class and do a ‘Add Watch’ so that you can see its current value in the Watch window. However, once again, the object needs to be instantiated and in scope for a valid value to be displayed. This is much less powerful and more restrictive than using the Immediate Window.

Along with inspecting methods, you can do simple math equations:

? 5 * 6
30
or compare values:

? 5==6
false
? 6==6
true
The question mark ('?') is unnecessary if you are in directly in the Immediate Window but it is included here for clarity (to distinguish between the typed in expressions versus the results.) However, if you are in the Command Window and need to do some quick stuff in the Immediate Window then precede your statements with '?' and off you go.

Intellisense works in the Immediate Window, but it sometimes can be a bit inconsistent. In my experience, it seems to be only available in Debug mode, but not in design, non-debug mode.

Unfortunately, another drawback of the Immediate Window is that it does not support loops.