How to iterate through Observable collection? - c#

Hi guys i want to ask that i have a Class with properties like following:
public class VLANSPropertyClass
{
public string vname { get; set; }
public int S_No { get; set; }
public string vid { get; set; }
public string ip { get; set; }
public string vports { get; set; }
}
I created an ObservableCollection as follows:
public ObservableCollection<VLANSPropertyClass> vlan { get; set; }
vlan = new ObservableCollection<VLANSPropertyClass>();
I am adding all these values in a datagrid:
void AddVlans()
{
var serial = new VLANSPropertyClass();
serial.S_No = vlan.Count + 1;
Console.WriteLine(serial.S_No);
serial.vname = VlanName;
Console.WriteLine(serial.vname);
serial.vid = VlanID;
Console.WriteLine(serial.vid);
serial.ip = VlanIP1 + "." + VlanIP2 + "." + VlanIP3 + "." + VlanIP4;
Console.WriteLine(serial.ip);
serial.vports = SelectedVlanPort;
vlan.Add(serial);
}
The display looks like following image:
Now i want go through each row and read its values.I tried following but didnt work
foreach(VLANSPropertyClass v in vlan)
{
Console.WriteLine(v);
Console.WriteLine();
}
Kindly tell me the possible way of reading values from ObservableCollection/Datagrid.Any help would be highly appreciable.

You can change your class to this...
public class VLANSPropertyClass
{
public string vname { get; set; }
public int S_No { get; set; }
public string vid { get; set; }
public string ip { get; set; }
public string vports { get; set; }
public override string ToString()
{
return String.Format("Name: {0}, Serial {1}", vname, S_No);
}
}
This change includes an override to the ToString method. It will be called whenever the framework needs a string representation of your class.
ToString is the major formatting method in the .NET Framework. It
converts an object to its string representation so that it is suitable
for display. (For information about formatting support in the .NET
Framework, see Formatting Types.)
source: http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx
Using an override to ToString will let you do this Console.WriteLine(v); with expected results.

When you loop through an ObservableCollection<>, accessing it through index returns a complete instance/item of the collection in form of the string, you now need to reference this string using index or property(in case its a user defined type(class)) in order to access the real content, in my case i am doing this to access temp property of an item of the collection mess.
mess[mj_key][mn_key][0].Temp.ToString()
here i have 3 dimensions, avoid it for now, just understand that 0 index returns string object, i then access temperature using .Temp
Hope it Helps!

Related

Accept a list of objects from form data in ASP.NET Core

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

Get value from Json url with a changing variable

I want to get the price of any crypto coin from BitZ api.
I have the code like this:
string coinName;
string jsonURL = "https://apiv2.bitz.com/Market/coinRate?coins=" + coinName;
I will give the variable coinName the value I want for example coinName = "btc" and I want the price in USDT
The problem here is the Json structure it contains the coin name I will end up with tons of code lines if do this for every coin,
public class Btc
{
public string usdt { get; set; }
}
public class Data
{
public Btc btc { get; set; }
}
public class Root
{
public int status { get; set; }
public string msg { get; set; }
public Data data { get; set; }
public int time { get; set; }
public string microtime { get; set; }
public string source { get; set; }
}
Unlike Bittrex api for example which is easier to read using JsonDotNet asset from unity store and :
BittrexJsonUrl = "https://api.bittrex.com/api/v1.1/public/getticker?market=USDT-" + coinName;
and then I use this code to get the data:
private IEnumerator GetData()
{
/////bittrex
UnityWebRequest request = UnityWebRequest.Get(BittrexJsonUrl);
yield return request.SendWebRequest();
if (request.error == null)
{
Bittrex_proccessJsonData(request.downloadHandler.text);
}
else
{
Debug.Log("Something went wrong!!");
}
}
private void Bittrex_proccessJsonData (string _url) {
var _bittrexJsonData = JsonConvert.DeserializeObject<BittrexJsonData>(_url);
bittrexPrice = _bittrexJsonData.result.Last;
}
this works perfectly with with bittrex's Json structure, since it doesnt contain the coin name all I do is change the Json URL.
Now I want to do like the same thing for BitZ's if you have any idea how to please help :) thank you in advance.
For such thing you could use good old SimpleJson.
Here you don't need to implement the entire c# structure but rather access the data field by field via it's ID. You can imagine it like a nested Dictionary like thing.
Simply create that file with given content from the link somewhere in your project and do e.g.
var json = JSON.Parse(the_JSON_string);
var usdt = json["Data"]["bst"]["usdt"].AsFloat;

JSON (deserialized) sends null values to list

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

Creating a Parse class to handle parsing of file being read in

I wrote a parse class trying to handle parsing the data from a string array into it's appropriate value. I am trying to test this program to see if it will print out the value parse.open, and it is not. It is printing up 0's for the moment (which isn't accurate), until i could figure out why it's not showing what I need.
while (!r.EndOfStream)
{
ParseFileRead parse = new ParseFileRead();
string line = r.ReadLine();
//Send this to Parse class
string [] values = line.Split(',');
//parse records
Console.WriteLine(values[6]); //This is printing the accurate value for parse.open
ParseFileRead.Parse(values);
Console.WriteLine(parse.open); //This is not printing the accurate value
}
Console.Read();
vWriteFile.Close();
And here is my ParseFileRead class:
public class ParseFileRead
{
public int open { get; set; }
public int buy { get; set; }
public int sell { get; set; }
public double settleMM { get; set; }
public string account { get; set; }
public string underlying { get; set; }
public string symbol { get; set; }
public static void Parse(string[] arr)
{
ParseFileRead parse = new ParseFileRead();
parse.account = arr[0];
parse.underlying = arr[12];
parse.symbol = arr[1];
parse.open = Convert.ToInt32(arr[6]);
parse.buy = Convert.ToInt32(arr[7]);
parse.sell = Convert.ToInt32(arr[8]);
parse.settleMM = Convert.ToDouble(arr[10]);
}
}
This is actually correct.
The default value for an uninitialized int is 0.
You are creating a new instance of your ParseFileRead class which will have a value of 0 for open. You then check your parsed value to make sure it's reading in correctly using Console.WriteLine(values[6]);.
Next, you try to parse your values using the Parse function of your ParseFileRead class; which is a void function so it has no return value.
Inside your Parse function you have: ParseFileRead parse = new ParseFileRead(); which creates yet another new instance of your class with a value of 0 for open. This particular instance is never used anywhere and is not the same as the values of the properties created with your initial instance of ParseFileRead
If you put a Console.Write in your Parse function, I'm sure that you will see it being parsed correctly.
So you have 2 options:
Set the properties of your ParseFileRead inside the Parse class without creating a new instance of ParseFileRead
Return the newly created ParseFileRead instance out of your Parse function.
Or a 3rd Option, which is probably best as suggested by Plutonix:
/*Parse class*/
public class ParseFileRead
{
public int open { get; set; }
public int buy { get; set; }
public int sell { get; set; }
public double settleMM { get; set; }
public string account { get; set; }
public string underlying { get; set; }
public string symbol { get; set; }
public ParseFileRead(string[] arr)
{
this.account = arr[0];
this.underlying = arr[12];
this.symbol = arr[1];
this.open = Convert.ToInt32(arr[6]);
this.buy = Convert.ToInt32(arr[7]);
this.sell = Convert.ToInt32(arr[8]);
this.settleMM = Convert.ToDouble(arr[10]);
}
}
/*Parsing code*/
while (!r.EndOfStream)
{
string line = r.ReadLine();
//Send this to Parse class
string [] values = line.Split(',');
//parse records
Console.WriteLine(values[6]); //This is printing the accurate value for parse.open
ParseFileRead parse = new ParseFileRead(values);
Console.WriteLine(parse.open); //This is not printing the accurate value
}

Converting from on type of list to another type

I have two classes - Record and RecordModified
public class Record
{
public int RecordID { get; set; }
public int FacilityID { get; set; }
public int NewAID { get; set; }
public string OldID { get; set; }
public string Data { get; set; }
public int SyncStatusID { get; set; }
public int RecordTypeID { get; set; }//RecordTypeID is integer here.
}
The second class
public class RecordModified
{
public int RecordID { get; set; }
public int FacilityID { get; set; }
public int NewAID { get; set; }
public string OldID { get; set; }
public string Data { get; set; }
public int SyncStatusID { get; set; }
public string RecordTypeText { get; set; }//RecordTypeText is string here.
}
I have a list of Record with at least 100 Record objects, now I have to convert the List<Record> into List<RecordModified>. The RecordTypeID property of the Record class has to be converted to the property RecordTypeText of RecordModified using enums which are in a different class.
Code snippet on how I'm trying to convert:
foreach(Record r in List<Record>)
{
switch(r.RecordTypeID)
{
case (int)MyEnum.One:
listofRecordModified.Add(new RecordModified{RecordTypeID=r.RecordTypeID,...,**RecordTypeText=(MyEnum.One).ToString()})** // Notice this
break;
...........//75 more cases.
}
This solution works fine, but the problem is lot of codes and I don't think its efficient. There must be some better way to do that. Please suggest.
I think you can use ConvertAll Method along with this
List<Record> t = new List<Record>();
var result = t.ConvertAll(x => new RecordModified()
{
RecordTypeText = ((MyEnum)x.RecordTypeID).ToString()
});
If your sole problem is the conversion of the index of an enum to its text, you could use GetNames and use the index of the to get the name of the enum value used.
string text = Enum.GetNames(typeof(MyEnum))[r.RecordTypeID];
This way, you don't need the switch statement, and you can revert to one line only.
You can just use the You can do using the (MyEnum)x.RecordTypeID to cast the integer value to matching enum value. and then use that .ToString() to get string value.Linq Lambda expressions as below,
var result = RecordList.Select(x=>new RecordModified{
RecordTypeID=x.RecordTypeID,
...,
RecordTypeText=((MyEnum)x.RecordTypeID).ToString()
});
You can also use the ConvertAll as,
var result = RecordList.ConvertAll(x => new RecordModified()
{
RecordTypeText = ((MyEnum)x.RecordTypeID).ToString()
});
Select is a LINQ extension method and works on all IEnumerable<> objects whereas ConvertAll is implemented only by List<>. The ConvertAll method exists since .NET 2.0 whereas LINQ was introduced with 3.5.
You should favor Select over ConvertAll as it works for any kind of list, but they do the same basically.
I believe you have each switch statement for each MyEnum value?
That is a lot of repeated code, that's true.
Why don't you just convert int to text value directly?
You can do it like this for more readability
foreach(Record r in List<Record>)
{
MyEnum myEnum = (MyEnum)r.RecordTypeID;
string stringValue = myEnum .ToString();
listofRecordModified.Add(new RecordModified{RecordTypeID=r.RecordTypeID, ...,**RecordTypeText=stringValue })** // Notice this
}

Categories