JSON parsing using .NET deserialize() with nested "list" - javascript

EDIT: Simplified the classes
{
"name": "Final Five",
"bio": null,
"noPlayers": "0",
"roster": {
"players0": {
"playerId": "3516",
"name": "Gate",
"role": "Mid Lane",
"isStarter": 1
},
"players1": {
"playerId": "3826",
"name": "Veritas",
"role": "AD Carry",
"isStarter": 1
},
"players2": {
"playerId": "4054",
"name": "Novel",
"role": "Support",
"isStarter": 1
},
"players3": {
"playerId": "4142",
"name": "Wizardry",
"role": "Top Lane",
"isStarter": 0
},
"players4": {
"playerId": "4555",
"name": "Metroid",
"role": "Jungler",
"isStarter": 0
},
"players5": {
"playerId": "4554",
"name": "Chau",
"role": "Jungler",
"isStarter": 0
},
"players6": {
"playerId": "3847",
"name": "Biofrost",
"role": "Support",
"isStarter": 0
}
},
"logoUrl": "http://riot-web-cdn.s3-us-west-1.amazonaws.com/lolesports/s3fs-public/final-five-logo.png",
"profileUrl": "http://na.lolesports.com/node/3498",
"teamPhotoUrl": "http://na.lolesports.com/",
"acronym": "F5"
}
I have this json being received on my end. The problem I'm having is trying to parse the players as a list instead of individual elements since the number of players may vary. I've tried using arrays and lists. These are the classes I have set up
public class Player
{
public string playerId { get; set; }
public string name { get; set; }
public string role { get; set; }
public int isStarter { get; set; }
}
public class Roster
{
public Player players0 { get; set; }
public Player players1 { get; set; }
public Player players2 { get; set; }
public Player players3 { get; set; }
public Player players4 { get; set; }
public Player players5 { get; set; }
public Player players6 { get; set; }
}
public class Team
{
public string name { get; set; }
public object bio { get; set; }
public string noPlayers { get; set; }
public Roster roster { get; set; }
public string logoUrl { get; set; }
public string profileUrl { get; set; }
public string teamPhotoUrl { get; set; }
public string acronym { get; set; }
}
This is my deserialization:
Team team = new JavaScriptSerializer().Deserialize<Team>(responseText);

One possibility is to deserialize into a dynamic object and convert from that to your strongly-typed object. Like so:
var dict = new JavaScriptSerializer().Deserialize<dynamic>(responseText);
The resulting dict object is a dictionary, with each property represented as a name-value pair in the dictionary. Nested objects, such as roster and its contained playersX objects are themselves represented as dictionaries.
So, for example, you would get to the name property of the player1 object like so:
Assert.AreEqual("Veritas", dict["roster"]["players1"]["name"]);
If it helps at all, you could just make the roster property dynamic, like so:
public class Team
{
public string name { get; set; }
public object bio { get; set; }
public string noPlayers { get; set; }
public dynamic roster { get; set; }
public string logoUrl { get; set; }
public string profileUrl { get; set; }
public string teamPhotoUrl { get; set; }
public string acronym { get; set; }
}
Then only that property will be deserialized as a dictionary of dictionaries.

Related

ASP NET MVC passing ajax list items to controller not working as expected

I am trying to pass a list of objects to Controller using ajax, it works and shows how many items are there but shows items as null and I do not know what I am misisng.
I have this in JavaScript:
var data = {
"expediente": '#Model.NUMEMP',
"edad": '#edad',
"sexo": '#Model.SEXO',
"piezasConNotas": piezasYNotas,
//"servicio": $("#actividades").val(),
//"subServicio": $("#actividadesRealizar").val(),
"diagnostico": $("#diagnosticos").val(),
"interconsulta_esp": "",
"interconsulta": $("#interconsulta").val(),
};
console.log(data);
$.ajax({
'url': ' #Url.Action("AgregarExpedienteDental", "ServiciosMedicos")',
"data": data ,
"success": function (result) {
if (result === "1") {
//swal("Good job!", "You clicked the button!", "success");
Swal.fire('Success', 'Se ha insertado', 'success');
setTimeout('', 3000);
const myTimeout = setTimeout(myGreeting, 1500);
}
},
"error": function (response) {
}
});
this is what console.log(data) shows:
and when I send them to controller this is how it shows in the debugger:
as you can see other data is ok and the count from the list is ok but the items are going inside
as null.
I do not know what I am doing wrong? How do I solve this?
this is my C# code:
public JsonResult AgregarExpedienteDental(ExpedienteDentall data)
{
....
}
public class ExpedienteDentall
{
public string diagnostico { get; set; }
public string edad { get; set; }
public string expediente { get; set; }
public string interconsulta { get; set; }
public string interconsulta_esp { get; set; }
//public string servicio { get; set; } = "";
public string sexo { get; set; }
//public string subServicio { get; set; } = "";
public List<piezasConNotas> piezasConNotas { get; set; }
}
public class piezasConNotas
{
public string diente { get; set; }
public string nota { get; set; }
public string actividad { get; set; }
public string actividadRealizada { get; set; }
}

Convert array of key objects pair to a C# object

I have a api that return data in this format
{ "reult":
{ "70":
{
"type_id": 3,
"type": "forex",
"group_title": "forex",
"name": "EUR",
"title": "EUR"
},
"724":
{
"type_id": 5,
"type": "shares",
"group_title": "shares",
"name": "#ABT",
"title": "#ABT"
}
}
}
Now I want these key object pair data to a genuine C# object array. Like this
[
{
Id = 70
Type_id = 3,
Type = "forex",
Group_title = "forex",
Name = "EUR",
Title = "EUR"
},
{
Id = 724,
Type_id = 5,
Type = "shares",
Group_title = "shares",
Name = "#ABT",
Title = "#ABT"
}
]
Is it possible to do so?
[I have Updated the api returned data. Because with this format it is easy to desterilize this data with c# Dictionary]
Say you have some classes:
public class Root
{
[JsonProperty("result")]
public Dictionary<int, Data> Result {get;set;}
}
public class Data
{
[JsonIgnore]
public int Id { get; set; }
[JsonProperty("type_id")]
public int TypeId { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("group_title")]
public string GroupTitle { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
}
You can deser the original data (not the one you modified by removing "result") and then call, if you want an array out of it:
var root = JsonConvert.DeserializeObject<Root>(str);
foreach(var kvp in root.Result) kvp.Value.Id = kvp.Key;
var arr = root.Result.Values.ToArray();
ps; you need references to Newtonsoft.Json; System.Collections.Generic; System.Linq;
create class with those properties
then use below code:
JsonSerializer.Deserialize<List<object>>(jsonString);
here is link to more detail:
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-6-0
When i deserialized your json to c# class
it is right class object
maybe your json is not correct
it is c# class:
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class _70
{
public int type_id { get; set; }
public string type { get; set; }
public string group_title { get; set; }
public string name { get; set; }
public string title { get; set; }
}
public class _724
{
public int type_id { get; set; }
public string type { get; set; }
public string group_title { get; set; }
public string name { get; set; }
public string title { get; set; }
}
public class Reult
{
public _70 _70 { get; set; }
public _724 _724 { get; set; }
}
public class Root
{
public Reult reult { get; set; }
}

Infragistics IgniteUI Tree Load OnDemand

I am using the plugin http://www.igniteui.com/tree/overview and want to load the tree data on demand.
My declaration of the tree is :
$("#tree").igTree({
checkboxMode: "off",
singleBranchExpand: true,
loadOnDemand: true,
dataSourceUrl : "/home/getagreements",
nodeClick: function (evt, ui) {
},
dataSourceType: "json",
initialExpandDepth: -1,
pathSeparator: ".",
bindings: {
textKey: "Text",
valueKey: "Value",
imageUrlKey: "ImageUrl",
childDataProperty: "Value",
Description: "Description"
},
},
dragAndDrop: false,
nodeExpanding: function (evt, ui) {
}
});
and the JSON output for home/getagreements is
return Json(agrmnts, JsonRequestBehavior.AllowGet);
where
List<Agreements> agrmnts = new List<Agreements>();
and the class definitions as below:
[JsonObject(MemberSerialization = Newtonsoft.Json.MemberSerialization.OptIn)]
public class AgreementNode
{
[JsonProperty(Order = 1)]
public string AgreementNbr { get; set; }
[JsonProperty(Order = 2)]
public string ExternalDescription { get; set; }
[JsonProperty(Order = 3)]
public string Description { get; set; }
[JsonProperty(Order = 4)]
public string EffDate { get; set; }
[JsonProperty(Order = 5)]
public string ExpDate { get; set; }
[JsonProperty(Order = 6)]
public string ReleaseStatus { get; set; }
[JsonProperty(Order = 7)]
public string ImageUrl { get; set; }
[JsonProperty(Order = 8)]
public string Folder { get; set; }
[JsonProperty(Order = 9)]
public string Value { get; set; }
[JsonProperty(Order = 10)]
public string Text { get; set; }
}
public class Agreements
{
public string AgreementType { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public string Folder { get; set; }
public string ImageUrl { get; set; }
public List<AgreementNode> agreements { get; set; }
}
The first level data is displayed correct but when I click the node the same data is binding again. Please suggest if I am missing any configuration settings for Loading on Demand
With the current configuration the igTree is using the dataSourceUrl to request the new data from the same controller action you used to bind the initial level. At this point you would need to use the parameters the tree is providing to the controller action - path, binding and depth - to return the correct layer of data.
Here's an example of how you can do this.

Unable to deserialize a JSON string generated by a JQuery plugin

I using a JQuery plugin that enable my users to design forms. The design is saved in form of a JSON string in database. This JSON string is in following format:
{
"fields": [{
"label": "Untitled",
"field_type": "text",
"required": true,
"field_options": {
"save_to": "",
"size": "small",
"description": ""
},
"cid": "c5"
}]
}
Following is C# class structure and code that is used to deserialize this JSON string:
public class Options {
public string label {
get;
set;
}
public bool Checked {
get;
set;
}
}
public class FieldOption {
public string save_to {
get;
set;
}
public string description {
get;
set;
}
public object options {
get;
set;
}
public bool include_other_option {
get;
set;
}
public string size {
get;
set;
}
}
public class DesignField {
public string label {
get;
set;
}
public string field_type {
get;
set;
}
public bool required {
get;
set;
}
public string cid {
get;
set;
}
public List < FieldOption > field_options {
get;
set;
}
}
public class Design {
public List < DesignField > fields {
get;
set;
}
}
public partial class FormDesign: System.Web.UI.UserControl {
List < DesignField > FormFields;
public string FormDesignData {
get;
set;
}
protected void Page_Load(object sender, EventArgs e) {
Design res = JsonHelper.JsonDeserialize < Design > (FormDesignData);
}
}
JSON Helper class is given here: http://www.codeproject.com/Articles/272335/JSON-Serialization-and-Deserialization-in-ASP-NET
The problem is that it is deserializing when inner JSON objects are enclosed with [] for example:
"field_options":[{
"save_to": "",
"size": "small",
"description": ""
}]
But the plugin is not exporting the JSON in that format but in the format I mentioned before.
Please tell me how can I convert it to a valid deserializable format?
The model according to your json should be:
public class FieldOptions
{
public string save_to { get; set; }
public string size { get; set; }
public string description { get; set; }
}
public class Field
{
public string label { get; set; }
public string field_type { get; set; }
public bool required { get; set; }
public FieldOptions field_options { get; set; }
public string cid { get; set; }
}
public class RootObject
{
public List<Field> fields { get; set; }
}
I used this online tool http://json2csharp.com/ to generate it.
RootObject is the type you will use to deserialize
Using, for ex, Json.Net, your code would be
var myobj = JsonConvert.DeserializeObject<RootObject>(json);

Custom POST Action including child elements

I want to replace the default Create View and Controller for my modelclass CourseEvent which should be able to handle request containing child elements. The child elements are of type public virtual ICollection<CourseEventDate>.
Model Class CourseEvent
public partial class CourseEvent
{
public CourseEvent()
{
this.CourseEventDates = new HashSet<CourseEventDate>();
this.UsersInCourseEvents = new HashSet<UsersInCourseEvent>();
}
public int CourseEventId { get; set; }
public Nullable<int> CourseFk { get; set; }
public Nullable<int> CourseEventDurationInDays { get; set; }
public Nullable<int> CourseEventDurationInHours { get; set; }
public Nullable<int> CourseEventPrice { get; set; }
public virtual Course Course { get; set; }
public virtual ICollection<CourseEventDate> CourseEventDates { get; set; }
public virtual ICollection<UsersInCourseEvent> UsersInCourseEvents { get; set; }
}
Model Class CourseEventDate
public partial class CourseEventDate
{
public int CourseEventDateId { get; set; }
public Nullable<int> CourseEventFk { get; set; }
public Nullable<System.DateTime> CourseEventDateTimeFrom { get; set; }
public Nullable<System.DateTime> CourseEventDateTimeTo { get; set; }
public virtual CourseEvent CourseEvent { get; set; }
}
If mvc would use JSON for the scafffolded POST requests, I would've considered sending a POST request using JavaScript, the JSON request would look something like this:
{
"CourseFk": "123",
"CourseEventDurationInDays": "2",
"CourseEventDurationInHours": "16",
"CourseEventPrice": "1234",
"CourseEventDate": [{
"CourseEventDateTimeFrom": "2015-05-05 08:00",
"CourseEventDateTimeTo": "2015-05-05 12:00"
},
{
"CourseEventDateTimeFrom": "2015-05-05 13:00",
"CourseEventDateTimeTo": "2015-05-05 17:00"
},
{
"CourseEventDateTimeFrom": "2015-05-06 08:00",
"CourseEventDateTimeTo": "2015-05-06 12:00"
},
{
"CourseEventDateTimeFrom": "2015-05-06 13:00",
"CourseEventDateTimeTo": "2015-05-06 17:00"
}]
}
So what's the best strategy/best practices to solve this problem?

Categories