Только что начали играть с ASP.NET MVC и наткнулись на следующую ситуацию. Это очень похоже на ошибку, но если это не так, мы будем признательны за объяснение :)
Представление содержит довольно простые вещи
<%=Html.DropDownList("MyList", ViewData["MyListItems"] as SelectList)%>
<%=Html.TextBox("MyTextBox")%>
Когда модель не используется, значение и выбранный элемент устанавливаются должным образом:
//works fine
public ActionResult MyAction(){
ViewData["MyListItems"] = new SelectList(items, "Value", "Text"); //items is an ienumerable of {Value = "XXX", Text = "YYY"}
ViewData["MyList"] = "XXX"; //set the selected item to be the one with value 'XXX'
ViewData["MyTextBox"] = "ABC"; //sets textbox value to 'ABC'
return View();
}
Но при попытке загрузки через модель в текстовом поле установлено ожидаемое значение, но в раскрывающемся списке не отображается выбранный набор элементов.
//doesnt work
public ActionResult MyAction(){
ViewData["MyListItems"] = new SelectList(items, "Value", "Text"); //items is an ienumerable of {Value = "XXX", Text = "YYY"}
var model = new {
MyList = "XXX", //set the selected item to be the one with value 'XXX'
MyTextBox = "ABC" //sets textbox value to 'ABC'
}
return View(model);
}
Любые идеи? Мои текущие мысли по этому поводу заключаются в том, что, возможно, при использовании модели мы ограничены установкой выбранного элемента в конструкторе SelectList вместо использования viewdata (который отлично работает) и передачи списка выбора вместе с моделью - что будет иметь преимущество немного почистить код - мне просто интересно, почему этот метод не работает ....
Большое спасибо за любые предложения





После кучи подшивки и перетягивания все сводится к следующей строке кода
if (ViewData.ModelState.TryGetValue(key, out modelState))
что означает, что MVC пытается разрешить значение, только глядя на объект ViewData Dictionary <>, а не переходя вниз к объекту ViewData.Model.
Я не уверен, является ли это ошибкой, ограничением или дизайнерским решением. Однако исправить это можно следующим образом:
<%= Html.TextBox("MyTextBox", ViewData.Model.MyTextBox) %>
В основном это просто поведение, которое меня озадачило - по крайней мере, вы дали мне начало - думаю, мне нужно выяснить весь поток ModelState - если он исходит оттуда, то должен быть шаг, который загружает материал из ViewData и т. д.
Эй ... это даже не ответ ... как ты мог это подобрать ?? Вы не можете установить выбранное значение в методе расширения Html, вы должны сделать это в контроллере при построении ViewData
попробуйте установить выбранное значение в действии контроллера при создании коллекции SelectList.
ViewData ["AddressTypeId"] = новый список выбора (CustomerService.AddressType_List (), «AddressTypeId», «Имя», myItem.AddressTypeId);
Это решило для меня проблему при попытке выбрать значение для элементов раскрывающегося списка. Спасибо!
Хорошо, мне может чего-то не хватать в этом потоке, однако в C# работает следующее:
Html.DropDownList("ProfessionGuid", (SelectList)ViewData["Professions"])
Где «ProfessionGuid» - это значение, которое нужно выбрать в списке.
В VB.Net я считаю, что это будет:
Html.DropDownList("ProfessionGuid", ViewData["Professions"] AS SelectList)
На самом деле вам просто нужно передать null для Html.DropDownList().
У меня была такая же проблема, и я использовал Reflector, чтобы посмотреть исходный код MVC.
В методе System.Web.Mvc.Extensions.SelectExtensions класса SelectInternal() он проверяет, является ли параметр selectListноль или нет.
Если он передается как null, он правильно ищет SelectList.
Вот «Код программной части».
ViewData["MyDropDown"] = new SelectList(selectListItems,
"Value",
"Text",
selectedValue.ToString()
);
Вот код просмотра HTML.
<%= Html.DropDownList("MyDropDown", null,
"** Please Select **",
new { @class = "my-select-css-class" }
) %>
Примечание. Я использую ASP.NET MVC 2.0 (бета-версия).
После интенсивного использования ASP.NET MVC в течение последних 3 лет я предпочитаю использовать additionalViewData из Html.EditorFor() метод.
Передайте свой [Элементы списка] как объект anonymous с то же название собственности как свойство модели в метод Html.EditorFor().
<%= Html.EditorFor(
m => m.MyPropertyName,
new { MyPropertyName = Model.ListItemsForMyPropertyName }
) %>
Если вам нужна дополнительная информация, обратитесь к мой ответ в другой теме здесь.
Спасибо ... это лучшее решение этой проблемы со строго типизированными представлениями, которое я когда-либо видел ... Он работает с моделью, имя свойства которой соответствует имени раскрывающегося списка, и поэтому оно должно ... спасибо
Я согласен. Мантра «переименовать свое поле» убивает привязку модели к объектам впереди. Для меня это тоже было лучшим решением.
я думаю, что это ломается, если свойство является частью массива
Если у вас есть проблемы с недопустимыми или нулевыми ViewData, обратите внимание на действие вашего контроллера.
Предположим, у вас есть ViewData с именем MyList для Html.DropDownlist с именем MyList.
Если вы позвоните в ModelState.AddModelError("MyList","Please select the profession"), вы замените содержимое списка ViewData этим предупреждением.
Вот почему у людей в Интернете возникают нулевые проблемы с ViewData в DropDownList.
Суть в том, что обратите внимание на свои идентификаторы в модели ошибок, они не должны мешать вашим элементам управления html.
Меня беспокоит то, что вы можете использовать список только для одного поля. У меня есть Entities с несколькими пользовательскими полями, поэтому я использую следующее:
< %= Html.DropDownList("fieldAAA",
new SelectList( (IEnumerable) ViewData["Users"], "Value", "Text", fieldAAA))
%>
Я явно здесь опоздал. Но я хотел добавить этот комментарий, если кто-то еще столкнется с этой проблемой.
В MVC 2. Чтобы выбрать элемент, вы можете сделать следующее ...
public ActionResult Edit(int id)
{
Team team = _db.TeamSet.First(m => m.TeamID == id);
var fanYear = from c in _db.FanYearSet select c;
ViewData["FantasyYear"] = new SelectList(fanYear, "YearID", "FantasyYear", team.FanYearReference.EntityKey.EntityKeyValues[0].Value);
var league = from c in _db.LeagueSet select c;
ViewData["League"] = new SelectList(league, "LeagueID", "League_Name", team.LeaguesReference.EntityKey.EntityKeyValues[0].Value);
return View(team);
}
Четвертый параметр принимает значение и выберет нужное значение в раскрывающемся списке. В моем примере у меня есть таблица под названием team, и у меня есть отношение, установленное к таблице под названием fanYear и league.
Как видите, я сначала получаю команду, которую редактирую, затем создаю раскрывающийся список года фэнтези и еще один для лиг. Чтобы определить год и лигу команды, мне пришлось использовать Entity Reference.
Просто хотел рассказать об этом. Я не мог найти никаких примеров этого.
Спасибо за предложение, Тодд. Как я уже упоминал в сообщении, при использовании модели вы можете обойти это с помощью: var model {MyList = new SelectList (items, "Value", "Text", selected_value)} и просто: <% = Html.DropDownList ("MyList")%>