How to convert JSON Array to List<>? - c#

This is my json and I need to access the values under each object in the attendance array:
{"name":" ","course":"","attendance":[{"name":"INTERNATIONAL FINANCE","type":"Theory","conducted":"55","present":"50"},{"name":"INDIAN CONSTITUTION","type":"Theory","conducted":"6","present":"6"}]}
Here is my code:
public class Att
{
public class Attendance
{
public string name { get; set; }
public string type { get; set; }
public string conducted { get; set; }
public string present { get; set; }
}
public Att(string json)
{
JObject jObject = JObject.Parse(json);
JToken jUser = jObject;
name = (string)jUser["name"];
course = (string)jUser["course"];
attender = jUser["attendance"].ToList<Attendance>;
}
public string name { get; set; }
public string course { get; set; }
public string email { get; set; }
//public Array attend { get; set; }
public List<Attendance> attender { get; set; }
}
It is the attender = jUser["attendance"].ToList<Attendance>; line that I have a problem with. It says,
Cannot convert method group ToList to non-delegate type. Did you intend to invoke this method?
How do I access those values?

You have a typo!
attendance vs attendence
And this should work
attender = jUser["attendance"].ToObject<List<Attendance>>();
You may find the running result at DotNetFiddle

You wanted to write:
attender = jUser["attendence"].ToList<Attendance>(); // notice the ()
About the Error:
When you dont put the parantheses there, C# assumes you want
to assign the function (delegate) ToList to the varaible attender, instead of
invoking it and assign its return value.

Related

C# Searching List of Arrays for specific value and returning related value

I hope this isn't a foolishly simple question. Im very simply trying to figure out how to manipulate a relatively simple table in SQLite through C#.
Im looking to take a parameter and search a List of Arrays for one such array where the parameter matches, and return a related variable within that same array.
For example where an array in the list might be.
Name IATA
Brisbane BNE
The sqlbind:
public static List<Airport> LoadAirports()
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
var output = cnn.Query<Airport>("select * from Airport", new DynamicParameters());
return output.ToList();
}
}
The Class:
class Airport
{
int Id { get; set; }
string Name { get; set; }
string LocationName { get; set; }
string IATA { get; set; }
string PortType { get; set; }
string PortOwner { get; set; }
string MotherPort { get; set; }
bool Active { get; set; }
bool IsApplyMeetAndGreet { get; set; }
decimal MeetAndGreet { get; set; }
}
The main Program:
List<Airport> Airports = new List<Airport>();
public FreightCalculator()
{
LoadAirportsList();
string OriginName = OriginInput.Value;
var OriginAirport = Airports.Where(s => s.Name == OriginName);
}
private void LoadAirportsList()
{
Airports = SqliteDataAccess.LoadAirports();
}
Ive tried various combinations of Where, Equals, For each indexing etc. Always getting an error of some kind.
The Error with the above Airports.Where is that the s.Name is inaccessible due to its protection level.
If I do:
var OriginAirport = Airports.Where(Name => Name == OriginName);
I get an error where the operand == cannot be used with Airport and String (Though Name is a string in Airport.)
Im either missing something simple or making this more complicated than it needs to be. Once I find the matching Airport, I need to return the IATA code.
Which I envisage looking like this:
var OriginIATA = OriginAirport.IATA;
Im tired and feeling dumb. Please help :(
Since you declared all members of the Airport class as properties I assume you wanted to expose them publicly.
The error you get is because they are private members and can't be accessed outside the class.
Change "Airport" class to:
class Airport
{
public int Id { get; set; }
public string Name { get; set; }
public string LocationName { get; set; }
public string IATA { get; set; }
public string PortType { get; set; }
public string PortOwner { get; set; }
public string MotherPort { get; set; }
public bool Active { get; set; }
public bool IsApplyMeetAndGreet { get; set; }
public decimal MeetAndGreet { get; set; }
}

Convert JSON string to object C#

I have JSON string results as follows.
In this response Sometimes sizeKey and sizeName properties are returned as a string. But sometimes both properties are returns inside an array as follows
I am using following code to convert it to object
var assets = jObject["assets"].Children().ToList();
foreach (var item in assets)
{
decorationAssets.Add(item.ToObject<AEDecorationAssets>());
}
And my AEDecorationAssets class is as follows.
public class AEDecorationAssets
{
public string Id { get; set; }
public string Url { get; set; }
public string[] Colors { get; set; }
public string FontKey { get; set; }
public string SizeKey { get; set; }
public string ViewKey { get; set; }
public string FontName { get; set; }
public int Rotation { get; set; }
public string SizeName { get; set; }
public string TextValue { get; set; }
public string EntityType { get; set; }
public string LocationCode { get; set; }
public string LocationName { get; set; }
public string TextEffectKey { get; set; }
public string TextEffectName { get; set; }
public string DecorationMethod { get; set; }
public string NumDecorationColors { get; set; }
}
At the time when "sizeKey" is an array, the above code gives an error. How can I resolve this issue? Is there any JSON property we can use to resolve it?
One way you can do it is by making your SizeKey type an object (i.e. public object SizeKey { get; set; }), then you can switch/case on item.ToObject<AEDecorationAssets>().SizeKey.GetType() to figure out how to handle it (i.e. if String do this, if JArray do that), etc.
If a JSON type is sometime an array, and sometimes a string, you can't really map it simply to a .NET type, as there is none that supports this behavior.
So first you need a datatype that can store this, like and string[] or List<string>.
It could be that JsonConvert will solve this automatically, but otherwise you'll need to write a custom ContractResolver or JsonConverter. Here you can detect if the source property is a string or array. If it's an array, you can use the default deserialization. If it is a string, you need to convert it to an array with a single value.
Simply get json result for which you want to create c# object and then you can valid json response from https://jsonlint.com/ and then you can create c# object of any type json response which you want through http://json2csharp.com. And after get c# object of your json response you only need to deserialization of your json response to c# object which you have created. which will return you expected result.

Deserialize CSV string to an C# Object

I have a response from Jira API, require to be deserialized into data model:
com.atlassian.greenhopper.service.sprint.Sprint#40675167[id=10151,rapidViewId=171,state=CLOSED,name=Sprint 37.1,startDate=2015-07-30T16:00:22.000+03:00,endDate=2015-08-13T16:00:00.000+03:00,completeDate=2015-08-13T14:31:34.343+03:00,sequence=10151]
This is actually the information of current sprint for issue.
I need to deserialize it to a model like:
public class Model
{
public string name { get; set; }
...
}
I have already removed all non-required information, like com.atlassian.greenhopper.service.sprint.Sprint#40675167 using Regex pattern \[(.*?)\] so I have brackets and all inside.
Now I stopped completely trying to find the a way to convert this string to a data model.
Found the following thread at the Atlassian Answers page and there appears to be no JSON representation of that inner Object. As shown in the example from that thread:
customfield_10007:[
"com.atlassian.greenhopper.service.sprint.Sprint#a29f07[rapidViewId=<null>,state=CLOSED,name=NORD - Sprint 42,startDate=2013-07-29T06:47:00.000+02:00,endDate=2013-08-11T20:47:00.000+02:00,completeDate=2013-08-14T15:31:33.157+02:00,id=107]",
"com.atlassian.greenhopper.service.sprint.Sprint#769133[rapidViewId=<null>,state=ACTIVE,name=NORD - Sprint 43,startDate=2013-08-14T15:32:47.322+02:00,endDate=2013-08-23T15:32:47.322+02:00,completeDate=<null>,id=117]"
],
The response is indeed a JSON array, but the array itself contains CSV's, so you can make use of the following to parse that:
public class DataObject
{
public string id { get; set; }
public string rapidViewId { get; set; }
public string state { get; set; }
public string name { get; set; }
public string startDate { get; set; }
public string endDate { get; set; }
public string completeDate { get; set; }
public string sequence { get; set; }
}
public class Program
{
private const string sampleStringData =
#"[id=10151,rapidViewId=171,state=CLOSED,name=Sprint 37.1,startDate=2015-07-30T16:00:22.000+03:00,endDate=2015-08-13T16:00:00.000+03:00,completeDate=2015-08-13T14:31:34.343+03:00,sequence=10151]";
static void Main(string[] args)
{
var dataObject = new DataObject();
string[][] splitted;
var sampleWithNoBrackets = sampleStringData.Substring(1,sampleStringData.Length-2);
splitted = sampleWithNoBrackets.Split(',').Select(p => p.Split('=')).ToArray();
dataObject.id = splitted[0][1];
dataObject.rapidViewId = splitted[1][1];
dataObject.state = splitted[2][1];
dataObject.name = splitted[3][1];
dataObject.startDate = splitted[4][1];
dataObject.endDate = splitted[5][1];
dataObject.completeDate = splitted[6][1];
dataObject.sequence = splitted[7][1];
Console.ReadKey();
}
}
Here's the output for the above:

how can convert var to List c#

I would like to convert var to list value . I am getting 'myobj' var value. Now how can i convert to CandidateResume list ?.
JavaScriptSerializer jsSerializer = new JavaScriptSerializer() { MaxJsonLength = 86753090 };
var myobj = jsSerializer.Deserialize<List<List<CandidateResume>>>(description);
My CandidateResume class like this
public class CandidateResume
{
public string name { get; set; }
public string url { get; set; }
public string summary { get; set; }
public string role { get; set; }
public string compensation { get; set; }
public string education { get; set; }
public string expertise { get; set; }
public string years { get; set; }
public string relocation { get; set; }
public string resume { get; set; }
public string resumeExtension { get; set; }
public string resumeMimeType { get; set; }
}
Please see this current item value in screenshot
How can i catch item value ?
foreach (var item in myobj)
{
WebScrappingCandidate webScrappingCandidate = new WebScrappingCandidate();
}
Deserialize<T> returns a T (MSDN), which means myObj is already of type: List<List<CandidateResume>>.
Remember, var is not a type, it just uses type inference to be shorthand for: "Be whatever type I'm being assigned to".
To "flatten" this list, you could just use SelectMany:
foreach (CandidateResume resume in myObj.SelectMany(i => i))
{
}
Of course, there are other methods as well, but the crux of the answer is that you already have a list of candidate resumes. No conversion required.
You already have a list, the Deserialize method returns a typed result:
List<List<CandidateResume>> myobj =
jsSerializer.Deserialize<List<List<CandidateResume>>>(description);
When you loop through that, each item is a list:
foreach (List<CandidateResume> item in myobj) {
...
}

How to update Mongo DB by parsing a list of object

I'm using c#
one of the mongo db document is in such structure
Class QuestionData{
public Guid Id { get; set; }
public string Type { get; set; }
public List<NotesQuestion> Question { get; set; }
}
So I want to do a updating. I write the update as following:
var update = Update.Set("Question", data.Question);
The 'data' is a type of QuestionData.
But now it says "invalid argument" of data.Question.
If I change it to
var update = Update.Set("Question", data.Question.ToJson());
It has no problem. But I don't want to save it as json string.
How to resolve this issue?
With my own model classes,
internal class QuestionData
{
[BsonId] public Guid Id { get; set; }
[BsonElement("type")] public string Type { get; set; }
[BsonElement("qnotes")] public QuestionNote[] QuestionNotes { get; set; }
}
[BsonNoId] internal class QuestionNote
{
[BsonElement("q")] public string Question { get; set; }
[BsonElement("n")] public string Note { get; set; }
}
you can overwrite the whole bson array like:
// get client, database, collection ...
var col = Database.GetCollection<QuestionData>("questions");
// QuestionNote[] toModifyWith = ...
var udb = Builders<QuestionData>.Update;
var fdb = Builders<QuestionData>.Filter;
var ur = await col.UpdateManyAsync(fdb.Empty, udb.Set(x => x.QuestionNotes, toModifyWith ));

Categories