2015-11-17 54 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 }}); 

,但最有可能的情況是客戶端正在定義參數。