Monday, November 16, 2015

Effortless getting data out of a JSON REST response

One of the pains with using REST is getting the data from JSON into something usable. There is a very simple solution:  Take the JSON, pass it to a magic black box and get a dataset back that has foreign keys and other joys.   That sounds very nice --

  • Make the JSON REST call and then
  • Query or filter data tables to do future processing. No need to define classes to deserialize the JSON into.....
The code is horrible and shown below...
using System;
using System.Linq;
using System.Data;
using System.Xml;
using Newtonsoft.Json;
namespace Avalara.AvaTax.JsonUtilities
{
    public static class Utility
    {
        public static DataSet ConvertJsonToDataSet(string jsonText, string rootElementName)
        {
            var xd1 = new XmlDocument();
            xd1 =JsonConvert.DeserializeXmlNode( jsonText,rootElementName);
            var result = new DataSet();
            result.ReadXml(new XmlNodeReader(xd1));
            return result;
        }  
    }
}

To put this into a fuller context, consider the code below that does a get to any REST JSON url and returns a dataset

public static DataSet GetDataSet(string url, string rootName = "myroot")
{
    var webRequest = (HttpWebRequest)WebRequest.Create(url);
    webRequest.Method = "GET";
    webRequest.ContentType = "application/json, *.*";
    webRequest.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:28.0) Gecko/20100101 Firefox/28.0";
    webRequest.Headers.Add("AUTHORIZATION", Authorization);
    var webResponse = (HttpWebResponse)webRequest.GetResponse();
    if (webResponse.StatusCode != HttpStatusCode.OK) Console.WriteLine("{0}", webResponse.Headers);
    var json = String.Empty;
    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
    {
        json = reader.ReadToEnd();
        reader.Close();
    }
    // We must name the root element
    return DropUnusedTables(Utility.ConvertJsonToDataSet(json, rootName));
}

No longer do you need to deserialize to hand constructed classes to consume the data.

1 comment: