我有一个我创建的ViewModel文件:
public class MyViewModel
{
public string AString { get; set; }
public string BString { get; set; }
public string CString { get; set; }
public string DString { get; set; }
public DateTimeOffset ADate { get; set; }
public DateTimeOffset BDate { get; set; }
}
我正在尝试运行for-each语句来迭代项目,但我正在
MyViewModel不包含
的公开定义GetEnumerator
以下是我试图使用它的声明:
public ActionResult MyMethod(MyViewModel model)
{
foreach(var item in model)
{
//add code here
}
}
我不确定为什么会这样,有人可以帮忙吗?
编辑:ViewModel接受通过AJAX-get调用传递给它的数据。我只是填写必要的字段。我之所以这样做,是因为我不希望有一个接受超过20个内联参数的方法(字符串a,字符串b,字符串c,...)。使一个具有所有可能字段的ViewModel更有意义,并且AJAX调用将相应地填充这些字段。之后我想要做的是将这些值传递给服务,但是必须稍微更改它们才能使用旧服务。
服务期望:
serviceName(ID, GUID, NAME, parameters)
ID - string
GUID - GUID
NAME - string
parameters - new parameter { name = "[model.Name]", value = new List<string>(){ "[model.value]" }}
[model.Name]和[model.Value]通过迭代“如果使用正确的术语”填充我创建的模型来填充这些插槽。
答案 0 :(得分:2)
您可以使用反射遍历模型中的所有公共属性:
var properties = typeof(MyViewModel).GetProperties();
foreach(var property in properties)
{
var propertyName = property.Name;
var propertyValue = property.GetValue(model);
//Now process the property
}
但请注意,反射会导致性能下降,如果有更好的替代方案,则不应使用反射。在您的情况下,看起来您可以很好地声明几个数组或字典来存储您的数据。例如:
public class MyViewModel
{
public MyViewModel
{
TheStrings = new string[4];
TheDates = new DateTimeOffset[2];
}
public string TheStrings { get; private set; }
public DateTimeOffset TheDates { get; private set; }
}
现在您可以访问model.TheStrings[0]
而不是model.AString
,依此类推;使用带有键A,B,C,D的字典将进一步提高可读性,但想法是相同的。现在,您可以轻松地foreach
字符串和日期。
答案 1 :(得分:0)
foreach适用于任何实现IEnumerable
和数组的对象集合。在您的代码中,MyViewModel是一个POCO类,它没有实现Innumerable。
如果您发布的模型是MyViewModel的集合,您可以循环使用它们。例如,如果您要发布客户/产品列表,您将执行类似这样的操作
public ActionResult MyMethod (IEnumerable<MyViewModel> model)
{
foreach(var product in model)
{
//You can access each property here
//product.AString
}
}
如果您只想阅读已发布模型的不同属性值,则不需要foreach。简单地说,阅读每个属性
public ActionResult MyMethod(MyViewModel model)
{
var aStringVal = model.AString;
var bStringVal = model.BString;
//Do something with the values.
}
如果你仍想获得MyViewModel的单个实例的所有属性,你应该使用反射来解决这个问题,就像Konamiman在他的回答中写的那样。
答案 2 :(得分:0)
C#与JavaScript完全不同:
在C#中,foreach循环遍历一系列对象中的每个对象(IEnumerable)
在JavaScript中,foreach循环遍历单个对象中每个属性的值。
在C#中,你不能轻易地遍历一个类中的每个属性,也不应该尝试这样做。
相反,如果您想要多个相同类型的属性,请使用wikipedia
foldr
答案 3 :(得分:0)
基于添加到问题的新信息
如果参数可以在每次调用时更改,那么使用具有固定属性的viewmodel将不适合您的情况。
请记住,C#是强类型的,您不能只发送您想要的任何值,只能发送已定义的值。
如果每个调用的参数都可以更改,那么您不能使用固定的viewmodel,因此将方法更改为name + value的字典:
public ActionResult MyMethod(IDictionary<string, string> model)
{
var parameters = new List<Parameter>();
foreach (var kvp in model)
{
parameters.Add(new parameter { name = kvp.Key, value = new List<string> { key.Value }});
}
如果你有很多价值,这也可能是合适的。
您可以使用继承或具有字典属性的ViewModel,但这是必不可少的部分
如果参数始终相同,则明确使用值:
public ActionResult MyMethod(IDictionary<string, string> model)
{
var parameters = new List<Parameter>();
parameters.Add(new parameter { name = "AString", value = new List<string> { model.AString }});
parameters.Add(new parameter { name = "BString", value = new List<string> { model.BString }});
但最有可能的情况是客户端正在定义参数。