Creating an array in C# that contains an object - c#

I have a RequestModel that contains some properties and another class Consignment.
Calling JsonConvert.SerializeObject(this); returns
{ "consignment": { "collectionDetails": null } }
Instead I would like to return an array of the object
"consignment": [ { "collectionDetails": null } ]
I've tried to create Consignment[] but get a conversion issue.
I've also tried to create a List<Consignment>
class RequestModel
{
public string job_id { get; set; }
public Consignment consignment = new Consignment();
public class Consignment
{
public string consignmentNumber { get; set;
}
public string ToJSON()
{
return JsonConvert.SerializeObject(this);
}

Here you go:
public class RequestModel
{
public string job_id { get; set; }
public Consignment consignment { get; set; }
public RequestModel()
{
consignment = new Consignment();
}
public string ToJSON()
{
return JsonConvert.SerializeObject(this);
}
}
Then your Consignment DTO would look like this assuming you have a CollectionItems class (didn't see any code in question around this):
public class Consignment
{
public List<CollectionItems> collectionDetails { get; set; }
public Consignment()
{
collectionDetails = new List<Collection>();
}
}

Related

Deserialize JSON to Nested Model

I have a model like below:
public class YourInformationInputModel
{
public YourInformationInputModel()
{
PrimaryBuyerInformation = new PrimaryBuyerInformationInputModel();
}
public PrimaryBuyerInformationInputModel PrimaryBuyerInformation { get; set; }
public bool TermsCondition { get; set; }
}
PrimaryBuyerInputModel like below:
public class PrimaryBuyerInformationInputModel
{
[Required]
public string BuyerFirstName { get; set; }
public string BuyerMiddleInitial { get; set; }
[Required]
public string BuyerLastName { get; set; }
}
and when I am submitting my form then I am getting JSON like below:
{
"PrimaryBuyerInformation.BuyerFirstName": "Sunil",
"PrimaryBuyerInformation.BuyerMiddleInitial": "",
"PrimaryBuyerInformation.BuyerLastName": "Choudhary",
"TermsCondition": "true"
}
When I am trying to deserialize this json the TermsCondition property successfully done, but the property of PrimaryBuyerInformation is not mapped.
var myObject = JsonConvert.DeserializeObject<YourInformationInputModel>(json);
Any idea how to do that ?
Kindly take a cue from the code below, i tested it and you should be able to get your value as request. This solves the issue of you trying to access the property you have mapped in a dot property name format.
Instead your object should be nested in a curly brace showing that the other property belongs to PrimaryBuyerInformationInputModel which is another object entirely.
Best Regards,
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var json = #"{'PrimaryBuyerInformation': {'buyerFirstName': 'Sunil','buyerMiddleInitial': '','buyerLastName': 'Choudhary'},'termsCondition': false}";
var obj = JsonConvert.DeserializeObject<YourInformationInputModel>(json);
Console.WriteLine(obj.PrimaryBuyerInformation.BuyerFirstName);
}
}
public class YourInformationInputModel
{
public YourInformationInputModel()
{
PrimaryBuyerInformation = new PrimaryBuyerInformationInputModel();
}
public PrimaryBuyerInformationInputModel PrimaryBuyerInformation { get; set; }
public bool TermsCondition { get; set; }
}
public class PrimaryBuyerInformationInputModel
{
public string BuyerFirstName { get; set; }
public string BuyerMiddleInitial { get; set; }
public string BuyerLastName { get; set; }
}

Project a name-value list into an object

I want to be able to save an arbitrary flat object into the name-value list.
public class NameValueListEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[InverseProperty(nameof(NameValueListContentEntity.Entity))]
public ICollection<NameValueListContentEntity> Content { get; set; }
}
public class NameValueListContent
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("entity_fk")]
public NameValueListEntity Entity { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
public class ObjectToSave
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
I could use reflection to manually assemble/parse the list, but it will create a lot of overhead. Lots of NameValueListContent objects will be needlessly created both during the saving and the reading. Could it somehow be omitted? Especially during the reading, which is very performance-sensitive in my case.
Assume you have a AppDbContext class that holds your NameValueListContent class objects named as NVListContents. You can read and write the name-value list of objects by doing the following:
public class AppDbContext : DbContext
{
public DbSet<NameValueListContent> NVListContents { get; set; }
public AppDbContext()
: base()
{ }
}
public class SomeClass
{
private AppDbContext context { get; set; }
public SomeClass(AppDbContext _context)
{
context = _context;
}
public List<ObjectToSave> ReadObjects()
{
return context.NVListContents
.Select(nvlc => new ObjectToSave { Prop1 = nvlc.Name, Prop2 = nvlc.Value
}).ToList();
}
public bool WriteObjects(int id, string name, string value)
{
var query = context.NVListContents
.FirstOrDefault(nvlc => nvlc.Id == id);
if(query != null)
{
query.Name = name;
query.Value = value;
context.Update(query);
context.SaveChanges();
return true;
}
else
{
return false;
}
}
}
Hope, this answers to your question.

Json.Encode object with array string to "[ ]" instead of null

I'm using de Json.Encode(object) function to convert my object to a json.
The problem is I have a string array property (headers) and I want to convert it to { 'headers': [] } instead of { 'headers': null } when it's empty.
My class:
public class BaseObject
{
public LinkModel Links { get; set; }
}
public class LinkModel
{
public SelfLinkModel Self { get; set; }
}
public class SelfLinkModel
{
public string Uri { get; set; }
public string Method { get; set; }
public string[] Headers { get; set; }
}
And the Encoding:
string content = Json.Encode(profile);
To sum up, it converts to:
{
"Links":{
"Self":{
"Uri":"href",
"Method":"GET",
"Headers":null
}
}
}
And I want:
{
"Links":{
"Self":{
"Uri":"href",
"Method":"GET",
"Headers": []
}
}
}
One option would be to initialise the property to an empty array. Do it in the class constructor like this:
public class SelfLinkModel
{
public SelfLinkModel()
{
Headers = new string[0];
}
public string Uri { get; set; }
public string Method { get; set; }
public string[] Headers { get; set; }
}

Trying to work out these interfaces

I'm trying to create some interfaces. The IReportSection object will have one string and a collection of items, which could be different depending on what we're working with. Do I need to make it generic?
The IReport will have one string and a collection of IReportSection.
Here's how I'm trying to define it now.
public interface IReport
{
string ReportName { get; set; }
ICollection<IReportSection> ReportSections { get; }
}
public interface IReportSection
{
string ReportSectionName { get; set; }
ICollection ReportItems { get; }
}
public abstract class ReportSectionBase : IReportSection
{
public string ReportSectionName { get; set; }
public ICollection ReportItems { get; set; }
}
And my models:
pulic class ProjectSubmissionViewModel
{
public int ProjectSubmissionId { get; set; }
public string SubmissionTitle { get; set; }
}
pulic class AffiliateViewModel
{
public int AffiliateId { get; set; }
public string AffiliateName { get; set; }
}
This is how I'm trying to use it in code:
public class ChapterAffiliates : ReportSectionBase
{
public string ReportSectionName { get { return "Chapter Affiliates"; } }
public ICollection<AffiliateViewModel> ReportItems { get; set; }
}
public class ChapterTitles : ReportSectionBase
{
public string ReportSectionName { get { return "Chapter Titles"; } }
public ICollection<ProjectSubmissionViewModel> ReportItems { get; set; }
}
public class SubmissionListViewModel : IReport
{
public ICollection<ProjectSubmissionViewModel> Submissions { get; set; }
public ICollection<AffiliateViewModel> Affiliates{ get; set; }
public string ReportName { get; set; }
public ICollection<IReportSection> ReportSections
{
get
{
var affiliateSection = new ChapterAffiliates
{
ReportItems = Affiliates
};
var titleSection = new ChapterTitles
{
ReportItems = Submissions.Where(s => s.SubmissionTitle.Contains("SomePhrase")).ToList()
};
var sections = new List<IReportSection> { {subSection}, {titleSection} };
return sections;
}
}
}
I'm not sure how to best define this. I'm pretty sure I've done it before, but it's not coming to me.
Are the type parameters for TRType all the same within a certain report? E.g. will you have report sections with different report types in them?
If all types within a report are the same, the solution is relatively simple:
public interface IReport<T> { ... }
If this is not the case - you'll have to do something different, e.g:
public interface IReportSection
{
string ReportSectionName { get; }
ICollection ReportItems { get; }
}
public abstract class ReportSectionBase<TRType> : IReportSection {
...
}
This allows you to put different underlying types in the ReportSections collection related to the report. You'll have to do some more work to get the exact information that you need out of each report section.

Json.Net - Deserialize object with "dynamic" properties

I got the following Json data
{
"HasErrors": false,
"Includes": {
"Products": {
"091006": {
"hej" : "tja"
},
"091026": {
"hej" : "tjafsafsa"
}
}
}
}
By dynamic JSON i mean that the propertys on the Products class changes so I cant hardcode them in the c# class in the same way that I do with "HasErrors" for example.
Example:
{
"HasErrors": false,
"Includes": {
"Products": {
"091006": {
"hej" : "tja"
},
"091026": {
"hej" : "tjafsafsa"
}
}
}
}
Another example:
{
"HasErrors": false,
"Includes": {
"Products": {
"091126": { //CHANGED
"hej" : "tja"
},
"091043226": { //CHANGED
"hej" : "tjafsafsa"
}
}
}
}
I've built up the following classes in .NET
Response.cs
public class Response<T> where T : new()
{
[JsonProperty("hasErrors")]
public bool HasErrors { get; set; }
[JsonProperty("includes")]
public Includes<T> Includes { get; set; }
}
Includes.cs
public class Includes<T> where T : new()
{
[JsonProperty("products")]
public ProductRoot Products { get; set; }
}
ProductRoot.cs
public class ProductRoot
{
[JsonProperty("products")]
public Dictionary<string, Product> Products { get; set; }
}
Product.cs
public class Product
{
[JsonProperty("hej")]
public string Hej { get; set; }
}
I then try to Deserialize it like this:
var hej = JsonConvert.DeserializeObject<Response<Product>>(json_from_above_as_string);
And then I get this error:
Could not cast or convert from System.String to www.Models.Externals.Product.
[JsonSerializationException: Error converting value "091006" to type 'www.Models.Externals.Product'. Path 'Includes.ProductsOrder[0]', line 1, position 15173.]
You guys have any idea of what Im doing wrong?
I've instantiated an object of type <Response<Product>> successfully and serialized it to get a feel about what's happening under the hood and, as an example, the JSON I get out of it is as follows:
{
"hasErrors":false,
"includes":{
"products":{
"products":{
"091006":{
"hej":"tja"
}
}
}
}
}
This shows that your JSON simply doesn't marry up with your object model. You can do a couple of things. Either change your JSON format to something like the above, or change your object model to the following:
public class Response<T> where T : new()
{
[JsonProperty("hasErrors")]
public bool HasErrors { get; set; }
[JsonProperty("includes")]
public Includes<T> Includes { get; set; }
}
public class Includes<T> where T : new()
{
[JsonProperty("products")]
public Dictionary<string, T> Products { get; set; }
}
public class Product
{
[JsonProperty("hej")]
public string Hej { get; set; }
}
I solved it by removing the ProductRoot class.
It now looks like this:
public class Response<T> where T : new()
{
[JsonProperty("hasErrors")]
public bool HasErrors { get; set; }
[JsonProperty("includes")]
public Includes<T> Includes { get; set; }
}
public class Includes<T> where T : new()
{
[JsonProperty("products")]
public Dictionary<string, Product>Products { get; set; }
}

Categories

Resources