2015-11-17 26 views
-1

遍历我有我创建一个视图模型文件:不能使用的foreach通过视图模型

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; } 
} 

我试图运行foreeach语句来遍历通的项目,但我得到

MyViewModel不包含GetEnumerator

这里一个公共定义是我的发言,试图使用它:

public ActionResult MyMethod(MyViewModel model) 
{ 
    foreach(var item in model) 
    { 
     //add code here 
    } 
} 

我不知道为什么会发生这种情况,任何人都可以帮忙吗?

编辑:viewmodel正在接受通过AJAX获取调用传递给它的数据。我只是填写必要的字段。我这样做是因为我不想有一个方法接受超过20个参数inline(string a,string b,string c,...)。制作具有所有可能字段的视图模型更有意义,并且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]是通过迭代“如果使用正确的术语”直通我创建以填充这些时隙模型填充。

+1

由于MyViewModel不是IEnumerable。如果你想循环遍历模型中的所有成员,你需要明确或通过反射来完成。我不确定你想在循环中完成什么,如果你正在进行验证,你需要根据字段包含的内容来做到这一点,并且在那时你最好为每个成员编写“if”语句。你想在循环内完成什么? –

+0

你能给我一个明确的例子吗?我是学习C#和MVC的一个月。我正在构建要传递给endPoint的项目列表。 – seroth

+0

代码中没有收集哪个循环。你想要在那个循环中做些什么? – David

回答

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你的字符串和日期。

+0

请注意,使用反射代价高昂。不要将它用于大型迭代。大多数时候,手动操作属性并不复杂...... –

+0

当然!我正在改进我的答案,谢谢。 – Konamiman

+0

您通常不需要在应用程序代码中进行反射。如果实际问题不明确,请不要建议OP(特别是因为他们说他们对C#非常陌生)。 – CodeCaster

0

foreach适用于实现IEnumerable和数组的任何对象集合。在你的代码中,MyViewModel是一个POCO类,它没有实现无数。

如果您发布的模型是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在他的回答中写道。

0

C#是完全不同的,以JavaScript的:

  • 在C#,的foreach在对象(IEnumerable的)

  • 在JavaScript的序列通过每一个对象循环,foreach循环通过每一个属性的值在一个单一的对象。

在C#中,您不能轻松遍历类中的每个属性,也不应该尝试这样做。
相反,如果你想在几个相同类型的属性,使用List<T>

public class MyViewModel 
{ 
    public List<string> MyStrings { get; set; } 
    public List<DateTime> MyDates { get; set; } 
} 

foreach (string s in model.MyStrings) 
{ 
} 

foreach (DateTime d in model.MyDates) 
{ 
} 
0

基于添加到这个问题

如果这些参数可以在每次调用改变新的信息,然后使用具有固定属性的视图模型不适合您的情况。

请记住,C#是强类型的,你不能只给你想要的,已经定义只有那些任何值。

如果参数可以为每个调用而变化,那么你不能用一个固定的视图模型,所以更改方法名称+值的字典:

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 }}); 
    } 

这也可能是合适的,如果你有很多值。

你可以使用继承或有字典属性视图模型,但这是必不可少的一部分


如果参数总是相同的,则显式使用值:

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 }}); 

,但最有可能的情况是客户端正在定义参数。