ASPNET MVC: почему это обязательный метод действий? - PullRequest
2 голосов
/ 01 апреля 2012

Потратив два удивительных часа на форматирование некоторых скрытых полей, чтобы правильно связать их с параметрами метода действия - во второй раз, когда я испытывал это на прошлой неделе, - мне теперь очень любопытно, почему архитекторы MVC выбрал конкретное соглашение о связывании, которое они сделали для списков (и словарей) объектов.

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

<input type="hidden" name="prefix[idx].PropertyName" value="PropertyName[idx] Value" />

Префикс - это ViewDataDictionary.TemplateInfo.HtmlPrefix, если он был определен.

Я считаю, что начинать ссылку на что-либо с информации об индексировании (то есть, части [idx]) очень нелогично. Меня также беспокоит, что нигде в этой конструкции я не делаю ссылку на имя параметра метода действия, к которому привязываюсь. Это, кажется, находится в прямом противоречии с тем, что происходит, скажем, с примитивным свойством модели:

<input type="hidden" name="Text" value="something" />

public ActionResult SomeActionMethod( string Text )...

Я понимаю, что могу свернуть свою собственную модель в MVC. Это не похоже на прибыльное использование моего времени, хотя проводить часы, пытаясь найти правильный формат для скрытых полей, тоже не выгодно :), так что, возможно, я попробую это. Я также знаю, что могу позволить MVC выполнять всю тяжелую работу, создав шаблон типа с помощью @ Html.HiddenFor (), а затем вывести экземпляры CustomClass через простое частичное представление с CustomClass в качестве модели и однострочный @Html. DisplayForModel (). Но это похоже на долгий путь вокруг сарая тоже. Кроме того, существуют ограничения на использование помощников @ Html.Hidden (например, они «старательно» совершают набег на кэш после обратной передачи для заполнения значений, поэтому написание @ Html.Hidden («fieldname», value) не гарантирует, что значение закончится) до вывода - вы можете вместо этого получить старое значение в кэше, что сегодня было еще одним часовым раздражением).

Но мне просто любопытно, почему этот формат был выбран. Почему не что-то более C / C ++ / C # / VB вроде:

<input name="prefix.ParameterName.PropertyName[idx]" />

Edit:

Хороший вопрос о том, куда я поместил параметр индекса в моем примере. Вы правы, свойство не проиндексировано, содержащий класс:

Однако это не меняет основную ситуацию. Почему синтаксис не похож на:

<input name="prefix.ParameterName[0].PropertyName" />

Стандартный синтаксис игнорирует имя параметра с коллекциями пользовательских типов и «угадывает» пользовательский тип по именам свойств. Это странно ... поэтому за этим должна стоять история или выбор:).

1 Ответ

0 голосов
/ 01 апреля 2012

На самом деле, это имеет смысл.Индекс находится в коллекции, а не в собственности.У вас нет коллекции PropertyName, у вас есть коллекция CollectionName [], у которой есть PropertyName.

Другими словами:

public class Foo { public string Bar { get; set; } }

var foos = List<Foo>();

for (var i = 0; i < foos.Length; i++)
{
     var prop = foos[i].Bar;  // This is the important bit
}

Это именно то, что происходит всвязыватель модели.

Когда связыватель модели десериализует значения записей, он должен знать, в какую коллекцию вставлять значения, и знать, для какого индекса предназначен каждый элемент.Таким образом, он должен знать, чтобы создать коллекцию Foos, х элементов, и с какими индексами связан каждый столбец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...