Loop model data and list it out - c#

I am trying to loop through data that is passed to my view in a model object. I want to list out the property name and the property value of each of the model properties, even if they are null. I have been at this for a few hours and have tried googling it but cannot get any good examples that work.
I got this to list out all of the properties of the current object, however cannot get the values:
#model List<object>
#foreach (var obj in Model)
{
var properties = obj.GetType().GetProperties();
foreach (var property in properties)
{
string name = null;
var value = ""
try
{
name = property.Name;
value = property.GetType().GetProperty(property.Name).GetValue(property, null).ToString();
}
catch (Exception e)
{
<p>#e</p>
}
finally
{
<p>#name - #value</p>
}
}
And the controller code:
RootobjectPlayerData obj = JsonConvert.DeserializeObject<RootobjectPlayerData>(jsonstring);
List<object> list = new List<object>();
list.Add(obj.data.accountinfo);
list.Add(obj.data.accountinfo.statistics);
list.Add(obj.data.accountinfo.statistics.clan);
list.Add(obj.data.accountinfo.statistics.company);
list.Add(obj.data.accountinfo.statistics.all);
list.Add(obj.data.accountinfo.statistics.historical);
list.Add(obj.data.accountinfo.statistics.team);
return View(list);
I am able to do a break point and view all of the data within each of the objects, however I cannot get it to print out on screen.

First of all you are getting the property value incorrectly. You should get the value from the object you have, but not from the type of the property:
value = obj.GetType().GetProperty(property.Name).GetValue(obj, null)
Secondly, try to loop only through data that's not null:
#foreach (var obj in Model.Where(w => w != null))

Try getting the values from i, not x.
try
{
name = x.Name;
// Wrong
// value = x.GetType().GetProperty(x.Name).GetValue(x, null).ToString();
// Correct
value = x.GetValue(i, null).ToString();
}
catch (Exception e)
{
<p>#e</p>
}

Related

MVC List Error List<Model>

I'm using foreach to transfer data from list to another but when adding value updated automatically to last value added. For example:
list1 = [1,2,3]
list2 = new List<Model>()
foreach(var item in list1) {
list2.Add(item)
}
the result in list2 is [ 3, 3, 3]
Actually example is below :
var _sizes = new List<ProductsSize>();
var _size = new ProductsSize();
if (model.Dynamic_ProductsSize.Count > 0)
{
foreach (var item in model.Dynamic_ProductsSize)
{
_size.SizeId = item;
_sizes.Add(_size);
}
}
model.ProductsSize = _sizes.ToList();
I need to know why it only takes the last item and what is the solution for this case
You only have one ProductsSize object:
var _size = new ProductsSize();
And you keep modifying that same object. All references to that object, including any list elements it's been added to, get updated when you modify that one object.
Instead, create your new object in the loop:
foreach (var item in model.Dynamic_ProductsSize)
{
var _size = new ProductsSize();
_size.SizeId = item;
_sizes.Add(_size);
}
That way each element in the list is a new object instead of the same object added multiple times.
Side note, you have a few things in the code which aren't necessary. Checking the length before the loop, for example, as well as converting a list to a list at the end.
In fact, I imagine all of the code shown can be shortened to simply this:
model.ProductsSize = model.Dynamic_ProductsSize.Select(p => new ProductsSize { SizeId = p }).ToList();
In which case you're also just converting one model property to another model property. Why not put this logic in the model itself and skip the whole thing?
public IEnumerable<ProductsSize> ProductsSize
{
get { return this.Dynamic_ProductsSize.Select(p => new ProductsSize { SizeId = p });
}
Unless there's a particular reason you want the same data twice in two different properties that isn't clear from this code, having one set of data and just different views/calculations/etc. of that data is often preferred.
Create a new object before adding it to the list. You can use the object initializer syntax to keep it concise:
if (model.Dynamic_ProductsSize.Count > 0)
{
foreach (var item in model.Dynamic_ProductsSize)
{
_sizes.Add(new ProductsSize(){SizeId = item});
}
}

C# for each property get both value and name

I'm sending a JSON object through PUT from angularJS to c#, which has a property name and a value.
I'm trying to loop for each property and read both name and the value, but it fails. I have succeed to read only the name or only the value though with the below code:
Newtonsoft.Json.Linq.JObject cbpcs = pricestopsale.cbPricegroups;
foreach (string pricegroupInfo in cbpcs.Properties().Select(p => p.Value).ToList())
{
// I want to be able to do something like this inside here
if(pricegroupInfo.Value == "Something") {
// do stuff
}
}
In my above example pricegroupInfo has the value, if i change .Select(p => p.Name).ToList()) i get the name of the property.
What can I do if i want to get both name and value inside my loop ?
Update 1: The property Name is unknown to me, it's generated dynamically so I dont know in advance the property name.
Update 2: I want to be able to compare the value and the name as a string inside the loop.
Try using an anonymous object in the select.
Newtonsoft.Json.Linq.JObject cbpcs = pricestopsale.cbPricegroups;
foreach (var pricegroupInfo in cbpcs.Properties().Select(p => new { p.Value, p.Name }).ToList())
{
// read the properties like this
var value = pricegroupInfo.Value;
var name = pricegroupInfo.Name;
if(pricegroupInfo.Value.ToObject<string>() == "foo")
{
Console.WriteLine("this is true");
}
}
Reference: JObject.Properties Method
Newtonsoft.Json.Linq.JObject cbpcs = pricestopsale.cbPricegroups;
foreach (var pricegroupInfo in cbpcs.Properties())
{
if(pricegroupInfo.Name == "propName" // your property name
&& pricegroupInfo.Value.ToString() == "something") { // your value
// do stuff
}
}
As you can see, it returns IEnumerable<JProperty> which use can iterate and make use of to get property Name and Value
Try this
foreach(var prop in cbpcs.GetType().GetProperties()) {
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(foo, null));}

C# (Xamarin) List, where and its changes

I don't know where an error is. I have a list of element called TileModel with default values and ObservableCollection<TileModel> list
When I show a form in my view model I have to find in this list an element with the same name. If an element in the list exists, I copy this element in the ObservableCollection.
public ObservableCollection<TileModel> testList { get; set; }
List<TileModel> dsType = new List<TileModel>() {
new TileModel() { Text = "Alarms", IconImage = "Alarm.png",
NavigateType = typeof(Alarms) },
}
In a function I have this code:
foreach (string s in items)
{
TileModel dm = dsType.Where(d => d.Text.RemoveTextBetween("(", ")").Trim() == s)
.FirstOrDefault();
if (dm != null)
{
dm.Text = UpdateTextItem(dm.Text, iType);
testList.Add(dm);
}
}
UpdateTextItem changes the name Text to add the number of records. If I follow the code with F11, when I enter in the function dsType is the original. After dm.Text = UpdateTextItem(dm.Text, iType); dsType is changed this dm.text.
In my point of view dm is a new variable with in it a value of the list but isn't an instance of an element of the list. Then why do the code change my original dsType?
Thank you in advance.
That is because your class TileModel is a reference type. That means dm is just a reference to the original object.
By:
testList.Add(dm);
you add the reference to your testList - the object is the same if it gets changed, it also changes your object in your original list.
To Avoid this. You can add the Item like this: (If your ctor allows this)
var dm_new = new TileModel(dm);
dm_new .Text = UpdateTextItem(dm_new .Text, iType);
testList.Add(dm_new );

Updating sort column in ASP.NET with Request.QueryString Array

I'm passing a list of guids in a GET request from a JQuery Ajax call.
on my ASP.NET controller side I want to iterate through the list and update the Display_Sort column to match my newly sorted list.
My ID is a Guid and I'm getting a type error in the following code, because it's a string that I'm passing to the Db. However, I can't seem to convert the item(string) into a Guid.
I've tried Guid(item) and it would allow the constructor. Not sure what I'm missing.
Here is the code:
//REORDER HOME ASSETS
public ActionResult ReOrderHome()
{
using (var db = new IFEntities())
{
var myString = Request.QueryString;
var i = 1;
foreach (var item in myString)
{
var myObj = db.HomeContents.Find(item);
myObj.display_order = i;
db.SaveChanges();
i++;
}
}
You can convert item to GUID and then compare like this.
var myObj = db.HomeContents.Find(new Guid(item));
Or, you can use select instead of find. Syntax for select --
foreach (var item in myString)
{
var myObj = db.HomeContents.Select(p => p.<GUID_COLUMN_NAME> == item);
myObj.display_order = i;
db.SaveChanges();
i++;
}
Replace GUID_COLUMN_NAME with actual column name.

How to figure out which key of ModelState has error

How do I figure out which of the keys in ModelState that contains an error when ModelState.IsValid is false? Usually I would just hover the mouse thru the ModelState.Values list checking item by item for error count > 0. But now I'm working on a view that has some lists of complex objects, totalling 252 ModelState items(each item of each object of each list has an entry on ModelState.Keys).
So, is there an easier way to point out the error source?
You can check the ViewData.ModelState.Values collection and see what are the Errors.
[Httpost]
public ActionResult Create(User model)
{
if(ModelState.IsValid)
{
//Save and redirect
}
else
{
foreach (var modelStateVal in ViewData.ModelState.Values)
{
foreach (var error in modelStateVal.Errors)
{
var errorMessage = error.ErrorMessage;
var exception = error.Exception;
// You may log the errors if you want
}
}
}
return View(model);
}
}
If you really want the Keys(the property name), You can iterate through the ModelState.Keys
foreach (var modelStateKey in ViewData.ModelState.Keys)
{
var modelStateVal = ViewData.ModelState[modelStateKey];
foreach (var error in modelStateVal.Errors)
{
var key = modelStateKey;
var errorMessage = error.ErrorMessage;
var exception = error.Exception;
// You may log the errors if you want
}
}
ModelState.Values.SelectMany(v => v.Errors);
is considered cleaner.
where modelState is a ModelStateDictionary object
foreach (var keyModelStatePair in modelState)
{
var key = keyModelStatePair.Key;
var errors = keyModelStatePair.Value.Errors;
if (errors != null && errors.Count > 0)
{
var errorMessages = errors.Select(error =>
{
return error.ErrorMessage;
}).ToArray();
// do something with your keys and errorMessages here
}
}
I had the same problem for a long time and finally I found it. In my case, it was the Id field :)
Just place a breakpoint and check your ModelState in runtime and go to this section :
ModelState -> Root -> Children
and you will see all valid and invalid Keys

Categories

Resources