ASP.NET MVC - Html.DropDownList - значение не задано с помощью ViewData.Model
Только что начали играть с 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 (который отлично работает) и передачи списка избранных с моделью - что принесет пользу немного очистить код - мне просто интересно, почему этот метод не работает...
Большое спасибо за любые предложения
Ответы
Ответ 1
После того, как кучка подшивки и взламывания сводится к следующей строке кода
if (ViewData.ModelState.TryGetValue(key, out modelState))
что означает, что MVC пытается разрешить значение, только просматривая объект ViewData Dictionary < > и не пересекая его в объект ViewData.Model.
Я не уверен, что это ошибка, ограничение или дизайнерское решение. Однако вы можете исправить это следующим образом:
<%= Html.TextBox("MyTextBox", ViewData.Model.MyTextBox) %>
Ответ 2
На самом деле вам просто нужно передать null
для Html.DropDownList()
.
У меня была такая же точная проблема, и я использовал рефлектор, чтобы посмотреть исходный код MVC.
В методе System.Web.Mvc.Extensions.SelectExtensions
class SelectInternal()
он проверяет, является ли параметр selectList null или нет.
Если он передается как 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 (бета-версия).
ОБНОВЛЕНИЕ ПРИМЕЧАНИЕ: 31 января 2012
После экстренного использования ASP.NET MVC в течение последних 3 лет я предпочитаю использовать additionalViewData
из Html.EditorFor()
метод.
Перейдите в [Элементы списка] как объект anonymous
с тем же именем свойства как свойство Model в метод Html.EditorFor()
.
<%= Html.EditorFor(
m => m.MyPropertyName,
new { MyPropertyName = Model.ListItemsForMyPropertyName }
) %>
Если вы хотите получить более подробную информацию, см. мой ответ в другом разделе здесь.
Ответ 3
попробуйте установить выбранное значение в действии контроллера при создании коллекции SelectList.
ViewData [ "AddressTypeId" ] = новый SelectList (CustomerService.AddressType_List(), "AddressTypeId", "Name", myItem.AddressTypeId);
Ответ 4
Я, очевидно, опаздываю здесь. Но я хотел добавить этот комментарий, если кто-то другой столкнулся с этой проблемой.
В 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);
}
Четвертый параметр принимает значение и выберет нужное значение в раскрывающемся списке. В моем примере у меня есть таблица, называемая командой, и у меня есть отношение, установленное к таблице под названием fanYear и лиге.
Вы можете видеть, что я сначала получаю команду, которую я редактирую, а затем создаю выпадающий список года фантазии и еще один для лиг. Чтобы определить год и лигу для команды, мне пришлось использовать ссылку Entity Reference.
Просто хотел поместить это там. Я не мог найти примеров этого.
Ответ 5
Хорошо, я могу что-то пропустить из этого потока, однако в С# работает следующее:
Html.DropDownList("ProfessionGuid", (SelectList)ViewData["Professions"])
Где 'ProfessionGuid
' - это значение, которое должно быть выбрано в списке.
В VB.Net я считаю, что это будет:
Html.DropDownList("ProfessionGuid", ViewData["Professions"] AS SelectList)
Ответ 6
Если у вас возникли проблемы с недопустимыми или нулевыми ViewData, обратите внимание на действие вашего контроллера.
Предположим, у вас есть ViewData, называемый MyList для Html.DropDownlist, называемый MyList.
Если вы вызываете ModelState.AddModelError("MyList","Please select the profession")
, вы замените содержимое списка ViewData этим предупреждающим текстом.
Это также объясняет, почему люди вокруг Интернета имеют нулевые проблемы с ViewData в DropDownList.
В нижней строке, обратите внимание на свои идентификаторы на модели ошибок, они не должны мешать вашим элементам управления html.
Ответ 7
Мое беспокойство в том, что вы можете использовать только список для одного поля. У меня есть объекты с несколькими полями пользователя, поэтому я использую следующее:
< %= Html.DropDownList("fieldAAA",
new SelectList( (IEnumerable) ViewData["Users"], "Value", "Text", fieldAAA))
%>