C# Deserialization of JSON for use in a foreach loop - c#

I have json that is posted from a HTTP req. I am trying to deserialize it for use in a for each loop. Unfortunately, its format is kicking my ass as its a list of objects (i believe).
so far i have the following:
dynamic jsonObj = JsonConvert.DeserializeObject(await req.ReadAsStringAsync());
foreach (var p in jsonObj.hireSchedules)
{
///do something
}
My json is as below:
{
"hireSchedules": [
{
"plant": "7246054",
"num" : "79",
"hire": "1137277"
},
{
"plant": "7246055",
"num" : "80",
"hire": "1137278"
}
]
}
I have the following classes:
public class HireSchedule
{
public string plant { get; set; }
public string num { get; set; }
public string hire { get; set; }
}
public class RootObject
{
public List<HireSchedule> hireSchedules { get; set; }
}
Any help would be appreciated. Thanks!

Since you have already defined the classes it's easy enough to deserialize it into them. Then you have a strongly typed class and the IDE should be able to help you out how to access the properties.
var json = File.ReadAllText("json1.json");
var root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (var p in root.hireSchedules)
{
///do something
}

One of the way is to use Newtonsoft.json nuget which is really very powerful, so
var files = JObject.Parse(YourJSON);
var recList = files.SelectTokens("$..hireSchedules").ToList();
foreach (JObject obj in recList.Children())
{
foreach (JProperty prop in obj.Children())
{
var key = prop.Name.ToString();
var value = prop.Value.ToString();
//Do your stuffs here
}
}

Related

How can i access fields of anonymous typed JArray in C#?

string sampleString = "[{\"id\":\"1\",\"status\":302},{\"id\":\"2\",\"status\":302},{\"id\":\"3\",\"status\":302},{\"id\":\"4\",\"status\":302}]";
JArray json = JArray.Parse(sampleString );
TempValue t;
foreach(JObject obj in json)
{
t = new TempValue {
id =//id of json,
status=//state of json
};
}
i want to access value of json anonymous objec to assign to t object.
It is always good to work with a typed object to avoid typing mistakes. In this case create a class with the structure of the json string like so:
public class StatusObj
{
public string id { get; set; }
public int status { get; set; }
}
The deserialize the json string to list of your class like so:
List<StatusObj> obj = JsonConvert.DeserializeObject<List<StatusObj>>(sampleString);
And then you can loop through the list like so:
foreach (var item in obj)
{
var id = item.id;
var status = item.status;
}
The whole code look like this:
class Program
{
static void Main(string[] args)
{
string sampleString = "[{\"id\":\"1\",\"status\":302},{\"id\":\"2\",\"status\":302},{\"id\":\"3\",\"status\":302},{\"id\":\"4\",\"status\":302}]";
List<StatusObj> obj = JsonConvert.DeserializeObject<List<StatusObj>>(sampleString);
foreach (var item in obj)
{
var id = item.id;
var status = item.status;
}
}
}
public class StatusObj
{
public string id { get; set; }
public int status { get; set; }
}
NB. Newtonsoft.Json package needed to be installed. You can also convert any json to class here
By the indexer
foreach(JObject obj in json)
{
t = new TempValue {
id = obj["id"].ToString() ,
...
};
Object.Item Property (String)
Gets or sets the JToken with the specified property name.

Converting JSON array

I am attempting to use the Newtonsoft JSON library to parse a JSON string dynamically using C#. In the JSON is a named array. I would like to remove the square brackets from this array and then write out the modified JSON.
The JSON now looks like the following. I would like to remove the square bracket from the ProductDescription array.
{
"Product": "123",
"to_Description": [
{
"ProductDescription": "Product 1"
}
]
}
Desired result
{
"Product": "123",
"to_Description":
{
"ProductDescription": "Product 1"
}
}
I believe I can use the code below to parse the JSON. I just need some help with making the modification.
JObject o1 = JObject.Parse(File.ReadAllText(#"output.json"));
The to_Description property starts off as List<Dictionary<string,string>> and you want to take the first element from the List.
So, given 2 classes
public class Source
{
public string Product {get;set;}
public List<Dictionary<string,string>> To_Description{get;set;}
}
public class Destination
{
public string Product {get;set;}
public Dictionary<string,string> To_Description{get;set;}
}
You could do it like this:
var src = JsonConvert.DeserializeObject<Source>(jsonString);
var dest = new Destination
{
Product = src.Product,
To_Description = src.To_Description[0]
};
var newJson = JsonConvert.SerializeObject(dest);
Note: You might want to check there really is just 1 item in the list!
Live example: https://dotnetfiddle.net/vxqumd
You do not need to create classes for this task. You can modify your object like this:
// Load the JSON from a file into a JObject
JObject o1 = JObject.Parse(File.ReadAllText(#"output.json"));
// Get the desired property whose value is to be replaced
var prop = o1.Property("to_Description");
// Replace the property value with the first child JObject of the existing value
prop.Value = prop.Value.Children<JObject>().FirstOrDefault();
// write the changed JSON back to the original file
File.WriteAllText(#"output.json", o1.ToString());
Fiddle: https://dotnetfiddle.net/M83zv3
I have used json2csharp to convert the actual and desired output to classes and manipulated the input json.. this will help in the maintenance in future
First defined the model
public class ToDescription
{
public string ProductDescription { get; set; }
}
public class ActualObject
{
public string Product { get; set; }
public List<ToDescription> to_Description { get; set; }
}
public class ChangedObject
{
public string Product { get; set; }
public ToDescription to_Description { get; set; }
}
Inject the logic
static void Main(string[] args)
{
string json = "{\"Product\": \"123\", \"to_Description\": [ { \"ProductDescription\": \"Product 1\" } ]} ";
ActualObject actualObject = JsonConvert.DeserializeObject<ActualObject>(json);
ChangedObject changedObject = new ChangedObject();
changedObject.Product = actualObject.Product;
changedObject.to_Description = actualObject.to_Description[0];
string formattedjson = JsonConvert.SerializeObject(changedObject);
Console.WriteLine(formattedjson);
}
Why not:
public class EntityDescription
{
public string ProductDescription { get; set; }
}
public class Entity
{
public string Product { get; set; }
}
public class Source : Entity
{
[JsonProperty("to_Description")]
public EntityDescription[] Description { get; set; }
}
public class Target : Entity
{
[JsonProperty("to_Description")]
public EntityDescription Description { get; set; }
}
var raw = File.ReadAllText(#"output.json");
var source = JsonConvert.DeserializeObject<Source>(raw);
var target = new Target { Product = source.Product, Description = source.Description.FirstOrDefault() };
var rawResult = JsonConvert.SerializeObject(target);
Update For dynamic JSON
var jObject = JObject.Parse(File.ReadAllText(#"output.json"));
var newjObject = new JObject();
foreach(var jToken in jObject) {
if(jToken.Value is JArray) {
List<JToken> l = jToken.Value.ToObject<List<JToken>>();
if(l != null && l.Count > 0) {
newjObject.Add(jToken.Key, l.First());
}
} else {
newjObject.Add(jToken.Key, jToken.Value);
}
}
var newTxt = newjObject.ToString();

.net json deserializer failing for google api returned json result

I am unable to deserialize the json result I am getting from google api during an API call. The API request is successful, but I can't deserialize it.
Code for deserialization is as follows :
var datareceived = JsonConvert.DeserializeObject<RootObject>(response);
Please find below the json I am getting from Google api(response object in above code) :
{"result":[]}
{"result":[{"alternative":[{"transcript":"distance between the trees","confidence":0.46962094},{"transcript":"Justin prescription that reason"},{"transcript":"Justin Swift accessories"},{"transcript":"justice respiratory"},{"transcript":"Justin syska accessories"}],"final":true}],"result_index":0}
Exception Details :
Message = "Additional text encountered after finished reading JSON content: {. Path '', line 2, position 0."
RootObject Class :
public class RootObject
{
public List<Result> result { get; set; }
public int result_index { get; set; }
}
Any help would be highly appreciated!
you just can't parse this JSON as it is because } symbolize the end of JSON
but you can do something like this
string json = "{\"result\":[]}\r\n{\"result\":[{\"alternative\":[{\"transcript\":\"distance between the trees\",\"confidence\":0.46962094},{\"transcript\":\"Justin prescription that reason\"},{\"transcript\":\"Justin Swift accessories\"},{\"transcript\":\"justice respiratory\"},{\"transcript\":\"Justin syska accessories\"}],\"final\":true}],\"result_index\":0}";
string trueJson = json.Split(new[] { Environment.NewLine }, StringSplitOptions.None)[1];
try
{
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(trueJson);
rootObject = rootObject;
}
catch (Exception ex)
{
throw;
}
public class Alternative
{
public string transcript { get; set; }
public double confidence { get; set; }
}
public class Result
{
public List<Alternative> alternative { get; set; }
public bool final { get; set; }
}
public class RootObject
{
public List<Result> result { get; set; }
public int result_index { get; set; }
}
You can utilize following method to get JSON in List:
public List<string> GetJsonItems(string jsonString)
{
int bracketCount = 0;
List<string> jsonItems = new List<string>();
StringBuilder Json = new StringBuilder();
foreach (char c in jsonString)
{
if (c == '{')
++bracketCount;
else if (c == '}')
--bracketCount;
Json.Append(c);
if (bracketCount == 0 && c != ' ')
{
jsonItems.Add(Json.ToString());
Json = new StringBuilder();
}
}
return jsonItems;
}
Then utilize it like:
List<string> strings = GetJsonItems(response.Replace(Environment.NewLine, String.Empty));
if (strings.Length > 1)
{
List<Rootobject> allResultSet = new List<Rootobject>();
foreach (var str in strings)
{
Rootobject items = JsonConvert.DeserializeObject<Rootobject>(str);
if (items.result.Length > 0)
{
allResultSet.Add(items);
}
}
}
It seems that each line of the result contains a separate JSON object. (It's not clear why the API doesn't return an actual JSON array instead.) If this is the case, you can split the response into lines and parse each line separately:
string[] lines = response.Split(new char[]{'\r','\n'},StringSplitOptions.RemoveEmptyEntries);
var datareceived1 = JsonConvert.DeserializeObject<RootObject>(lines[0]);
... and so on.

C#: How to parse HttpWebResponse object?

I can explain this question better in terms of code and example. This is my code so far:
url = "x";
// create the request
req = WebRequest.CreateHttp(url);
req.ClientCertificates.Add(Program.GetCert(thumbprint));
result = (HttpWebResponse)req.GetResponse();
using (Stream data = result.GetResponseStream())
{
if (data != null)
{
TextReader tr = new StreamReader(data);
json = tr.ReadToEnd();
}
}
System.Diagnostics.Debug.WriteLine(json);
This is the output of the code:
{ "field1":"blah","field2":[
{
"Id":"1","Name":"Jon"
},{
"Id":"2","Name":"Mark"}] }
What I want to do-->
Access field2 of that json and iterate through ids and names (I don't care about field1 at all). How can I do that? Has this got anything to do with serialization?
one possible solution is -
var o = (JArray)(JObject.Parse(json)["field2"]);
foreach (JToken token in o)
{
Console.WriteLine(token["Id"]);
Console.WriteLine(token["Name"]);
}
Alternatively, you could create strongly typed C# objects and access them as a list -
static void Main(string[] args)
{
var o = JsonConvert.DeserializeObject<RootObject>(json).field2;// list - count = 2
}
public class Field2
{
public string Id { get; set; }
public string Name { get; set; }
}
public class RootObject
{
public string field1 { get; set; }
public List<Field2> field2 { get; set; }
}
Use the DataContractJsonSerializer Class with suitable DataContract classes (Using Data Contracts), to deserialize your JSON data to objects.
Then you can iterate your way through the data.
First install Json.NET and try something like:
dynamic stuff = JObject.Parse(json);
var field2 = (JArray)stuff["field2"];
var field2Dict = field2.ToDictionary(k => (string)k["Id"], x => (string)x["Name"]);
foreach (var item in field2Dict)
{
System.Diagnostics.Debug.WriteLine("Id: {0} Nam: {1}", item.Key, item.Value);
}

Create Json Array with ServiceStack

Quite new to .NET. Still haven't gotten the hang of how to do dictionaries, lists, arrays, etc.
I need to produce this JSON in order to talk to SugarCRM's REST API:
{
"name_value_list": {
"assigned_user_name": {
"name": "assigned_user_name",
"value": "joe"
},
"modified_by_name": {
"name": "modified_by_name",
"value": "jill"
},
"created_by_name": {
"name": "created_by_name",
"value": "jack"
}
}
}
from this C# POCO, which plays nicely with ServiceStack:
public class lead {
public string assigned_user_name { get; set; }
public string modified_by_name { get; set; }
public string created_by_name { get; set; }
}
I have to do this sort of conversion for lots of different classes, so I don't think it's wise to create another strongly typed class (ala Costomising the serialisation/serialised JSON in service stack)
I've looked through the ServiceStack docs, but maybe I missed an example of this somewhere.
How do I build this JSON in a way that I can extend to other ServiceStack POCOs?
This produces the right JSON:
Dictionary<string, Dictionary<string, string>> nameValues = new Dictionary<string, Dictionary<string, string>>();
// Deal with all the properties on the object
IList<PropertyInfo> props = new List<PropertyInfo>(this.GetType().GetProperties());
foreach (PropertyInfo prop in props)
{
Dictionary<string, string> nameValue = new Dictionary<string, string>();
nameValue.Add("name", prop.Name);
object propValue = prop.GetValue(this, null);
if (propValue == null)
{
nameValue.Add("value", string.Empty);
}
else
{
nameValue.Add("value", prop.GetValue(this, null).ToString());
}
nameValues.Add(prop.Name, nameValue);
}
Dictionary<string, object> nameValuesArray = new Dictionary<string, object>();
nameValuesArray.Add("name_value_list", nameValues);
string jsonString = JsonSerializer.SerializeToString<Dictionary<string, object>>(nameValuesArray);
The reflection stuff is so that I can use it on any object later.
It's just a matter of constructing the right dictionary for the desired JSON output - in this case a dictionary -> dictionary -> dictionary. Trial and error... :/
Update
Altered it slightly (thanks paaschpa) to use a generic NameValue class because Dictionaries look ugly. I also got the requirements wrong. The JSON should be this:
[
{
"name": "id",
"value": "60e03cb3-df91-02bd-91ae-51cb04f937bf"
},
{
"name": "first_name",
"value": "FancyPants"
}
]
which you can do like this:
public class NameValue
{
public string name { get; set; }
public string value { get; set; }
}
public class Lead
{
public string assigned_user_name { get; set; }
public string modified_by_name { get; set; }
public string modified_user_name { get; set; }
public List<NameValue> toNameValues()
{
List<NameValue> nameValues = new List<NameValue>();
IList<PropertyInfo> props = new List<PropertyInfo>(this.GetType().GetProperties());
foreach (PropertyInfo prop in props)
{
NameValue nameValue = new NameValue();
object propValue = prop.GetValue(this, null);
if (propValue != null && !String.IsNullOrEmpty(propValue.ToString()))
{
nameValue.name = prop.Name;
nameValue.value = propValue.ToString();
nameValues.Add(nameValue);
}
}
return nameValues;
}
}
I'm leaving my original question as is (and my above answer) because it's still a legit example and proper JSON.
Well, I don't think .NET dictionaries, lists, arrays, etc. will be helpful since the JSON you listed doesn't appear to have any arrays (square brackets) it in. I'm guessing most .NET JSON serializers will use square brackets when it hits these types. So, I think this leaves creating your own classes or doing some type of 'string magic' to produce to JSON you need.
Not exactly sure how you are using ServiceStack to talk to SugarCRM, but doing something like below should have ServiceStack.Text.JsonSerializer produce the JSON string you listed.
public class NameValue
{
public string name { get; set; }
public string value { get; set; }
}
public class Lead
{
public NameValue assigned_user_name { get; set; }
public NameValue modified_by_name { get; set; }
public NameValue created_by_name { get; set; }
}
public class LeadRequest
{
public Lead name_value_list { get; set; }
}
public void JsonTest()
{
var req = new LeadRequest
{
name_value_list = new Lead
{
assigned_user_name = new NameValue {name = "assigned_user_name", value = "joe"},
modified_by_name = new NameValue {name = "modified_by_name", value = "jill"},
created_by_name = new NameValue {name = "created_by_name", value = "jack"}
}
};
var jsonReq = ServiceStack.Text.JsonSerializer.SerializeToString(req);
}
You could create a custom serializer for the lead class.
JsConfig<lead>.SerializeFn = lead => {
// Use reflection to loop over the properties of the `lead` object and build a dictionary
var data = new Dictionary<string, object>();
foreach (var property in typeof(lead).GetProperties()) {
data[property.Name] = new {
name: property.Name,
value: property.GetValue(lead, null);
};
}
return data.ToJson();
};
You could make this generic by having all classes that you want to serialize in this way implement a marker interface, for example ISugarCrmRequest, and register this custom serializer for all implementations of that interface.

Categories