I have three classes:
public class M2ArticleMain
{
public int Id { get; set; }
public List<M2ArticleAttributeWeb> Attribut_Web { get; set; }
}
public class M2ArticleAttributeWeb
{
public int Web_Id { get; set; }
public M2ArticleTmpMainSkus Variants { get; set; }
}
public class M2ArticleTmpMainSkus
{
public DateTime TimeAdded { get; set; }
public List<string> Skus { get; set; }
}
And I have two Lists in my code like this:
List<M2ArticleMain> data = new List<M2ArticleMain>();
List<M2ArticleAttributeWeb> attb = new List<M2ArticleAttributeWeb>();
In some part of my code firstly I (from foreach loop) add data to attb list where I add only only some data (because I don't have all data at this point), like this:
...
attb.Add(new M2ArticleAttributeWeb
{
Web_id = item.Id, //(item is from foreach loop)
Variants = null //this is **importat**, I left null for later to add it
});
Next, after I fill attb, I add all this to data list:
...
data.Add(new M2ArticleMain
{
Id = item.Id_Pk, //this is also from foreach loop,
Attribut_Web = attb //now in this part I have only data for Web_id and not Variants
}
Now my question is How to Add items later to data list to object Variants?
Something like this:
data.AddRange( "how to point to Variants" = some data);
The M2ArticleAttributeWeb type holding your Variants property is the member of a collection. That is, there are potentially many of them. You can reference an individual Variants property like this:
data[0].Attribut_Web[0].Variants
But you need to know which items you want to add map to which data and Attribut_Web indexes/objects in order to assign them properly. That probably means another loop, or even a nested loop. That is, you can see all of your Variants properties in a loop like this:
foreach(var main in data)
{
foreach(var attrw in main)
{
var v = attrw.Variants;
// do something with v
Console.WriteLine(v);
// **OR**
attrw.Variants = // assign some object
}
}
It's also much better practice to create your collection properties with the object, and then give them private set attributes:
public class M2ArticleMain
{
public int Id { get; set; }
public List<M2ArticleAttributeWeb> Attribut_Web { get; private set; } = new List<M2ArticleAttributeWeb>();
}
public class M2ArticleAttributeWeb
{
public int Web_Id { get; set; }
public M2ArticleTmpMainSkus Variants { get; set; }
}
public class M2ArticleTmpMainSkus
{
public DateTime TimeAdded { get; set; }
public List<string> Skus { get; private set; } = new List<string>();
}
Now instead of assigning Attribut_Web = attb, you would need to .Add() to the existing List.
Related
I am currently struggling to accept a list of objects from FormData in ASP.NET Core.
The project looks like this:
I have a class called Stavka (English: Item).
public class Stavka
{
public string naziv { get; set; }
public double cenaPoJedinici { get; set; }
public string jedinicaMere { get; set; }
public int kolicina { get; set; }
public Stavka(string naziv, double cenaPoJedinici, string jedinicaMere, int kolicina)
{
this.naziv = naziv;
this.cenaPoJedinici = cenaPoJedinici;
this.jedinicaMere = jedinicaMere;
this.kolicina = kolicina;
}
public Stavka()
{
}
}
I have a class called Faktura (English: Bill) which has a variable called Stavke (English: Items) that is a list containing the Stavka objects.
public class Faktura
{
public int Id { get; set; }
public string pibStart { get; set; }
public string pibEnd { get; set; }
public DateTime datumGen { get; set; }
public DateTime datumRok { get; set; }
public List<Stavka> stavke { get; set;}
public double cena { get; set; }
public string tip { get; set; }
public Faktura(int id, string pibStart, string pibEnd, DateTime datumGen, DateTime datumRok, List<Stavka> stavke, string tip)
{
Id = id;
this.pibStart = pibStart;
this.pibEnd = pibEnd;
this.datumGen = datumGen;
this.datumRok = datumRok;
this.stavke = stavke;
this.tip = tip;
double sumCena = 0;
foreach(Stavka s in stavke)
{
sumCena += s.kolicina * s.cenaPoJedinici;
}
this.cena = sumCena;
}
public Faktura()
{
}
I want to create a new Faktura object and add it to a list within my Controller. I tried to do this with the following code:
[HttpPost("dodajFakturu")]
public IActionResult dodajFakturu([FromForm]string pibStart, [FromForm]string pibEnd,[FromForm]DateTime datumStart, [FromForm]DateTime datumEnd,[FromForm]List<Stavka> stavkeLis, [FromForm]string tip)
{
int id = lst.OrderByDescending(p => p.Id).First().Id + 1;
Faktura f = new Faktura(id, pibStart,pibEnd, datumStart,datumEnd,stavkeLis,tip);
lst.Add(f);
return Ok(SveFakture());
}
And yet, when i post the request (in Swagger/Postman), the variable stavkeLis (which accepts the JSON array) is always empty:
This is certainly because i fundamentally misunderstood the way in which NET Core accepts these variables.
Is there some other way to send a list of objects through form data?
this way you have is currect, but if its not maybe because simple code problem but way that you right the code can be better or you can say develop your code as Below:
// StavkaBody => I Mean All Body In One Json
public async Task<IActionResult> MethodName([FromForm] string
StavkaBody)
{
YourObjectType object = new YourObjectType();
// this will be Populate All Json To Single object And
// You dont Need To Add some Constructors For Done this
JsonConvert.PopulateObject(StavkaBody, objec);
// Example Usage
Console.WriteLine(object.Name);
}
in Here I`ve Used The Newtonsoft.Json For this And Its Make Your Model So Much Simpler.
I Hope Its Helps
Firstly thank you for taking the time to look at this. It's quite alot.
Question:
I'm basically trying to download a json as a string and then deserialize it to a list. The reason why is so i can then call a specific property of that list (in my case 'ips' because it's all i actually need) and insert it into a table if requirements are met.
The problem is that it moves all null values into the array. 114 columns of null, or empty array and i can't figure out why?
I think i'll attach a link to the JSON because its a massive file its here https://endpoints.office.com/endpoints/Worldwide?clientRequestId=b10c5ed1-bad1-445f-b386-b919946339a7
Here is my code:
Getters and setters for JSON
public class GetSetJsonIP {
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("serviceArea")]
public string ServiceArea { get; set; }
[JsonProperty("serviceAreaDisplayName")]
public string ServiceAreaDisplayName { get; set; }
[JsonProperty("urls")]
public IList<string> urls { get; set; }
[JsonProperty("ips")]
public IList<string> ips { get; set; }
[JsonProperty("tcpPorts")]
public string tcpPorts { get; set; }
[JsonProperty("expressRoute")]
public bool expressRoute { get; set; }
[JsonProperty("category")]
public string category { get; set; }
[JsonProperty("required")]
public bool required { get; set; }
[JsonProperty("notes")]
public string notes { get; set; }
[JsonProperty("udpPorts")]
public string udpPorts { get; set; }
}
List class
public class ConvertJsonIP{
public List<GetSetJsonIP> jsonIpConvert { get; set; }
public List<GetSetJsonIP> jsonIPConvert = new List<GetSetJsonIP>();
}
3.I download the JSON using an empty string called o365IP
o365IP = wc.DownloadString(wc.BaseAddress + "/endpoints/Worldwide?clientRequestId=b10c5ed1-bad1-445f-b386-b919946339a7");
I deserialize using my List to a seperate var
var o365IpVerion = JsonConvert.DeserializeObject<List<ConvertJsonIP>>(o365IP);
This code shows no errors. so i can only assume its a logical one on my part. It should be noted that i had to put the <List< in to stop an error stating that it couldnt convert an object to an array.
Seriously, i've been stuck on this for 3 days so any help on this would be greatly appreciated! Thanks in advance!
the json you have is a list of objects and each of these objects conform to GetSetJsonIp. You should deserialize using List<GetSetJsonIP>
var o365IpVerion = JsonConvert.DeserializeObject<List<GetSetJsonIP>>(o365IP);
public class GetJsonIP works fine.
The reason you must Deserialize into a List<> is because the json object starts with a bracket making the entire object a List or array.
var O365IpVersion = JsonConvert.DeserializeObject<List<GetJsonIP>(O365IP);
There are different ways to fetch the value of a certain property. If you just need ips and want to check the value then update it, then you could loop:
JArray arr = JArray.Parse(O365IP);
foreach (JObject obj in arr.Children<JObject>())
{
foreach (JPRoperty prop in obj.Properties().Where(x => x.Name == "ips"))
{
//use prop.Value and perform tasks
}
}
Or just simply loop like this:
for (int i = 0; i < O365IpVersion.Count; i++)
{
//use O365IpVersion.ElementAt(i).ips
I have a class that I am populating with a view to serializing into JSON
My class has strings and one IEnumerable of a second class (Icons)
public class ManifestModel
{
public string ShortName { get; set; }
public string Name { get; set; }
public IEnumerable<Icon> Icons { get; set; }
public string BackgroundColour { get; set; }
public string ThemeColour { get; set; }
public class Icon
{
public string Src { get; set; }
public string Type { get; set; }
public string Sizes { get; set; }
}
}
When creating an instance of ManifestModel, it is easy enough to populate the string properties, but how do I add my two icon variables (icon192 and icon512)?
var icon192 = new ManifestModel.Icon
{
Src = "192",
Type = "images/png",
Sizes = "192x192"
};
var icon512 = new ManifestModel.Icon
{
Src = "512",
Type = "images/png",
Sizes = "512x512"
};
var manifestModel = new ManifestModel
{
ShortName = siteRoot.GetValue<string>("siteTitle"),
Name = siteRoot.GetValue<string>("siteName"),
//how to add two Icon objects here
};
I have tried
Just create an array and assign to Icons property.
var manifestModel = new ManifestModel
{
Icons = new[] { icon192, icon512 },
//...
Because Icons is an IEnumerable, you can create a list
var manifestModel = new ManifestModel
{
Icons = new List<ManifestModel.Icon>() { icon192, icon512 },
//do something
It is uncommon to use a read/write property to maintain a list of items in an object. What you generally want is a solution, where you can just write:
foreach (Icon icon in model.Icons) {
//Do something
}
With a read/write property, Icons can be null and the result will be a NullReferenceException.
What is even worse is that you will add the potential for subtle bugs. When you start iterating over Icons and you set the value during the iteration, you might expect that you are continuing to iterate over the new list. This is not the case though, you're still iterating over the previous value. Usually in these cases the original iteration should fail with an InvalidOperationException upon continuation.
To avoid this problem, use a collection that is derived from System.Collections.ObjectModel.Collection<T> and expose it as a property:
public class IconCollection : Collection<Icon> {
//Customize here
}
public class ManifestModel
{
//
public IconCollection Icons { get; } = new IconCollection();
//...
}
When you want to add items you go:
model.Icons.Add(icon);
This will avoid the problems described above.
Sorry if this is a simple question but if I want to have a list inside a model, and later access and set the values of the list?
Say my main model looks like this:
public class StartPageModel : IPageViewModel<StartPage>
{
public IList<ListContent> ListContent { get; set; }
public StartPage CurrentPage { get; set; }
}
public class ListContent
{
public IList<ListElement> ArticleListContent { get; set; }
public IList<ListElement> InsightListContent { get; set; }
}
How can I set the ArticleListContent list to a value by referencing the parent model?
public ActionResult Index(StartPage currentPage)
{
var model = new StartPageModel(currentPage);
model.ListContent.ArticleListContent = GetListContent(currentPage.ArticleCollection);
}
However this returns the error:
IList does not contain a definition for 'ArticleListContent'
I'm not sure you require a collection of ListContent in your StartPageModel, correct me if I'm wrong.
Change
public IList<ListContent> ListContent { get; set; }
to
public ListContent ListContent { get; set; }
And provided ListContent is initialized, your assignment will work.
It's because it's referencing the List of ListContent, not an individual item in that list. Here's some examples:
var model = new StartPageModel(currentPage);
model.ListContent[0].ArticleListContent = GetListContent(currentPage.ArticleCollection); // Access first in list
model.ListContent[1].ArticleListContent = GetListContent(currentPage.ArticleCollection); // Access secondin list
model.ListContent.First().ArticleListContent = GetListContent(currentPage.ArticleCollection); // Access first in list using Linq
I need a clear example that shows me how to define a list that has n rows and 4 columns and how to use it. I need a list to save my data like the below image. as you see this could be a dictionary.
You need to create a class with all the above properties
public class Sample
{
public string vocabulary { get; set; }
public string meaning { get; set; }
public int number { get; set; }
public int group { get; set; }
}
and then you can create a List of type Sample,
List<Sample> yourList = new List<Sample>();
You can add items to the list as below
yourList.Add(new Sample { vocabulary = "massive", meaning = "very big", number = 5, group = 15 });
You can access them later like this, if you want the first element,
var result = yourList[0];
this is the easiest and best way of doing it. You need to create a new class and then create new instances of the class and then add it to the list and then use LINQ to get the data out
void Main()
{
var list = new List<myClass>()
list.Add(new myClass() {
Vocabluary = "Vocabluary ",
Meaning = "meaning",
Number = 1,
Group = 2})
}
public class myClass
{
public string Vocabluary { get; set; }
public string Meaning { get; set; }
public int Number { get; set; }
public int Group { get; set; }
}
yes... as Sajeetharan mentioned, with a custom class you can create an any dimensions List. but i don't think you need to think about dimension in C#... it is a bit more high level than that.
just simply create a class and put everything you need in it...
public class CustomClass{
public string d1;
public int d2;
public string d3;
public string d4;
...
//you can easily create a N dimension class
}
to access it and apply it
public void Main(){
List<CustomClass> list = new List<CustomClass>();
CustomClass cc = new CustomClass();
cc.d1 = "v1";
cc.d2 = 0; //v2
list.Add(cc);
//to access it
foreach(CustomClass tmpClass in list)
{
string d1Value = tmpClass.d1;
int d2Value = tmpClass.d2;
}
}