I am developing an adapter to a REST service that is returning a JSON string and am wondering if there is a better/more efficient way of doing what I am doing. What I am doing now currently works, but seems a little off in that there are nested foreach loops. I am using JSON.net and this is a console application:
Here is the JSON that is being returned:
{"skillsMetrics":{"201":{"avgTimeToAbandon":0,"totalTimeToAnswer":223,"totalTimeToAbandon":0,"enteredQEng":5,"avgTimeToAnswer":45,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":5}},"metricsTotals":{"avgTimeToAbandon":0,"totalTimeToAnswer":223,"totalTimeToAbandon":0,"enteredQEng":5,"avgTimeToAnswer":45,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":5}}
So the issue there is that "201" in this case is an ID field that will change as the Skill changes.
So as I said this code runs, but nested foreach loops seems not within the realm of good coding standards, but I am at a bit of a loss on how else to do this.
Here is my C#:
using (var reader = new StreamReader(response.GetResponseStream()))
{
var r = reader.ReadToEnd();
var parsedO = JObject.Parse(r);
foreach (var item in parsedO)
{
var i = item.Key;
var f = item.Value;
var parsedO2 = JObject.Parse(f.ToString());
foreach (var item1 in parsedO2)
{
var qHealth = new QueueHealth
{
SkillId = item1.Key,
avgTimeToAbandon = item1.Value.SelectToken("avgTimeToAbandon").Value<dynamic>(),
totalTimeToAnswer = item1.Value.SelectToken("totalTimeToAnswer").Value<dynamic>(),
totalTimeToAbandon = item1.Value.SelectToken("totalTimeToAbandon").Value<dynamic>(),
enteredQEng = item1.Value.SelectToken("enteredQEng").Value<dynamic>(),
avgTimeToAnswer = item1.Value.SelectToken("avgTimeToAnswer").Value<dynamic>(),
abandonmentRate = item1.Value.SelectToken("abandonmentRate").Value<dynamic>(),
abandonedEng = item1.Value.SelectToken("abandonedEng").Value<dynamic>(),
connectedEng = item1.Value.SelectToken("connectedEng").Value<dynamic>()
};
}
}
EDIT:
I forgot to put my class in here as well. The challenge is I need to pass that SkillID with it in order to do some data aggregation etc on the database side of the house. The data is going to be used in a reporting tool
public class QueueHealth
{
public string SkillId { get; set; }
public int avgTimeToAbandon { get; set; }
public int totalTimeToAnswer { get; set; }
public int totalTimeToAbandon { get; set; }
public int enteredQEng { get; set; }
public int avgTimeToAnswer { get; set; }
public double abandonmentRate { get; set; }
public int abandonedEng { get; set; }
public int connectedEng { get; set; }
}
public class QueueHealthContext : DbContext
{
public QueueHealthContext() : base(ConfigWrapper.AppConnectionString) { }
public DbSet<QueueHealth> QueuHealthTemp { get; set; }
}
}
Here is the multiple Skill JSON that is being returned:
{"skillsMetrics":{"64":{"avgTimeToAbandon":0,"totalTimeToAnswer":56,"totalTimeToAbandon":0,"enteredQEng":19,"avgTimeToAnswer":3,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":19},"201":{"avgTimeToAbandon":0,"totalTimeToAnswer":470,"totalTimeToAbandon":0,"enteredQEng":5,"avgTimeToAnswer":67,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":7},"65":{"avgTimeToAbandon":0,"totalTimeToAnswer":56,"totalTimeToAbandon":0,"enteredQEng":5,"avgTimeToAnswer":11,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":5},"66":{"avgTimeToAbandon":0,"totalTimeToAnswer":3,"totalTimeToAbandon":0,"enteredQEng":2,"avgTimeToAnswer":2,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":2},"202":{"avgTimeToAbandon":0,"totalTimeToAnswer":19,"totalTimeToAbandon":0,"enteredQEng":5,"avgTimeToAnswer":4,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":5},"199":{"avgTimeToAbandon":932,"totalTimeToAnswer":2802,"totalTimeToAbandon":2796,"enteredQEng":5,"avgTimeToAnswer":934,"abandonmentRate":0.5,"abandonedEng":3,"connectedEng":3},"198":{"avgTimeToAbandon":203,"totalTimeToAnswer":10488,"totalTimeToAbandon":405,"enteredQEng":178,"avgTimeToAnswer":62,"abandonmentRate":0.01,"abandonedEng":2,"connectedEng":168},"192":{"avgTimeToAbandon":0,"totalTimeToAnswer":41,"totalTimeToAbandon":0,"enteredQEng":3,"avgTimeToAnswer":10,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":4},"194":{"avgTimeToAbandon":0,"totalTimeToAnswer":2,"totalTimeToAbandon":0,"enteredQEng":1,"avgTimeToAnswer":2,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":1},"100":{"avgTimeToAbandon":0,"totalTimeToAnswer":68,"totalTimeToAbandon":0,"enteredQEng":19,"avgTimeToAnswer":3,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":20},"169":{"avgTimeToAbandon":0,"totalTimeToAnswer":2497,"totalTimeToAbandon":0,"enteredQEng":55,"avgTimeToAnswer":47,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":53},"168":{"avgTimeToAbandon":10,"totalTimeToAnswer":1728,"totalTimeToAbandon":10,"enteredQEng":37,"avgTimeToAnswer":48,"abandonmentRate":0.03,"abandonedEng":1,"connectedEng":36},"101":{"avgTimeToAbandon":0,"totalTimeToAnswer":0,"totalTimeToAbandon":0,"enteredQEng":1,"avgTimeToAnswer":0,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":1},"175":{"avgTimeToAbandon":0,"totalTimeToAnswer":5837,"totalTimeToAbandon":0,"enteredQEng":4,"avgTimeToAnswer":1459,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":4},"174":{"avgTimeToAbandon":1201,"totalTimeToAnswer":2144,"totalTimeToAbandon":1201,"enteredQEng":3,"avgTimeToAnswer":1072,"abandonmentRate":0.33,"abandonedEng":1,"connectedEng":2},"96":{"avgTimeToAbandon":0,"totalTimeToAnswer":18,"totalTimeToAbandon":0,"enteredQEng":5,"avgTimeToAnswer":4,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":5},"97":{"avgTimeToAbandon":0,"totalTimeToAnswer":352,"totalTimeToAbandon":0,"enteredQEng":4,"avgTimeToAnswer":70,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":5},"167":{"avgTimeToAbandon":40,"totalTimeToAnswer":8661,"totalTimeToAbandon":40,"enteredQEng":140,"avgTimeToAnswer":62,"abandonmentRate":0.01,"abandonedEng":1,"connectedEng":140},"46":{"avgTimeToAbandon":0,"totalTimeToAnswer":87,"totalTimeToAbandon":0,"enteredQEng":33,"avgTimeToAnswer":2,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":38},"45":{"avgTimeToAbandon":0,"totalTimeToAnswer":74,"totalTimeToAbandon":0,"enteredQEng":24,"avgTimeToAnswer":2,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":30},"55":{"avgTimeToAbandon":352,"totalTimeToAnswer":22025,"totalTimeToAbandon":1407,"enteredQEng":396,"avgTimeToAnswer":55,"abandonmentRate":0.01,"abandonedEng":4,"connectedEng":402},"59":{"avgTimeToAbandon":0,"totalTimeToAnswer":1463,"totalTimeToAbandon":0,"enteredQEng":39,"avgTimeToAnswer":37,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":40},"57":{"avgTimeToAbandon":0,"totalTimeToAnswer":3069,"totalTimeToAbandon":0,"enteredQEng":44,"avgTimeToAnswer":68,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":45},"56":{"avgTimeToAbandon":0,"totalTimeToAnswer":6740,"totalTimeToAbandon":0,"enteredQEng":114,"avgTimeToAnswer":58,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":116},"182":{"avgTimeToAbandon":0,"totalTimeToAnswer":6,"totalTimeToAbandon":0,"enteredQEng":3,"avgTimeToAnswer":2,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":3},"62":{"avgTimeToAbandon":0,"totalTimeToAnswer":871,"totalTimeToAbandon":0,"enteredQEng":1,"avgTimeToAnswer":871,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":1},"61":{"avgTimeToAbandon":0,"totalTimeToAnswer":2015,"totalTimeToAbandon":0,"enteredQEng":1,"avgTimeToAnswer":672,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":3},"180":{"avgTimeToAbandon":0,"totalTimeToAnswer":6,"totalTimeToAbandon":0,"enteredQEng":3,"avgTimeToAnswer":2,"abandonmentRate":0.0,"abandonedEng":0,"connectedEng":3},"60":{"avgTimeToAbandon":849,"totalTimeToAnswer":11973,"totalTimeToAbandon":3394,"enteredQEng":16,"avgTimeToAnswer":1330,"abandonmentRate":0.31,"abandonedEng":4,"connectedEng":9}},"metricsTotals":{"avgTimeToAbandon":578,"totalTimeToAnswer":83569,"totalTimeToAbandon":9253,"enteredQEng":1165,"avgTimeToAnswer":71,"abandonmentRate":0.01,"abandonedEng":16,"connectedEng":1170}}