I have simple class
class Person
{
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public List<string> ParentsNames { get; set; }
}
And a json file
[
{
"Name": "Frank",
"Surname": "Wilson",
"Age": "52",
"Login": "fwillock",
"Password": "willock123",
"ParentsNames": [
"Charles",
"Sarah"
]
},
{
"Name": "Karen",
"Surname": "Davies",
"Age": "35",
"Login": "kdavies",
"Password": "davies123",
"ParentsNames": [
"Jason",
"Angela"
]
}
]
I need to get in console all names or surnames, existing in Person list. I tried to use something like this:
var JsonDeserialize = File.ReadAllText(fileName);
List<Person> result = JsonSerializer.Deserialize<List<Person>>(JsonDeserialize);
Console.WriteLine(result.Select(x => x.Name).ToList());
But i don't have any idea to use it in my code.
Thanks in advance.
list of names
var names= result.Select(i=> new {Name=i.Name, Surname=i.Surname}).ToList();
to print
foreach (var n in result) Console.WriteLine ( $"{n.Name} {n.Surname}");
If you want to customise how you display information in a class one option is to override ToString() for your Person class:
class Person
{
...
// customize however you like
public override string ToString() => $"{Name} {Surname}";
}
Then to display in a single line, you could use string.Join():
Console.WriteLine(string.Join(", ", result));
Or if you want each person on a new line:
result.ForEach(person => Console.WriteLine(person));
// which can be shortened to
result.ForEach(Console.WriteLine);
Related
I have a json config file with values as variables. I want to replace these variables with actual values that are stored in another json file.
Source data json file:
{
"person": {
"id": 15305,
"gender": "Male",
"dob": "1958-10-31T00:00:00",
"name": {
"id": 80587,
"first": "John",
"last": "Dominick"
}
},
"ethnicity": [
{
"id": 2,
"display": "Not Hispanic or Latino",
"kbEthnicity": null
}
],
"race": [
{
"id": 4,
"display": "Black"
},
{
"id": 6,
"display": "Other Race"
}
]
}
Destination data json file:
{
"dryRun": "true",
"person": {
"firstName": "[person.name.first]",
"lastName": "[person.name.last]",
"dateOfBirth": "[person.dob]",
"gender": "[person.gender]",
"race": "[race]"
}
}
Final json file that I want:
{
"dryRun": "true",
"person": {
"firstName": "John",
"lastName": "Dominick",
"dateOfBirth": "1958-10-31T00:00:00",
"gender": "MALE",
"race": "Black, Other Race"
}
}
Here is the code that I wrote using the following SO post that reads both files and is able to extract the correct values from the source file, but I am stuck on what is the best way to create a final json file.
public static void Main(string[] args)
{
var sourceJson = File.ReadAllText("./sourcedata.json");
var srcObj = JObject.Parse(sourceJson);
var destJson = File.ReadAllText("./destinationdata.json");
var destObj = JObject.Parse(destJson);
var result = destObj.Descendants()
.OfType<JProperty>()
.Select(p => new KeyValuePair<string, object>(p.Path,
p.Value.Type == JTokenType.Array || p.Value.Type == JTokenType.Object
? null : p.Value));
foreach (var kvp in result)
{
var isVariable = kvp.Value == null ? false : Regex.IsMatch(kvp.Value.ToString(), #"^\[.*?\]$");
if (isVariable)
{
var variable = Regex.Replace(kvp.Value.ToString(), #"[\[\]]+", "");
Console.WriteLine($"Key: {kvp.Key} Value: {kvp.Value} Updated: {srcObj.SelectToken(variable)}");
}
else
{
Console.WriteLine($"Key: {kvp.Key} Value: {kvp.Value}");
}
}
}
Another issue that I want to solve is how to concatenate the values if there is an array? Any help would be appreciated.
High level: You need two POCO objects: one to deserialize your source json (with the values), and one to serialize to your destination json.
You read in the source, deserialize to the source poco, translate from source poco to destination poco, and then serialize that as destination json.
I think that's much more straightforward than working with JObjects, etc.
Here is a slightly simplified version of your objects:
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var json = #"{""person"":{""name"": {""first"": ""John"",""last"": ""Dominick""}}}";
var objA = Newtonsoft.Json.JsonConvert.DeserializeObject<Source.MyObject>(json);
Console.WriteLine("FirstName: " + objA.Person.Name.FirstName);
var objB = new Destination.MyObject(objA);
var outJson = Newtonsoft.Json.JsonConvert.SerializeObject(objB);
Console.WriteLine(outJson);
}
}
public class Source{
public class MyObject
{
[JsonProperty("person")]
public Person Person { get; set; }
}
public class Person
{
[JsonProperty("name")]
public Name Name { get; set; }
}
public class Name
{
[JsonProperty("first")]
public string FirstName { get; set; }
[JsonProperty("last")]
public string LastName { get; set; }
}
}
public class Destination{
public class MyObject{
public MyObject(Source.MyObject sourceObject){
Person = new Person();
Person.FirstName = sourceObject.Person.Name.FirstName;
Person.LastName = sourceObject.Person.Name.LastName;
}
[JsonProperty("person")]
public Person Person {get;set;}
}
public class Person
{
[JsonProperty("firstName")]
public string FirstName {get;set;}
[JsonProperty("lastName")]
public string LastName {get;set;}
}
}
Output:
FirstName: John
{"person":{"firstName":"John","lastName":"Dominick"}}
see:
https://dotnetfiddle.net/0V4pEO
do I always need to create a model for an incoming JSON and then deserialize the JSON to it or is there a way to loop through the JSON file, check specific properties and add additional information?
Here is why I ask:
In my project I have two classes "region" and "country". Inside "region" is the nested class "country"
enter code here
public class Region`enter code here`
{
[Key]
public int Id { get; set; }
public string Region { get; set; }
public Country Country { get; set; }
}
public class Country
{
[Key]
public int Id { get; set; }
[Required]
[MaxLength(255)]
public string Name { get; set; }
[Required]
[MaxLength(2)]
public string ISO3166Alpha2 { get; set; }
[Required]
[MaxLength(3)]
public string ISO3166Alpha3 { get; set; }
}
Now I have an incoming JSON which has the country and region information which i need but without Ids or any other required information.
So do i need to create a new model, deserialize the JSON and then use that new model to create my "region" and "country" model or is there a better way of doing this?
{
"regions": [
{
"country": "France",
"region": [
"Bordeaux",
"Burgundy",
"Beaujolais",
"Champagne",
"Loire",
"Alsace",
"Rhône",
"Provence",
"Languedoc-Roussillon",
"Jura"
]
},
{
"country": "Italy",
"region": [
"Piedmont",
"Barolo",
"Barbaresco",
"Tuscany",
"Veneto",
"Friuli-Venezia",
"Giulia",
"Abruzzo",
"Sicily",
"Lambrusco"
]
}
}
´´´
Thanks a lot :)
kindly find below the way to achieve that as stated by the docs. kindly visit this link https://www.newtonsoft.com/json/help/html/DeserializeAnonymousType.htm but however my solution is shown below.
var json1 = #"{
'regions': [
{
'country': 'France',
'region': [
'Bordeaux',
'Burgundy',
'Beaujolais',
'Champagne',
'Loire',
'Alsace',
'Rhône',
'Provence',
'Languedoc-Roussillon',
'Jura'
]
},
{
'country': 'Italy',
'region': [
'Piedmont',
'Barolo',
'Barbaresco',
'Tuscany',
'Veneto',
'Friuli-Venezia',
'Giulia',
'Abruzzo',
'Sicily',
'Lambrusco'
]
}]}";
var definition = new { regions = new[]{new {country = "" , region = new string[]{ } } }};
var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition);
Console.WriteLine(customer1.regions);
foreach (var item in customer1.regions)
{
Console.WriteLine(item.country);
}
How could I find a specific id in this list?
var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
contactList.contacts.FindAll(x => x.id == item.id);
The code above is not filtering by id and is returning all rows from object.
(Visual Studio is not showing me .Where clause only .Find and .FindAll)
C# code
namespace RestDemo.Model
{
public class Phone
{
public string mobile { get; set; }
public string home { get; set; }
public string office { get; set; }
}
public class Contact
{
public int id { get; set; }
public string name { get; set; }
public string email { get; set; }
public string address { get; set; }
public string gender { get; set; }
public Phone phone { get; set; }
}
public class ContactList
{
public List<Contact> contacts { get; set; }
}
}
Json:
{ "contacts": [ { "id": 200, "name": "Ravi Tamada", "email": "ravi#gmail.com", "address": "xx-xx-xxxx,x - street, x - country", "gender": "male", "phone": { "mobile": "+91 0000000000", "home": "00 000000", "office": "00 000000" } }, { "id": 201, "name": "Klev Krist", "email": "klev#gmail.com", "address": "xx-xx-xxxx,x - street, x - country", "gender": "male", "phone": { "mobile": "+91 0000000000", "home": "00 000000", "office": "00 000000" } }, { "id": 202, "name": "Paul Neil", "email": "paul.neil#gmail.com", "address": "xx-xx-xxxx,x - street, x - country", "gender": "male", "phone": { "mobile": "+91 0000000000", "home": "00 000000", "office": "00 000000" } } ]}
Thanks
The FindAll method does not assign an object to the search result.
You have to keep the search result somewhere.
Example Multi Result
If you are expecting multiple results
var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
var findedContact = contactList.contacts.FindAll(x => x.id == item.id);
//You business codes..
Example Single Result
If you are only waiting for 1 result
var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
var oneContact = contactList.contacts.Find(x => x.id == item.id);
if(oneContact ==null){
//not found business codes
}
else {
//find result business codes
}
Assuming you want to find a certain id, we'll call it
var idToFind = "myID";
To find all contacts with said ID:
var contacts = contactList.contacts.Where(contact=> contact.id == idToFind);
To find at least one contact with said ID:
var contactWithID = contactList.contacts.FirstOrDefault(contact=> contact.id == idToFind);
// Before using, check if null, means no contact matched the id.
if(contactWithID != null)
{
// A contact was found.
}
else
{
// No contact matching that id is found.
}
Specific to your case, I am using the same Model structure to deserialize your JSON and then use the Where linq clause to achieve what you require. A working fiddle can be found at: https://dotnetfiddle.net/SAcFja
Code:
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var jsonString = #"{ 'contacts': [{ 'id': 200, 'name': 'Ravi Tamada', 'email': 'ravi#gmail.com', 'address': 'xx-xx-xxxx,x - street, x - country', 'gender': 'male', 'phone': { 'mobile': '+91 0000000000', 'home': '00 000000', 'office': '00 000000' } }] }";
var data= JsonConvert.DeserializeObject<ContactList>(jsonString);
//Console.WriteLine(data.contacts);
var found=data.contacts.Where(x=>x.id.ToString()=="200");
foreach(var value in found)
{
Console.WriteLine(value.id);
Console.WriteLine(value.address);
}
}
}
public class Phone
{
public string mobile { get; set; }
public string home { get; set; }
public string office { get; set; }
}
public class Contact
{
public string id { get; set; }
public string name { get; set; }
public string email { get; set; }
public string address { get; set; }
public string gender { get; set; }
public Phone phone { get; set; }
}
public class ContactList
{
public List<Contact> contacts { get; set; }
}
Output when id=200:
200
xx-xx-xxxx,x - street, x - country
As per your comment on #Tenretni's answer, I guess you missed to use System.Linq library in your code.
Import System.Collections.Generic and System.Linq in your code and use FirstOrDefault() or .Where() clause
using System.Collections.Generic;
using System.Linq;
//…
string jsonString = #"{ 'contacts': [{ 'id': 'c200', 'name': 'Ravi Tamada', 'email': 'ravi#gmail.com', 'address': 'xx-xx-xxxx,x - street, x - country', 'gender': 'male', 'phone': { 'mobile': '+91 0000000000', 'home': '00 000000', 'office': '00 000000' } }] }";
var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
var item = "c200";
var result = contactList.contacts.FirstOrDefault(x => x.id == item);
Console.WriteLine(result.name);
//If you have multiple records with same ID then you can try where clause
var result = contactList.contacts.Where(x => x.id == item); //Here result will be list of Contact
.Net Fiddle
I am getting familiar with C# and Linq and appreciate any help. It should be easy for someone who works with it. I have a Json object that returns contact information. I also have a list of ids. I need to compare the list to the Json object and wherever the value in the list matches the userclientcode in the Json object, I need to extract the following information (only for the matches):
clienttaxonomy (if not empty)
fullname (if not empty)
[0]contactdata ( -> email if not null or empty)
[1]contactdata (-> address if not null or empty)
[2]contactdata (-> phone number if not null or empty)
First List
var fileContactIds = new List<string> { "5678765", "2135123", "12341234", "341234123", "12341234123", "2341234123", "341234123", "123412341", "13342354",
"12342341", "123412322", "163341234", "2345234115", "8967896", "75626234 };
JSON object returned with:
return JsonConvert.DeserializeObject<RelatedContacts>(json)?.list;
This is the Json object:
[![Json object][1]][1]
This is the Json string (unescaped):
{
"type": "com.kurtosys.api.userprofile.domain.RelatedContactList",
"list": [{
"objectlistid": 5678765,
"objectlisttypeid": 4567876,
"objectlistname": "ALL.National",
"clienttaxonomyid": 765677,
"clienttaxonomy": "National Wholesaler",
"order": 1,
"contacts": [{
"personid": 7654345678,
"fullname": "Person Jallo",
"userid": 876567,
"userclientcode": "341234123",
"contactdetails": [{
"contactid": 8765567,
"contacttypeid": 4565,
"contactdata": "person.contact#site.com"
}, {
"contactid": 876545678,
"contacttypeid": 4565,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 87654567,
"contacttypeid": 4584,
"contactdata": "410-413-2640"
}]
}]
}, {
"objectlistid": 765678,
"objectlisttypeid": 40400461,
"objectlistname": "RM.Internal",
"clienttaxonomyid": 7567898,
"clienttaxonomy": "Internal Regional Wholesaler",
"order": 2,
"contacts": [{
"personid": 56789876,
"fullname": "Jackson Man",
"userid": 876567,
"userclientcode": "1012275",
"contactdetails": [{
"contactid": 309598309,
"contacttypeid": 76546,
"contactdata": "mister.jackson##site.com.com"
}, {
"contactid": 876567,
"contacttypeid": 4581,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 876567,
"contacttypeid": 2342,
"contactdata": "123-413-2604"
}]
}]
}, {
"objectlistid": 309571364,
"objectlisttypeid": 40400461,
"objectlistname": "RM.External",
"clienttaxonomyid": 309580710,
"clienttaxonomy": "External Regional Wholesaler",
"order": 3,
"contacts": [{
"personid": 302736188,
"fullname": "Phal Sumi",
"userid": 303826019,
"userclientcode": "163341234",
"contactdetails": [{
"contactid": 309598253,
"contacttypeid": 2342,
"contactdata": "misters.emailas#site.com"
}, {
"contactid": 309611930,
"contacttypeid": 2342,
"contactdata": "Baltimore,MD,21209,United States"
}, {
"contactid": 34234132,
"contacttypeid": 3422,
"contactdata": "342-803-1793"
}]
}]
}]
}
How do I
1] Select using Linq and Lambdas and put in a list fullname, email, address etc from the deserialized object ?
2]compare with first list and only transfer those items where the userclientcode == the number in list A.
I have tried:
var query5 = relatedContact.Where(s => s.objectlistid == Convert.ToInt64(contacts.Select(t => t.id)))
var selected = relatedContact.Where(p => p.contacts
.Any(a => fileContactIds.Contains(p.contacts))
.ToList();
var query2 = relatedContact.Where(s => s.objectlistid == Convert.ToInt64(contacts.Select(t => t.id)))
.Select(s => new
{
Description = s.clienttaxonomy,
Fullname = s.contacts[0].fullname,
Email = s.contacts[0].contactdetails[0].contactdata,
Address = s.contacts[0].contactdetails[1].contactdata,
PhoneNumber = s.contacts[0].contactdetails[2].contactdata
});
But don't really know what I'm doing it seems. Any suggestions on how to get the required sections ? I think part of the reason is that the contactdata is a list.
Thanks all
You can create a classes for the desearlization of JSON Object like this
public class Rootobject
{
public string type { get; set; }
public List[] list { get; set; }
}
public class List
{
public int objectlistid { get; set; }
public int objectlisttypeid { get; set; }
public string objectlistname { get; set; }
public int clienttaxonomyid { get; set; }
public string clienttaxonomy { get; set; }
public int order { get; set; }
public Contact[] contacts { get; set; }
}
public class Contact
{
public long personid { get; set; }
public string fullname { get; set; }
public int userid { get; set; }
public string userclientcode { get; set; }
public Contactdetail[] contactdetails { get; set; }
}
public class Contactdetail
{
public int contactid { get; set; }
public int contacttypeid { get; set; }
public string contactdata { get; set; }
}
And then to extract the selected information we can also create a another class like
public class ExtractedInfo
{
public string ocClientTaxonomy { get; set; }
public string ocFullName { get; set; }
public CTDetails ocContactDetails { get; set; }
}
public class CTDetails
{
public string ocCTAddress { get; set; }
public string ocCTEmail { get; set; }
public string ocCTPhoneNumber { get; set; }
}
Now we have to find all the data from JSON
var fileContactIds = new List<string> { "5678765", "2135123", "12341234", "341234123", "12341234123", "2341234123", "341234123", "123412341", "13342354", "12342341", "123412322", "163341234", "2345234115", "8967896", "75626234" };
//Read JSON from txt file. You can do it by your way
string myjson = File.ReadAllText("Some.txt");
string ctphno, ctadd, ctemail, cltax, ctfullname;
List<ExtractedInfo> ei = new List<ExtractedInfo>();
CTDetails ctdtl = new CTDetails();
ExtractedInfo eiex = new ExtractedInfo();
//Deserialize the JSON string to Object.
Rootobject AllData = JsonConvert.DeserializeObject<Rootobject>(myjson);
//Finding all data in List Class
foreach(List lst in AllData.list)
{
cltax = lst.clienttaxonomy; // you can directly put eiex.ocClientTaxonomy = lst.clienttaxonomy;
foreach(Contact ct in lst.contacts)
{
//To check if value in the list matches the objectlistid in the Json object
if(fileContactIds.Contains(lst.objectlistid.ToString()))
{
ctfullname = ct.fullname; // you can directly put eiex.ocFullName = ct.fullname;
foreach(Contactdetail ctd in ct.contactdetails)
{
//Here we are trying to find the Match for Email.
if(Regex.IsMatch(ctd.contactdata, #"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", RegexOptions.IgnoreCase))
{
ctemail = ctd.contactdata;
ctdtl.ocCTEmail = ctemail;
}
//Here We trying to find the match for Phone Number.
else if(Regex.IsMatch(ctd.contactdata, #"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}", RegexOptions.IgnoreCase))
{
ctphno = ctd.contactdata;
ctdtl.ocCTPhoneNumber = ctphno;
}
//If NOthing matches than it might be address (Assumed)
else
{
ctadd = ctd.contactdata;
ctdtl.ocCTAddress = ctadd;
}
}
eiex.ocFullName = ctfullname;
}
}
eiex.ocClientTaxonomy = cltax;
eiex.ocContactDetails = ctdtl;
ei.Add(eiex);
}
Hope this helps and fit in your requirements.
I'm able to parse simple properties using JSON.NET with this C# code:
Code C#
WebClient c = new WebClient();
var data = c.DownloadString("http://localhost/json1.json");
JObject o = JObject.Parse(data);
listBox1.Items.Add(o["name"]);
listBox1.Items.Add(o["email"][0]);
listBox1.Items.Add(o["email"][1]);
listBox1.Items.Add(o["website"]["blog"]);
json1.json
{
"name": "Fname Lname",
"email": [
"email#gmail.com",
"email#hotmail.com"
],
"website":
{
"blog": "example.com"
}
}
json2.json
{
"name": "Fname Lname",
"email": [
"email#gmail.com",
"email#hotmail.com"
],
"website":
{
"blog": "example.com"
},
"faculty":
{
"department": [
{
"name": "department.name",
"location": "department.location"
}
]
}
}
From the second JSON file, I'm not able to get name and location from the department. How do I do that in C#?
name : department.name
location: department.location
yourjsonobject.faculty.department[0].name;
yourjsonobject.faculty.department[0].location;
Here is some jsfiddle to help you with this:
http://jsfiddle.net/sCCrJ/
var r = JSON.parse('{"name": "Fname Lname","email": [ "email#gmail.com", "email#hotmail.com"],"website":{ "blog": "example.com"},"faculty":{ "department": [ { "name": "department.name", "location": "department.location" } ]}}');
alert(r.faculty.department[0].name);
alert(r.faculty.department[0].location);
for (var i = 0; i < r.faculty.department.length; i++) {
alert(r.faculty.department[i].name);
}
Your problem is that department is an array of objects (though it happens to just contain one item here), but you're not accessing it like it is. You can use o["faculty"]["department"][0]["name"] to get your data.
You might want to use classes (here are ones auto-converted with http://json2csharp.com/) to more easily work with your data.
public class Website
{
public string blog { get; set; }
}
public class Department
{
public string name { get; set; }
public string location { get; set; }
}
public class Faculty
{
public List<Department> department { get; set; }
}
public class RootObject
{
public string name { get; set; }
public List<string> email { get; set; }
public Website website { get; set; }
public Faculty faculty { get; set; }
}
Then you can get all of the data (instead of hoping the fixed indexes are right, and that you didn't make a typo in the property names) with this code:
WebClient c = new WebClient();
var data = c.DownloadString("http://localhost/json1.json");
var o = JsonConvert.DeserializeObject<RootObject>(data);
listBox1.Items.Add(o.name);
foreach (var emailAddr in o.email)
listBox1.Items.Add(emailAddr);
listBox1.Items.Add(o.website.blog);
foreach (var dept in o.faculty.department)
{
listBox1.Items.Add(dept.name);
listBox1.Items.Add(dept.location);
}