JsonNET decode with list - json.net

I'm using Json.Net to DeserializeObject Json data.
This is my Json
string datosContratos = {"Total":1,"Contrato":[{"Numero":1818,"CUPS":"ES003L0P","Direccion":"C. O ","TextoCiudad":"MADRID","Tarifa":"2"}]}
My classes are:
public class Contrato
{
public int Numero;
public String Cups;
public String Direccion;
public String TextoCiudad;
public String Tarifa;
}
public class Contratos
{
public int Total { get; set; }
public List<Contrato> ListaContratos { get; set; }
}
when I deseralize:
Contratos contratos = JsonConvert.DeserializeObject<Contratos>(datosContratos);
And the result is that contratos.Total is correct (in this case 1) but the ListaContratos is null although it should be filled with the data. I don't see the problem!!!

Your class must have the same variable names as your JSON, so it should look like this:
public class Contratos
{
public int Total { get; set; }
public List<Contrato> Contrato { get; set; }
}

In your JSON string there is attribute called Contrato,whereas in your class the list of Contrato is declared as ListaContratos
change json string to
string datosContratos = {"Total":1,
"ListaContratos ":[{"Numero":1818,
"CUPS":"ES003L0P",
"Direccion":"C. O ",
"TextoCiudad":"MADRID",
"Tarifa":"2"}]}
OR
change class definition to
public class Contratos
{
public int Total { get; set; }
public List<Contrato> Contrato { get; set; }
}

Related

Deserialize JSON into List with X++

I have a problem with generic types in X++. I need to deserialize a JSON list yet everything I tried failed. Like using IEnumerables and JsonSerializer(does it find only AX classes and can't see references library classes?).
My helper class is in a C# library and I only need to get access to values inside the response JSON that are in list. How can I archive this in X++?
//X++
defaultException defaultException= new defaultException();
defaultException= JsonConvert::DeserializeObject(response, defaultException.GetType()); <- this gives is correct yet I cant use the values in the list
//values = FormJsonSerializer::deserializeCollection(classnum(List), response, Types::Class, 'defaultException');
// C#
public class defaultException
{
public MyException exception { get; set; }
}
public class MyException
{
public string serviceCtx { get; set; }
public string serviceCode { get; set; }
public string serviceName { get; set; }
public string timestamp { get; set;}
public string referenceNumber { get; set; }
public List<exceptionDetailList> exceptionDetailList { get; set; }
}
public class exceptionDetailList
{
public int exceptionCode { get; set; }
public string exceptionDescription { get; set; }
}
Found a solution. If we have another list in this list we need to recreate the enumerator in loop again and again as needed.
defaultException defaultException = new defaultException();
defaultException = JsonConvert::DeserializeObject(batch, defaultException.GetType());
System.Collections.IEnumerable exceptionList = defaultException.exception.exceptionDetailList;
System.Collections.IEnumerator enumerator = exceptionList.GetEnumerator();
while (enumerator.MoveNext())
{
exceptionDetailList exceptionDetailList = new exceptionDetailList();
exceptionDetailList = enumerator.Current;
}

Set values for a nested class in C#

I want to set values for a nested class fields in C#. Herewith I have attached the model class which need to be created. I have completed up to a certain point in assigning values for the class object and stuck with assigning values for the "Description" class. I want to set a value for the "issue. Fields. Description. Content. Content. Text" column. Please help me to set values for this field.
// Class
`
`public partial class JiraIssue
{
[JsonProperty("update")]
public Update Update { get; set; }
[JsonProperty("fields")]
public Fields Fields { get; set; }
}
public partial class Fields
{
[JsonProperty("project")]
public Project Project { get; set; }
[JsonProperty("summary")]
public string Summary { get; set; }
[JsonProperty("issuetype")]
public Issuetype Issuetype { get; set; }
[JsonProperty("description")]
public Description Description { get; set; }
[JsonProperty("customfield_10014")]
public string Customfield10014 { get; set; }
}
public partial class Description
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("version")]
public long Version { get; set; }
[JsonProperty("content")]
public DescriptionContent[] Content { get; set; }
}
public partial class DescriptionContent
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("content")]
public ContentContent[] Content { get; set; }
}
public partial class ContentContent
{
[JsonProperty("text")]
public string Text { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
public partial class Issuetype
{
[JsonProperty("name")]
public string Name { get; set; }
}
public partial class Project
{
[JsonProperty("key")]
public string Key { get; set; }
}
public partial class Update
{
}`
// Assigning values
JiraIssue issue = new JiraIssue();
issue.Fields = new Fields();
issue.Fields.Summary = defect.ProjectName + " - " + defect.ObjectName;
issue.Fields.Customfield10014 = "PROJ3-16";
issue.Fields.Project = new Project();
issue.Fields.Project.Key = "PROJ3";
issue.Fields.Issuetype = new Issuetype();
issue.Fields.Issuetype.Name = "Story";
// Need to Set a value for issue.Fields.Description.Content.Content.Text

ServiceStack AutoQuery join use

After reading the documentation, I am not sure but I have come to the conclusion that when creating QueryDb, you cannot choose the columns to join by? And I am under the impression, you must have DTO object to copy to? You cannot copy to a regular object or a dynamic object?
public class SampleAutoQueryDb : QueryDb<MailResponseDetailOrm, object>, ILeftJoin<MailResponseDetailOrm, MailResponseOrm> { }
Can anyone provide any insight on joining my MailResponseOrm to MailResponseDetailOrm. MailResponseDetailOrm has 5 fields namely the Email address. And I would like MailResponseOrm to be joined to it by Email as well. I also, for good measure do not want to alter either columnname. Would I have to create a custom implementation or a service to do this?
UPDATE
Here is my code as posted below:
[Alias("MailReportsDetail")]
public class MailResponseDetailOrm
{
public string Email { get; set; }
public int ID { get; set; }
[Alias("RespDate")]
public DateTime? AddedDateTime { get; set; }
[Alias("DLReport")]
public string Action { get; set; }
public string ActionDetail { get; set; }
public string IP { get; set; }
public string UserAgent { get; set; }
public string EmailReferrer { get; set; }
}
[Alias("MailReports")]
public class MailResponseOrm
{
public int ID { get; set; }
public string Email { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string Company { get; set; }
public string Contact { get; set; }
public string Country { get; set; }
[Alias("LastMail")]
public DateTime? ModifiedDateTime { get; set; }
[Alias("LastReport")]
public string Action { get; set; }
public DateTime? OptOut { get; set; }
public string Part { get; set; }
public string Phone { get; set; }
public string PostalCode { get; set; }
public string Source { get; set; }
public string State { get; set; }
public string Title { get; set; }
#region Obsolete
[Obsolete]
public string Class { get; set; }
[Obsolete]
public string IP { get; set; }
#endregion
}
public class SampleAutoQueryDb : QueryDb<MailResponseDetailOrm> { }
public class MyQueryServices : Service
{
public IAutoQueryDb AutoQuery { get; set; }
// Override with custom implementation
public object Any(SampleAutoQueryDb query)
{
var q = AutoQuery.CreateQuery(query, base.Request);
q.Join<MailResponseDetailOrm, MailResponseOrm>((x, y) => x.Email == y.Email)
// .Select<MailResponseDetailOrm, MailResponseOrm>((x, y) => new { x.ID, y.Email })
;
return AutoQuery.Execute(query, q);
}
}
Joins in AutoQuery needs to use OrmLite's Joins Reference conventions and all AutoQuery Services results are returned in a Typed DTO, which by default is the table being queried or you can use the QueryDb<From,Into> base class to return a custom result of columns from multiple joined tables.
You would need to use a Custom AutoQuery Implementation or your own Service implementation if you need customizations beyond this, e.g:
public class SampleAutoQueryDb : QueryDb<MailResponseDetailOrm> { }
public class MyQueryServices : Service
{
public IAutoQueryDb AutoQuery { get; set; }
// Override with custom implementation
public object Any(SampleAutoQueryDb query)
{
var q = AutoQuery.CreateQuery(query, base.Request);
q.Join<MailResponseDetailOrm,MailResponseOrm>((x, y) => x.Email == y.Email);
return AutoQuery.Execute(query, q);
}
}
// The query to join 2 objects on field names not specifically set in the class.
var q = Db.From<MailResponseDetailOrm>().Join<MailResponseDetailOrm>(x,y) => x.Email = y.Email);
// Run the query
var results = Db.Select(q);

View Model with a List

If I construct a View Model with a List like this:
public class ProductsViewModel
{
public bool ProductBool { get; set; }
public string ProductString { get; set; }
public int ProductInteger { get; set; }
public List<Product> ProductList { get; set; }
}
it works fine. But I've seen code that constructs a similar Model like so:
public class ProductsViewModel
{
public bool ProductBool { get; set; }
public string ProductString { get; set; }
public int ProductInteger { get; set; }
public List<Product> ProductList { get; set; }
public ProductsViewModel()
{
this.ProductList = new List<Product>();
}
}
What does the extra contructor element actually do?
When you create an object of the class ProductsViewModel with the statement:
ProductsViewModel obj = new ProductsViewModel();
It automatically instantiate the ProductList. The values in obj now are:
ProductBool = false;ProductString = null;ProductInteger = 0;ProductList = new ProductList();
If you write obj.ProductList.Count() it will give 0
If you remove this constructor or the statement inside the constructor and create object of Class ProductsViewModel as created above. The values in obj will be:
ProductBool = false;ProductString = null;ProductInteger = 0;ProductList =null
If you write obj.ProductList.Count() it will give
Exception of NullReference

getting json byte array in list

I got null value for byte array in json web service when deserializing.but it returns byte array when invoked from browser.
C# Code:
var url = re.DownloadString("XXXX/ListService.svc/lstFooddtl/1/21");
var a = JsonConvert.DeserializeObject<FooddtlResult>(url);
In a i got null for food_photo...when i deserialize...
c# Class:
public class photo
{
public byte[] food_photo { get; set; }
}
public class Food
{
public int food_id { get; set; }
public string food_name { get; set; }
public photo[] food_photo { get; set; }
public string unitcost { get; set; }
}
public class FooddtlResult
{
public Food[] Result { get; set; }
}
{"Result":[{"food_id":"61","food_name":"Idli","food_photo":[255,216,255,224,0,....217],"unitcost":null}]}
Your model does not match the JSON. For correct deserialization change your Food class to
public class Food
{
public int food_id { get; set; }
public string food_name { get; set; }
public byte[] food_photo { get; set; }
public string unitcost { get; set; }
}
and remove the photo class.
Otherwise, if you want to keep the model structure, then correct JSON should be:
{"Result":[{"food_id":"61","food_name":"Idli","food_photo":[{"food_photo":[255,216,255,224,0,....217]},{"food_photo":[255,...]},...],"unitcost":null}]}

Resources