2015-11-17 5 views
-1

У меня есть ViewModel файл, который я создал:Невозможно использовать Еогеасп для перебора 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; } 
} 

Я пытаюсь запустить foreeach заявление итерацию через пункты, но я получаю

MyViewModel не содержит публичное определение GetEnumerator

Вот мое заявление, которое пытается использовать:

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

Я не уверен, почему это происходит, может ли кто-нибудь помочь?

EDIT: viewmodel принимает данные, переданные ему через вызов AJAX. Я просто заполняю поля по мере необходимости. Я сделал это, потому что я не хотел иметь метод, который принимает более 20 параметров inline (строка a, строка b, строка 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. Я создаю список элементов, которые нужно передать в конец. – 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, который не реализует Innumerable.

Если ваша построенная модель представляет собой коллекцию MyViewModel, вы можете пропустить ее. Например, если вы отправляете список клиентов/продуктов, вы будете делать что-то вроде этого

public ActionResult MyMethod (IEnumerable<MyViewModel> model) 
{ 
    foreach(var product in model) 
    { 
    //You can access each property here 
    //product.AString 
    } 
} 

Если вы просто хотите прочитать различные значения свойств, публикуемые моделей, Вам не нужен Еогеасп. Просто прочитайте каждое свойство

public ActionResult MyMethod(MyViewModel model) 
{ 
    var aStringVal = model.AString; 
    var bStringVal = model.BString; 
    //Do something with the values. 
} 

Если вы все еще хотите, чтобы получить все свойства своего единственного экземпляра MyViewModel, Вы должны использовать отражение, чтобы получить, что, как Konamiman написал в своем ответе.

0

C# полностью отличается от JavaScript:

  • В C#, Еогеасп цикл по каждому объекту в последовательности объектов (IEnumerable)

  • В JavaScript Еогеасп петли через значение каждого свойства в одном объекте.

В 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

на основе новой информации добавляется к вопросу

Если параметры могут изменяться при каждом вызове, а затем с помощью viewmodel с фиксированными свойствами не подходит вашему делу.

Помните, что C# строго типизирован, вы можете просто отправить любые значения, которые вы хотите, только те, которые уже определены.

Если параметры могут изменяться при каждом вызове, то вы не можете использовать фиксированный ViewModel, поэтому изменить метод словаря имя + значение:

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

, но это, скорее всего, случай, когда клиент определяет параметры.

Смежные вопросы