Read json with multiple values - c#

I have this code snippet from my method. It should write all parts of the list test.E_id, but it writes nothing. I don't know what i do wrong.
string jsonText = File.ReadAllText(jsonFilePath);
Execution test = JsonConvert.DeserializeObject<Execution>(jsonText);
foreach (string eID in test.E_id)
{
Console.WriteLine(eID);
}
This is my Execution class, besides the writing of the strings is working fine.
public class Execution
{
public string Usr_id { get; private set; }
public string Patient_id { get; private set; }
public List<string> E_id { get; private set; }
public List<string> E_title { get; private set; }
public List<string> E_description { get; private set; }
public List<string> E_date { get; private set; }
public List<string> E_delete { get; private set; }
public Execution(string usr_id, string patient_id, List<string> e_id, List<string> e_title, List<string> e_description,
List<string> e_date, List<string> e_delete)
{
Usr_id = usr_id;
Patient_id = patient_id;
E_id = e_id;
E_title = e_title;
E_description = e_description;
E_date = e_date;
E_delete = e_delete;
}
}
And here is the json file i want to read from:
{
"usr_id":"573",
"patient_id":"170510024",
"executions":[
{
"id":"SF70H",
"title":"Verbandswechsel",
"description":"Verband des rechten Armes wechseln",
"date":"2017-07-28T12:00:00.000Z",
"delete":false
},
{
"id":"SF18H",
"title":"Physiotherapie",
"description":"Beweglichkeit des Knies wiederherstellen",
"date":"2017-07-28T14:00:00.000Z",
"delete":false
}
]
Maybe anyone knows what i do wrong and can help me to find my mistake.
}

Your problem is that your JSON and the code don't match with each other. You have lists for single fields, you have wrong names, etc.
Use this C# which maps to your JSON (generated from json2csharp.com):
public class Execution
{
public string id { get; set; }
public string title { get; set; }
public string description { get; set; }
public DateTime date { get; set; }
public bool delete { get; set; }
}
public class Test
{
public string usr_id { get; set; }
public string patient_id { get; set; }
public List<Execution> executions { get; set; }
}
Then use this C# code:
Test test = JsonConvert.DeserializeObject<Test>(jsonText);

Your code structure does not match your JSON-structure. Since you already knew the structure of the JSON file, there's a handy tool in Visual Studio to help you generate code from that.
Select the JSON structure in the file -> Ctrl+C -> Visual Studio -> Edit -> Paste Special -> Paste JSON as classes.
This gives following result:
public class Rootobject
{
public string usr_id { get; set; }
public string patient_id { get; set; }
public Execution[] executions { get; set; }
}
public class Execution
{
public string id { get; set; }
public string title { get; set; }
public string description { get; set; }
public DateTime date { get; set; }
public bool delete { get; set; }
}
Now you can decorate it with JsonProperty attributes and make the names to the C# standards:
public class Rootobject
{
[JsonProperty("usr_id")]
public string UserId { get; set; }
[JsonProperty("patient_id")]
public string PatientId { get; set; }
[JsonProperty("executions ")]
public Execution[] Executions { get; set; }
}
public class Execution
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("datee")]
public DateTime Date { get; set; }
[JsonProperty("delete")]
public bool Delete { get; set; }
}

This code worked fine:
public class ExecutionOrder
{
public string Usr_id { get; set; }
public string Patient_id { get; set; }
public List<Execution> Executions { get; set; }
public ExecutionOrder(string usr_id, string patient_id, List<Execution> executions)
{
Usr_id = usr_id;
Patient_id = patient_id;
Executions = executions;
}
}
public class Execution
{
public string E_id { get; set; }
public string E_title { get; set; }
public string E_description { get; set; }
public string E_date { get; set; }
public bool E_delete { get; set; }
public Execution(string e_id, string e_title, string e_description, string e_date, bool e_delete)
{
E_id = e_id;
E_title = e_title;
E_description = e_description;
E_date = e_date;
E_delete = e_delete;
}
}
But now I have another problem, i want to read the strings and the bool from the Execution object and print it in the CommandWindow. I can print the Usr_id and the Patient_id without any problems, and the bool from the object is also shown. But it doesn't print the strings. Is it the right way to read the strings out of the object?
ExecutionOrder test = JsonConvert.DeserializeObject<ExecutionOrder>(jsonText);
test.Executions.ForEach(delegate(Execution exec)
{
Console.WriteLine(test.Usr_id);
Console.WriteLine(test.Patient_id);
Console.WriteLine(exec.E_id);
Console.WriteLine(exec.E_title);
Console.WriteLine(exec.E_description);
Console.WriteLine(exec.E_date);
Console.WriteLine(exec.E_delete);
Console.WriteLine();
});

Related

Problem trying to deserialize a json with a model

I am trying to deserialize a json (using Newtonsoft.Json), i created the classes, but in json code there is a variable that i don't know if it is corrected or i don't know how to deserialize.
I am getting a null exception on line : MessageBox.Show(root.matriculations._14000.name)
private void btnImportaDados_Click(object sender, EventArgs e)
{
string getDataUrl = "https://xxx.xxx.com/api/matriculations/get.json?entity_code=14000";
try
{
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString(getDataUrl);
var root = JsonConvert.DeserializeObject<Rootobject>(json);
MessageBox.Show(root.matriculations._14000.name);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public class Rootobject
{
public Matriculations matriculations { get; set; }
}
public class Matriculations
{
public _14000 _14000 { get; set; }
}
public class _14000
{
public string entity_code { get; set; }
public string name { get; set; }
public string street { get; set; }
public string local { get; set; }
public string postal_code { get; set; }
public string sub_postal_code { get; set; }
public string phone1 { get; set; }
public object phone2 { get; set; }
public string email1 { get; set; }
public object email2 { get; set; }
public string entity_code_2 { get; set; }
public string courseaction_ref { get; set; }
public string courseaction_id { get; set; }
public string course_code { get; set; }
public string course { get; set; }
public Billingorderplan[] billingorderplans { get; set; }
}
public class Billingorderplan
{
public string id { get; set; }
public string paid { get; set; }
public string date { get; set; }
public object obs { get; set; }
public object payment_doc_num { get; set; }
public string value { get; set; }
public string description { get; set; }
public string entity_code { get; set; }
public object paid_date { get; set; }
}
The result(json data) from the url is:
{"matriculations":{"14000":{"entity_code":"14000","name":"Fabio Danilson Sivone Antonio","street":"Rua Dr. Pereira Jardim, Bl. 3 - 25 - 4 B","local":"Luanda","postal_code":"2685","sub_postal_code":"093","phone1":"923810539","phone2":null,"email1":"fabiodanilson1#hotmail.com","email2":null,"entity_code_2":"9957","courseaction_ref":"EPCE_01","courseaction_id":"1828","course_code":"EPCE","course":"Especializa\u00e7\u00e3o Avan\u00e7ada em Investiga\u00e7\u00e3o de Crime Econ\u00f3mico [E-learning]","billingorderplans":[{"id":"298","paid":"0","date":"2020-05-06","obs":null,"payment_doc_num":null,"value":"0.00","description":"Inscri\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"299","paid":"0","date":"2019-11-21","obs":null,"payment_doc_num":null,"value":"0.00","description":"1\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"300","paid":"0","date":"2019-12-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"2\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"301","paid":"0","date":"2020-01-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"3\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"302","paid":"0","date":"2020-02-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"4\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"303","paid":"0","date":"2020-03-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"5\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"304","paid":"0","date":"2020-04-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"6\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"305","paid":"0","date":"2020-05-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"7\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"306","paid":"0","date":"2020-06-08","obs":null,"payment_doc_num":null,"value":"0.00","description":"8\u00aa presta\u00e7\u00e3o","entity_code":"14000","paid_date":null},{"id":"16595","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null},{"id":"16596","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"45.00","description":"EExt - Teste","entity_code":"14000","paid_date":null},{"id":"16597","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null},{"id":"16598","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"45.00","description":"EExt - Teste","entity_code":"14000","paid_date":null},{"id":"16599","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null},{"id":"16601","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"45.00","description":"EExt - Teste","entity_code":"14000","paid_date":null},{"id":"16600","paid":"0","date":"2020-08-27","obs":null,"payment_doc_num":null,"value":"20.00","description":"EExt - Atividade","entity_code":"14000","paid_date":null}]}}}
But that "14000" is a varible value depending from the parameter passed.
How can i do it?
Thank You.
Since 14000 cannot be a variable name you will have to resort to some manual intervention to capture that dynamic value. The cleanest way is to remove the Matriculations class and replace it with Dictionary<int, _14000> (or Dictionary<string, _14000>).
public class Rootobject
{
public Dictionary<int, _14000> matriculations { get; set; }
}
This will ensure that the key is captured correctly even if it is a number. You can read the object from the dictionary's values as such: root.matriculations.Values.First().name. (Remember to import System.Linq for using .First().)
For clarity you can rename _14000 to something more descriptive.
You do not have _14000 in returned JSON but 14000 under matriculations.

I am getting error while converting json to object

i am trying to convert JSON to object following is my json
{"entity":"event","account_id":"acc_8yTsyb2WJOlcka","event":"payment.captured","contains":["payment"],"payload":{"payment":{"entity":{"id":"pay_AKR45WLH0g1ANu","entity":"payment","amount":100,"currency":"INR","status":"captured","order_id":"order_AKR41LsWIgOAB1","invoice_id":null,"international":false,"method":"netbanking","amount_refunded":0,"refund_status":null,"captured":true,"description":"Admission Fees","card_id":null,"bank":"SBIN","wallet":null,"vpa":null,"email":"xxxxx.xxxx#xxx.xxx","contact":"xxxxx","notes":{"address":"NA","merchant_order_id":"2516"},"fee":2,"tax":0,"error_code":null,"error_description":null,"created_at":1528367383}}},"created_at":1528367384}
and the code I am trying to convert to object is
jsonString = JsonConvert.SerializeObject(documentContents);
RazorPayPayload desJsonString = JsonConvert.DeserializeObject<RazorPayPayload>(jsonString);
and the classes where I want to deserialized
public class RazorPayPayload
{
public string entity { get; set; }
public string account_id { get; set; }
public string events { get; set; }
public List<string> contains { get; set; }
public payments payload { get; set; }
public string created_at { get; set; }
}
public class payments
{
public Entities payment { get; set; }
}
public class notes
{
public string address { get; set; }
public string merchant_order_id { get; set; }
public string source { get; set; }
}
public class Entities
{
public Entity entity { get; set; }
}
public class Entity
{
public string id { get; set; }
public string entity { get; set; }
public string amount { get; set; }
public string currency { get; set; }
public string order_id { get; set; }
public string invoice_id { get; set; }
public string international { get; set; }
public string method { get; set; }
public string amount_refunded { get; set; }
public string refund_status { get; set; }
public string captured { get; set; }
public string description { get; set; }
public string card_id { get; set; }
public string bank { get; set; }
public string wallet { get; set; }
public string vpa { get; set; }
public string email { get; set; }
public string contact { get; set; }
public notes notes { get; set; }
public string fee { get; set; }
public string tax { get; set; }
public string error_code { get; set; }
public string error_description { get; set; }
}
I am getting the error "Error converting value to type 'FeePayr_Razor_Webhook.RazorPayPayload'"
Have you tried changing:
{"entity":"event","account_id":"acc_8yTsyb2WJOlcka","event":
to
{"entity":"event","account_id":"acc_8yTsyb2WJOlcka","events":
That would better match your class definition. Or rename your class field to event.
There is a useful visual studio function for converting a json object to c# classes.
Copy the JSON into the clipboard. (helps if the JSON object properties holds data, to determine the data type)
Go to visual studio and place cursor where you'd like to paste in the c# classes.
click edit => paste special => paste json as classes

LDAP SearchResponse to Json C#

I am using a C# LdapConnection to get a SearchResponse at work. I can get the SearchResponse into a Json string, but am unable to put that Json string into an object class with properties which mimic the SearchResponse. The Json string is properly formatted. Am I using the Newtonsoft.Json library in the wrong way? Is there a better way to do this? My only requirements are that I get a SearchResponse into my object class (DirectoryEntity) so I can use it from there.
My Console Application:
class Program
{
static void Main(string[] args)
{
LdapClient client = new LdapClient();
List<LdapSearchResponseModel> list = new List<LdapSearchResponseModel>();
string query = "(|(uupid=name1)(uupid=name2))";
string[] attributes = new string[] { };
string host = "id.directory.univ";
int port = 1234;
SearchResponse response = client.RawQuery(query, attributes, host, port);
string json = JsonConvert.SerializeObject(response);
var test = JsonConvert.DeserializeObject<DirectoryEntities>(json);
}
}
My DirectoryEntity Class:
public class DirectoryEntity
{
public string EntityDN { get; set; }
public int MailStop { get; set; }
public List<string> UniversityAffiliation { get; set; }
public int UniversityId { get; set; }
public string GivenName { get; set; }
public string Title { get; set; }
public string PasswordState { get; set; }
public string MiddleName { get; set; }
public string AccountState { get; set; }
public int Uid { get; set; }
public string Mail { get; set; }
public string MailPreferredAddress { get; set; }
public DateTime DateOfBirth { get; set; }
public List<string> GroupMembership { get; set; }
public string DegreeType { get; set; }
public int ClassLevelCode { get; set; }
public string AuthId { get; set; }
public string Major { get; set; }
public string ClassLevel { get; set; }
public bool SupressDisplay { get; set; }
public string UnderGraduateLevel { get; set; }
public string ObjectClass { get; set; }
public int DepartmentNumber { get; set; }
public List<string> EduPersonAffiliation { get; set; }
public string LocalPostalAddress { get; set; }
public string Uupid { get; set; }
public string LocalPhone { get; set; }
public string TelephoneNumber { get; set; }
public string Department { get; set; }
public string Sn { get; set; }
}
My DirectoryEntities Class:
public class DirectoryEntities
{
public List<DirectoryEntity> Entities { get; set; }
public int Count { get; set; }
}
Have you tried explicitly defining a default constructor for the DirectoryEntity class? I believe that Newtonsoft requires objects to have a default constructor before they can be deserialized. Try adding this to the DirectoryEntity class:
public DirectoryEntity() { }

REST Api returning different object names for the same object, how to handle with RestSharp?

I'm programming a C# implementation for the Qualtrics API (v 2.5) using RestSharp. When calling the method getUserIds, it returns a list of users in JSON format (see the example output below).
The problem/question I face is that for each user object (the list of objects under Result) it generates a different id, starting with URH_. When using json2csharp it assumes ofcourse that it's always a different class, while in fact it's absolutely the same one as you can see in the output, and as is stated in the documentation of the api. How can I best resolve this - so that I can make a class UserData that I can reuse? Because now I obviously always see these random URH_ prefixed classes in each response.
NOTE: I was thinking I could try to massage the response first, and when I get the response replace each URH_ prefixed object under the root Result object with a "UserData" string - but I feel this is breaking the rules a bit, and thought the community would have a better solution?
Below is the raw JSON output (note that I removed sensitive information):
{"Meta":{"Status":"Success","Debug":""},"Result":{"URH_3wpA9pxGbE0c7Xu":{"DivisionID":null,"UserName":"user.name#domain.com","UserFirstName":"x","UserLastName":"x","UserAccountType":"UT_4SjjZmbPphZGKDq","UserEmail":"x.x#x.x","UserAccountStatus":"Active"},"URH_57vQr8MVXgpcPUo":{"DivisionID":"DV_XXXXXXXX","UserName":"jxxxx#xx.xxx","UserFirstName":"X","UserLastName":"X","UserAccountType":"UT_BRANDADMIN","UserEmail":"xxxx#xxg.xxx","UserAccountStatus":"Active"},"URH_6ujW1EP0QJOUaoI":{"DivisionID":"DV_XXXXXXXYZ","UserName":"x.xckx#xxx.xyz","UserFirstName":"x","UserLastName":"x","UserAccountType":"UT_XXXXXABCD","UserEmail":"c.c#cc.com","UserAccountStatus":"Active"}}}
This is what I get when generating a model using json2csharp:
public class Meta
{
public string Status { get; set; }
public string Debug { get; set; }
}
public class URH3wpA9pxGbE0c7Xu
{
public object DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class URH57vQr8MVXgpcPUo
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class URH6ujW1EP0QJOUaoI
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class Result
{
public URH3wpA9pxGbE0c7Xu URH_3wpA9pxGbE0c7Xu { get; set; }
public URH57vQr8MVXgpcPUo URH_57vQr8MVXgpcPUo { get; set; }
public URH6ujW1EP0QJOUaoI URH_6ujW1EP0QJOUaoI { get; set; }
}
public class RootObject
{
public Meta Meta { get; set; }
public Result Result { get; set; }
}
It's simple - just use Dictionary<string, UserData> generic type for Result field:
public class Response
{
public Meta Meta { get; set; }
public Dictionary<string, UserData> Result { get; set; }
}
public class Meta
{
public string Status { get; set; }
public string Debug { get; set; }
}
public class UserData
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}

Parse through deserialized JSON data

I am new to C#. I have successfully consumed the Mailchip API with a simple console app. I am pulling in relevant data and I have successfully used a JSON deserializer on the returned data (Newtonsoft.Json via NuGet). What I need to find is the best way to place the data into variables which I can then pass to a stored procedure to save the data. I know SQL and I know how to pass variables to a stored procedure in C# (connection strings and such).
What I don't know is how to parse through the deserialized data and then place each value into a variable or something I can pass to SQL. I know this is a vague question so here is the current code.
Class MailChimpAPIClient.cs:
//Declare the API Key
public const string APIKey = "My API Key Here";
public static void APIGet(string url)
{
//Syncronious Consumption
var syncClient = new WebClient();
syncClient.Headers.Add(APIKey);
var content = syncClient.DownloadString(url);
//Deseralize the Json String
MailChimpData data = JsonConvert.DeserializeObject<MailChimpData>(content);
}
Class: MailChimpData.cs:
[DataContract]
public class MailChimpData
{
[DataMember]
public List<Unsubscribes> unsubscribes { get; set; }
[DataMember]
public string campaign_id { get; set; }
[DataMember]
public List<Link2> _links { get; set; }
[DataMember]
public int total_items { get; set; }
[DataMember]
public Link link { get; set; }
[DataMember]
public MergeFields mergefields { get; set; }
[DataMember]
public Stats stats { get; set; }
[DataMember]
public Location location { get; set; }
[DataMember]
public List<Member> members { get; set; }
[DataMember]
public string list_id { get; set; }
}
//Unsubscribe Data
public class Link
{
public string rel { get; set; }
public string href { get; set; }
public string method { get; set; }
public string targetSchema { get; set; }
public string schema { get; set; }
}
public class Unsubscribes
{
public string email_id { get; set; }
public string email_address { get; set; }
public string timestamp { get; set; }
public string reason { get; set; }
public string campaign_id { get; set; }
public string list_id { get; set; }
public List<Link> _links { get; set; }
}
public class Link2
{
public string rel { get; set; }
public string href { get; set; }
public string method { get; set; }
public string targetSchema { get; set; }
public string schema { get; set; }
}
//List Data
public class MergeFields
{
public string FNAME { get; set; }
public string LNAME { get; set; }
}
public class Stats
{
public double avg_open_rate { get; set; }
public int avg_click_rate { get; set; }
}
public class Location
{
public double latitude { get; set; }
public double longitude { get; set; }
public int gmtoff { get; set; }
public int dstoff { get; set; }
public string country_code { get; set; }
public string timezone { get; set; }
}
public class Member
{
public string id { get; set; }
public string email_address { get; set; }
public string unique_email_id { get; set; }
public string email_type { get; set; }
public string status { get; set; }
public MergeFields merge_fields { get; set; }
public Stats stats { get; set; }
public string ip_signup { get; set; }
public string timestamp_signup { get; set; }
public string ip_opt { get; set; }
public string timestamp_opt { get; set; }
public int member_rating { get; set; }
public string last_changed { get; set; }
public string language { get; set; }
public bool vip { get; set; }
public string email_client { get; set; }
public Location location { get; set; }
public string list_id { get; set; }
public List<Link> _links { get; set; }
}
Program.cs:
class Program
{
static void Main(string[] args)
{
MailChimpApiClient.APIGet("Custom URL Here");
}
}
So when I run this and look in the Autos window of VS2013 I see this:
members: Count = 4 System.Collections.Generic.List
[0] {MailChimpAPI.Member} MailChimpAPI.Member
_links: Count = 8 System.Collections.Generic.List
email_address: email address here string
email_client: string
email_type: html string
id: (ID Here) string
ip_opt: (IP Here) string
ip_signup: string
language: string
last_changed: 9/16/15 19:31 string
list_id: (List ID Here) string
location: {MailChimpAPI.Location} MailChimpAPI.Location
member_rating: 3 int
merge_fields {MailChimpAPI.MergeFields} MailChimpAPI.MergeFields
stats: {MailChimpAPI.Stats} MailChimpAPI.Stats
status: unsubscribed string
timestamp_opt: 9/16/15 19:26 string
timestamp_signup: string
unique_email_id: (Unique Email ID Here) string
vip: FALSE bool
[1] {MailChimpAPI.Member}: MailChimpAPI.Member
[2] {MailChimpAPI.Member}: MailChimpAPI.Member
[3] {MailChimpAPI.Member}: MailChimpAPI.Member
Raw View
So for each member (0-3), I need to pull each fields value (Field names in bold) into a variable and save it to a database. I just don't know how to parse through each member.
I know this is a long question for a simple C# problem, but if you can remember way back to the beginning of the post I stated "I am new to C#"
Thanks in advance.

Categories

Resources