Verify Value exists in A Json Array with same key Names - c#

I have this json body
[
{
"Id": 1,
"Name": "John",
"Icon": "Icon/someplace",
"SortOrder": 1
},
{
"Id": 2,
"Name": "Jessica",
"Icon": "Icon/someplace",
"SortOrder": 1
},
{
"Id": 3,
"Name": "Kevin",
"Icon": "Icon/someplace",
"SortOrder": 1
},
{
"Id": 4,
"Name": "Lint",
"Icon": "Icon/someplace",
"SortOrder": 1
},
{
...
}
]
I am adding Values to the json via API, I need to verify that the new value is present is the json body
I am trying to Covert the response to json,
public object Get_Json()
{
var response = GEt_Json_Body();
var json_string = JsonConvert.SerializeObject(response);
JArray UpdatedContent = JArray.Parse(json_string);
JObject Facility_Json = JObject.Parse(UpdatedContent[0].ToString());
Assert.NotNull(Facility_Json);
return Facility_Json;
}
This Only gives me back the first json:
{
"Id": 1,
"Name": "John",
"Icon": "Icon/someplace",
"SortOrder": 1
}
UpdatedContent[i] i allows me to get the other jsons in the array, the problem is I don't know where the json I Created using the API will be placed, how to get All of the JArray and verify that my entry is there?
Update:
This is my Call:
public List<FooModel> Get_Json_Body()
{
var request = new RestRequest();
request.Resource = string.Format("/api/get_something");
return Execute<FooMedl>(request, Endpoint);
}
public class FooModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Icon { get; set; }
public int SortOrder { get; set; }
}
public List<T> Execute<T>(RestRequest request, string Endpoint) where T : new()
{
Client.BaseUrl = new Uri(Endpoint);
var response = Client.Execute<List<T>>(request);
Console.WriteLine(response.ResponseUri);
if (response.ErrorException != null)
{
string message = String.Format("Error retrieving response: \n{0} \n{1} \n{2} ",
response.Content, response.ErrorMessage, response.ErrorException);
Console.WriteLine(message);
var exception = new ApplicationException(message);
throw exception;
}
return Response.Data;
}
Update 2:
The Answer By Davig G helped me to solve the problem, Was able to verify my input via
if(data.Any(f => f.Name == "Kevin"))
{
Console.WriteLine("Kevin exists in the data");
}
I am returing a List of dictionaries From Get_Json() method Using DavigG's answer I am able to verify and access the specific keys and values within the list.

It's much easier to deal with concrete classes than pure JSON objects, I would recommend deserialising your JSON directly into a list of objects like this:
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public string Icon { get; set; }
public int SortOrder { get; set; }
}
And the code to deserialise is:
var data = JsonConvert.DeserializeObject<List<Foo>>(response);
Now you can treat that object as you wish, for example:
if(data.Any(f => f.Name == "Kevin"))
{
Console.WriteLine("Kevin exists in the data");
}
Or even make modifications:
var kevin = data.SingleOrDefault(f => f.Name == "Kevin");
if(kevin != null)
{
kevin.SortOrder = 3;
}
And then if you need it to be back to the original JSON:
var json = JsonConvert.SerializeObject(data);

Related

Convert custome Key+Value JSON object Response to C# Model

i have this API that i want to creat a dynamic object. My point here is to have normal object to deal with rather than what this API returns to me, i can't controll this API so the retrived data can't be modified, this is the body, and it represnet a view in Database
Also i think reflection could help me in this case, any idea....
Request Body:
{
"ViewName": "Person",
"ViewOutput": "Name, Email, Number",
"ViewFilter": [
{
"filterKey": "Number",
"filterValue": "532000000"
}
]
}
I want the ViewName + ViewOutput+ ViewFilter to be paramterized,
ViewName it will take single value,
ViewOutput will be array of string
ViewFilter will be list of filteration ("FilterKey", "FilterVlaue") because it could be mutliple filteration value like this:
"ViewFilter": [
{
"filterKey": "Number",
"filterValue": "532000000"
},
{
"filterKey": "Email",
"filterValue": "test1#test.ps"
}
]
This is What API Return to me, a list of Person Keys and values,
Response:
{
"ResponseCode": "0",
"ResponseMessage": "Success",
"NumberOfRecords": "1",
"MainData": [
{
"recordData": [
{
"dataKey": "Name",
"dataValue": "Test Name"
},
{
"dataKey": "Email",
"dataValue": "test#test.ps"
},
{
"dataKey": "Number",
"dataValue": "532000000"
}
]
}
]
}
What i want to be the output is like this:
"Person": [
{
"Name":"Test",
"Email":"test#test.ps",
"Number":"532000000",
}]
Pasting the response JSON into an empty class file in Visual Studio using the Paste JSON As Classes feature, yields these classes:
public class Rootobject
{
public string ResponseCode { get; set; }
public string ResponseMessage { get; set; }
public string NumberOfRecords { get; set; }
public Maindata[] MainData { get; set; }
}
public class Maindata
{
public Recorddata[] recordData { get; set; }
}
public class Recorddata
{
public string dataKey { get; set; }
public string dataValue { get; set; }
}
You can create your own Person class.
Once you deserialize the JSON into the generated classes, one way to get a List<Person> would be to do something like this (please note that this is untested example code):
var people = rootObject.Maindata.Select(r =>
{
var name = r.recordData.Single(d => d.dataKey == "Name").dataValue;
var email = r.recordData.Single(d => d.dataKey == "Email").dataValue;
var number = r.recordData.Single(d => d.dataKey == "Number").dataValue;
return new Person(name, email, number);
}).ToList();

Transforming an array of name-value pairs in a JSON array with individual properties in the containing object

I'm trying to transform a JSON array to become object format.
Example:
{
"country": "USA",
"date": "2019-6-30",
"Speaker": [
{
"id": "name",
"value": "Tiger"
},
{
"id": "age",
"value": "35"
},
{
"id": "topic",
"value": ".NET"
}
]
}
I want to convert this to:
{
"country": "USA",
"date": "2019-6-30",
"name": "Tiger",
"age": 35,
"topic": ".NET"
}
I tried several ways, but had no luck. It seems I can't get the value of the internal array. Please help.
You can use Json.Net's LINQ-to-JSON API (JObjects) to transform your JSON:
JObject root = JObject.Parse(json);
JProperty arrayProp = root.Properties()
.Where(jp => jp.Value.Type == JTokenType.Array)
.FirstOrDefault();
if (arrayProp != null)
{
foreach (JObject item in arrayProp.Value.Children<JObject>())
{
root[(string)item["id"]] = item["value"];
}
arrayProp.Remove();
}
json = root.ToString();
This solution does not depend on the array property having any particular name, nor does it care what the item ids are. However, if there are any ids in the array which overlap with an existing property in the root object, the value in the array will replace the one already in the root object. Similarly, if there are any duplicate ids in the array, the last one will "win".
Working demo: https://dotnetfiddle.net/p3WkqN
You only need a couple of classes to deserialise this JSON, for example:
public class Data
{
public string Country { get; set; }
public string Date { get; set; }
// Deserialise the array as a list of 'SpeakerItem'
public List<SpeakerItem> Speaker { get; set; }
// These will throw exceptions if the id doesn't match, but it's a start
public string Name => Speaker.Single(s => s.Id == "name").Value;
public string Age => Speaker.Single(s => s.Id == "age").Value;
public string Topic => Speaker.Single(s => s.Id == "topic").Value;
}
public class SpeakerItem
{
public string Id { get; set; }
public string Value { get; set; }
}
Now you can do something like this:
var value = JsonConvert.DeserializeObject<Data>(json);
I have something like this using JSON.Net, first of all your json is wrong (you have dot in the end of country line). I have used DynamoObjects.
string json = #"
{
""country"": ""USA"",
""date"": ""2019-6-30"",
""Speaker"" : [
{
""id"": ""name"",
""value"": ""Tiger""
},
{
""id"": ""age"",
""value"": ""35""
},
{
""id"": ""topic"",
""value"": "".NET""
},
]
}";
dynamic animalJson = JsonConvert.DeserializeObject<dynamic>(json);
dynamic animal = new ExpandoObject();
animal.country = animalJson.country;
animal.date = animalJson.date;
animal.name = animalJson.Speaker[0].value;
animal.age = animalJson.Speaker[1].value;
animal.topic = animalJson.Speaker[2].value;
string modifiedAnimalJson = JsonConvert.SerializeObject(animal);

Get method is not working in Restsharp using C#

Get Method is not working... below code display all names or other attributes in richtext box from json using restsharp...there is no error but Ouput is not came help me to solve this...
var client = new RestClient("http://www.jsongenerator.com/api/json/get/cfBwXjwjci?indent=2");
var request = new RestRequest(Method.GET);
var queryResult = client.Execute<List<Detail>>(request).Data;
foreach (var rl in queryResult)
{
richTextBox1.Text = rl.name;
}
public class Detail
{
public string city { get; set; }
public int id { get; set; }
public string Blood { get; set; }
public string name { get; set; }
}
Here is json
{
"Details": [
{
"city": "Londan",
"id": 1,
"Blood": "O+",
"name": "Nicolas"
},
{
"city": "USA",
"id": 2,
"Blood": "A+",
"name": "Jhon"
},
{
"city": "India",
"id": 3,
"Blood": "B-",
"name": "Shiva"
}
]
}
I see two problems:
1) "http://www.jsongenerator.com/api/json/get/cfBwXjwjci?indent=2" - doesn't work
2) If you provided a correct JSON example then you should use "RootObject" here:
client.Execute<List<Detail>>(request).Data;

Deserialise JSON array object with nested list in C#

I am trying to deserialise the live chat api json response to access the message id and text by filtering using user_type
JSON response
{{
"events": [
{
"type": "agent_details",
"message_id": 1,
"timestamp": 1532396384,
"user_type": "agent",
"agent": {
"name": "Adam Harris",
"job_title": "Support Agent",
"avatar": "livechat.s3.amazonaws.com/default/avatars/ab5b0666feffd67600206cd519fd77ea.jpg"
}
},
{
"type": "message",
"message_id": 3,
"timestamp": 1532396387,
"user_type": "visitor",
"text": "hi"
}
]
}}
JsonOject Class
class JsonLiveChatEvent
{
public class Rootobject
{
public Event[] events { get; set; }
}
public class Event
{
public string type { get; set; }
public int message_id { get; set; }
public int timestamp { get; set; }
public string user_type { get; set; }
public Agent agent { get; set; }
public string text { get; set; }
}
public class Agent
{
public string name { get; set; }
public string job_title { get; set; }
public string avatar { get; set; }
}
}
JsonConverter
string jsonStr= await Api.Chat.GetPendingMessages(visitorID, licenseID,
var chatEvent = JsonConvert.DeserializeObject<Rootobject>(jsonStr);
The chatEvent object will not let me call chatEvent.events.message_id for example. Any help would be greatly appreciated as this is my first time working with json in c#
There is nothing to do with JSON, you have parsed the JSON data back to Rootobject.
Now you are working with an instance of Rootobject as:
Rootobject chatEvent = JsonConvert.DeserializeObject<Rootobject>(jsonStr);
Event event1 = chatEvent.events[0];
Event event2 = chatEvent.events[1];
Also, consider the answer from Mohammad, because above JSON will throw an exception.
The main problem here is that your json is not valid, there is an extra { in the beginning and an extra } in the end.
Then you could deserialize your json with the types you provided
Your json contains more that one curly brackets so you have to first remove those
so your json look like
{
"events": [
{
"type": "agent_details",
"message_id": 1,
"timestamp": 1532396384,
"user_type": "agent",
"agent": {
"name": "Adam Harris",
"job_title": "Support Agent",
"avatar": "livechat.s3.amazonaws.com/default/avatars/ab5b0666feffd67600206cd519fd77ea.jpg"
}
},
{
"type": "message",
"message_id": 3,
"timestamp": 1532396387,
"user_type": "visitor",
"text": "hi"
}
]
}
After that you have to collect message ids depending upon user_type
So then we create enum for that
public enum UserType
{
agent, visitor
}
then we simply check in events that if user type is matches with any of above enum value.
If your json contains multiple events with multiple user types then collect those into List<int>.
If your json contains only single event of each user type then collect them into string variables.
Rootobject chatEvent = JsonConvert.DeserializeObject<Rootobject>(jsonStr);
List<int> agent_message_ids = new List<int>();
List<int> visitior_message_ids = new List<int>();
//string agent_message_id = string.Empty;
//string visitior_message_id = string.Empty;
foreach (Event e in chatEvent.events)
{
if (e.user_type == UserType.agent.ToString())
{
agent_message_ids.Add(e.message_id);
//agent_message_id = e.message_id;
}
if (e.user_type == UserType.visitor.ToString())
{
visitior_message_ids.Add(e.message_id);
//visitior_message_id = e.message_id;
}
}
We simply take a list of integers that store message ids for particular user_type
Try once may it help you
Result:
agent_message_ids:
visitor_message_ids:

json.net Unable to Deserialize to Object List

I am trying to create a JSON file that contains a list of parts for computers.
My Parts Class
namespace Part_Class
{
public class Part_DB : IEnumerable<Part>
{
public List<Part> Parts = new List<Part>();
public IEnumerator<Part> GetEnumerator()
{
return this.Parts.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Model
{
public String Name { get; set; } // E6430, M4600, T4220
public Model(string Name)
{
this.Name = Name;
}
}
public class Category
{
public String Name { get; set; } // E6430, M4600, T4220
public Category(string Name)
{
this.Name = Name;
}
}
public class Part
{
public List<Model> Models = new List<Model>(); //E6420
public string PartNumber { get; set; } //PPHPX, UK717
public string Description { get; set; } // "320GB Hard Drive", "E6410 keyboard"
public List<Category> Categories = new List<Category>(); //Hard Drive, Keyboard
public bool HeroKit { get; set; } //Y or N
}
}
First I create a handful of Model, Categories, and Parts.
....
Model E6410 = new Model("E6410");
Model M4600 = new Model("M4600");
Model M4700 = new Model("M4700");
Category Keyboard = new Category("Keyboard");
Category Hard_Drive = new Category("Hard Drive");
Part PPHPX = new Part();
PPHPX.PartNumber = "PPHPX";
PPHPX.Models.Add(M4600);
PPHPX.Models.Add(M4700);
PPHPX.Description = "320GB Spindle Hard Drive";
PPHPX.Categories.Add(Hard_Drive);
PPHPX.HeroKit = true;
Part UK717 = new Part();
UK717.PartNumber = "UK717";
UK717.Models.Add(E6410);
UK717.Description = "102 Key Non Backlit";
UK717.Categories.Add(Keyboard);
UK717.HeroKit = true;
//I store those parts into a Part_DB Object
Part_DB Stored = new Part_DB();
Stored.Parts.Add(PPHPX);
Stored.Parts.Add(UK717);
//Then take that object and serialize it into a string
string jsonStr = JsonConvert.SerializeObject(Stored, Formatting.Indented);
//Then save it to a file
System.IO.File.WriteAllText(#"C:\****\Parts.json", jsonStr);
....
This outputs the following json file.
[
{
"Models": [
{
"Name": "M4600"
},
{
"Name": "M4700"
}
],
"Categories": [
{
"Name": "Hard Drive"
}
],
"PartNumber": "PPHPX",
"Description": "320GB Spindle Hard Drive",
"HeroKit": true
},
{
"Models": [
{
"Name": "E6410"
}
],
"Categories": [
{
"Name": "Keyboard"
}
],
"PartNumber": "UK717",
"Description": "102 Key Non Backlit",
"HeroKit": true
}
]
I am having trouble doing the reverse. Deserialize the JSON file back into a Part_DB Object. Here is my attempt
List<string> errors = new List<string>();
try
{
//Create a string of the JSON File
string jsonStr;
using (StreamReader file = File.OpenText(#"C:\****\Parts.json"))
{
jsonStr = file.ReadToEnd();
}
// Deserilize object into the Part_DB
Part_DB Stored = JsonConvert.DeserializeObject<Part_DB>(jsonStr,
new JsonSerializerSettings
{
Error = delegate(object senders, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
errors.Add(args.ErrorContext.Error.Message);
//Debug.WriteLine(args.ErrorContext.Error.Message);
args.ErrorContext.Handled = true;
},
});
}
catch (Exception ex) {
Console.WriteLine(ex);
}
I suspect it has something to do with the somewhat oddness of your top-level model actually inheriting from IEnumerable<T>. I was able to successfully deserialize the file produced into a Part_DB by using the following:
var newObj = JsonConvert.DeserializeObject<List<Part>>( json );
var partDb = new Part_DB();
partDb.Parts.AddRange( newObj );
The json variable contains the contents of the file, which is actually an array of Part objects, not a complete Part_DB object. Then to reconstruct the entire Part_DB you need to take the deserialized array and add it back into the Parts collection of the Part_DB.
If you want to deserialize straight into a Part_DB you're going to have to change your model so that Part_DB isn't inherited from IEnumerable<T>.
public class Part_DB
{
public List<Part> Parts = new List<Part>();
}
Then you can just deserialize directly into that type.
JsonConvert.DeserializeObject<Part_DB>( json );
But it will change your JSON a bit.
{
"Parts": [
{
"Models": [
{ "Name": "M4600" },
{ "Name": "M4700" }
],
"Categories": [
{ "Name": "Hard Drive" }
],
"PartNumber": "PPHPX",
"Description": "320GB Spindle Hard Drive",
"HeroKit": true
},
{
"Models": [
{ "Name": "E6410" }
],
"Categories": [
{ "Name": "Keyboard" }
],
"PartNumber": "UK717",
"Description": "102 Key Non Backlit",
"HeroKit": true
}
]
}
I think that for the Json.NET the Part_DB is just an object (which happens to be enumerable, but that's not important) so it is looking for the JSON that looks more like:
{ "Parts": and here should be your output from serialization}
The output you got from serialization is actually just the serialized List<Part> so try deserializing to it first, create a new Part_DB object and then assign that list to the Parts property.

Categories

Resources