Ошибка означает, что значение CategoryList
равно нулю (и в результате метод DropDownListFor()
ожидает, что первый параметр имеет тип IEnumerable
).
Вы не генерируете вход для каждого свойства каждого SelectListItem
в CategoryList
(и не должен), поэтому никакие значения для SelectList
не отправляются в метод контроллера, и поэтому значение model.CategoryList
в методе POST равно null
, Если вы вернете представление, вы должны сначала переназначить значение CategoryList
, как и в методе GET.
public ActionResult Create(ProjectVM model)
{
if (!ModelState.IsValid)
{
model.CategoryList = new SelectList(db.Categories, "ID", "Name"); // add this
return View(model);
}
// Save and redirect
}
Чтобы объяснить внутреннюю работу (исходный код может быть см. здесь )
Каждая перегрузка DropDownList()
и DropDownListFor()
в конечном итоге вызывает следующий метод
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
string optionLabel, string name, IEnumerable selectList, bool allowMultiple,
IDictionary htmlAttributes)
, который проверяет, есть ли selectList
(второй параметр из @Html.DropDownListFor()
) является null
// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
selectList = htmlHelper.GetSelectData(name);
usedViewData = true;
}
, который, в свою очередь, вызывает
private static IEnumerable GetSelectData(this HtmlHelper htmlHelper, string name)
, который оценивает первый параметр @Html.DropDownListFor()
(в данном случае CategoryID
)
....
o = htmlHelper.ViewData.Eval(name);
....
IEnumerable selectList = o as IEnumerable;
if (selectList == null)
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
MvcResources.HtmlHelper_WrongSelectDataType,
name, o.GetType().FullName, "IEnumerable"));
}
Поскольку свойство CategoryID
является typeof int
, оно не может быть передано в IEnumerable
, и генерируется исключение (которое определено в файле MvcResources.resx
как)
The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.
Почему бы не использовать выражение лямбда?
public string SortByDateModified(List<CartItem> items)
{
items.Sort((a, b) => a.DateModified.CompareTo(b.DateModified));
}
bool
бесполезен для такого делегата, обычно используется int
, потому что вам нужно 3 значения для представления результатов сравнения, меньше, равно и больше, чем. Коллекции .NET обычно (если не всегда) предполагают, что -1 означает меньше чем, 0 означает равный и 1 означает больше чем.
Затем вы должны в своем делегате проверить, является ли значение x меньше, равно или больше значения y. Интересно отметить, что если вы перевернете результаты, например, сравните y с x, то вы будете сортировать в противоположном направлении.
Чтобы упростить сортировку дат, проверьте ответ Джона Си или Сэма .
Если вы не хотите использовать лямбдас или больше, чем .NET 2.0, используйте это:
public string SortByDateModified(List<CartItem> items)
{
items.Sort(delegate(CartItem itemA, CartItem itemB)
{
return itemA.DateModified.CompareTo(itemB.DateModified);
});
}
в моем опыте, в средах, таких как единство, лямбдас и даже делегаты могут вызвать сбои или проблемы, особенно на платформах, таких как iOS Отказ В этом случае вы хотели бы сделать вашу сортировку отдельную функцию, например:
int SortCartItemFunction(CartItem itemA, CartItem itemB)
{
return itemA.DateModified.CompareTo(itemB.DateModified);
}
, то вы можете передать его на ваш сорт, как это:
items.Sort(SortCartItemFunction);
Метод Сортировка
принимает задачу называемого сравнение
. Вы пытаетесь пройти в ФУНК
, который сам по себе является делегатом. Нет преобразования между делегатом FUNC
и делегатом сравнение
.
Вы можете, однако, использовать лямбда лямбда .
items.Sort((a, b) => a.DateModified.CompareTo(b.DateModified));
Действительно, вы используете это очень лямбда экспрессию и пропустите его в функцию
конструктор *. Однако нет необходимости. Выражение лямбда может быть преобразовано в любой делегат подписи для подписи - то есть (a, b) => aTedemodified.compareeto (b.datemodificed)
может быть назначен на что-то набранное func , int, int>
или что-то набранное сравнение
. В этом случае мы передаем его на что-то, что ожидает сравнения
.
*
с одной незначительной корректировкой. Сортировать ожидает целое число в качестве типа возврата. Отрицательные значения указывают на меньшее, чем 0 указывает на равные, а положительные значения указывают больше, чем.