Scott Scott - 2 months ago 16
C# Question

Dynanically create JSON object for datareader results, regardless of what they look like?

Right now I'm using

Newtonsoft.json
with my
OdbcConnection
and manually creating objects for each query I run. It looks something like this:

Classes:

public class payload
{
public string id;
public string type;
public DateTime timestmap;
public object data;
}
public class resultPhrLastTime
{
public string facilityId;
public string type;
public string time;
}


Code:

payload result = new payload();
var resultList = new List<resultPhrLastTime>();
result.id = "someid";

//connection stuff

while (reader.Read())
{
var t = new resultPhrLastTime();
//if (verbose) log(reader[0].ToString());
t.facilityId = reader[0].ToString();
t.type = reader[1].ToString();
t.time = reader[2].ToString();
resultList.Add(t);
}

result.data = resultList;
result.timestmap = DateTime.Now;
result.type = "complex";
string output = JsonConvert.SerializeObject(result);


This works fine, but every time I add a new query to my app (of which there will be many) I have to create a new custom class if the data looks different at all.

I would like to find a way to convert the entire
reader
object to JSON regardless of the format, so it may look like this:


SQL Result:

2814814


JSON:

result: {
timestamp: 2016-09-10 8:15,
data: { '2814814' }
}



or it may look like this:


SQL Result:

Apple | 59
Orange | 17


JSON:

result: {
timestamp: 2016-09-10 8:15,
data: {[
'Apple':'59',
'Orange':'17'
]}
}



Or there could be 5 columns...

Is there a way to do this?

Answer

You can use the dynamic type of c#

public class payload
{
    public string id;
    public string type;
    public DateTime timestmap;
    public dynamic data;
}


payload result = new payload();
var resultList = new List<Dictionary<string, dynamic>>();
result.id = "someid";

//connection stuff

while (reader.Read())
{

    var t = new Dictionary<string, dynamic>();
    for (var i = 0; i<reader.FieldCount; i++)
    {
        t[reader.GetName(i)] = reader[i];
    }
    resultList.Add(t);
}

result.data = resultList;
result.timestmap = DateTime.Now;
result.type = "complex";
string output = JsonConvert.SerializeObject(result);

The dynamic type is handled by JsonConvert automatically.

You can also make the data field of the payload to a dynamic to handle single field results like in your first JSON example.

Comments