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 (который отлично работает) и передачи списка выбора вместе с моделью - что будет иметь преимущество немного почистить код - мне просто интересно, почему этот метод не работает ....

Большое спасибо за любые предложения

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
17
0
80 313
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

После кучи подшивки и перетягивания все сводится к следующей строке кода

if (ViewData.ModelState.TryGetValue(key, out modelState))

что означает, что MVC пытается разрешить значение, только глядя на объект ViewData Dictionary <>, а не переходя вниз к объекту ViewData.Model.

Я не уверен, является ли это ошибкой, ограничением или дизайнерским решением. Однако исправить это можно следующим образом:

<%= Html.TextBox("MyTextBox", ViewData.Model.MyTextBox) %>

Спасибо за предложение, Тодд. Как я уже упоминал в сообщении, при использовании модели вы можете обойти это с помощью: var model {MyList = new SelectList (items, "Value", "Text", selected_value)} и просто: <% = Html.DropDownList ("MyList")%>

chrisb 24.12.2008 14:25

В основном это просто поведение, которое меня озадачило - по крайней мере, вы дали мне начало - думаю, мне нужно выяснить весь поток ModelState - если он исходит оттуда, то должен быть шаг, который загружает материал из ViewData и т. д.

chrisb 24.12.2008 14:27

Эй ... это даже не ответ ... как ты мог это подобрать ?? Вы не можете установить выбранное значение в методе расширения Html, вы должны сделать это в контроллере при построении ViewData

Jalal El-Shaer 17.01.2010 15:28

попробуйте установить выбранное значение в действии контроллера при создании коллекции SelectList.

ViewData ["AddressTypeId"] = новый список выбора (CustomerService.AddressType_List (), «AddressTypeId», «Имя», myItem.AddressTypeId);

Это решило для меня проблему при попытке выбрать значение для элементов раскрывающегося списка. Спасибо!

p.campbell 18.07.2009 02:47

Хорошо, мне может чего-то не хватать в этом потоке, однако в 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 (бета-версия).

ПРИМЕЧАНИЕ ОБ ОБНОВЛЕНИИ: 31 января 2012 г.

После интенсивного использования ASP.NET MVC в течение последних 3 лет я предпочитаю использовать additionalViewData из Html.EditorFor() метод.

Передайте свой [Элементы списка] как объект anonymous с то же название собственности как свойство модели в метод Html.EditorFor().

<%= Html.EditorFor(
    m => m.MyPropertyName,
    new { MyPropertyName = Model.ListItemsForMyPropertyName }
) %>

Если вам нужна дополнительная информация, обратитесь к мой ответ в другой теме здесь.

Спасибо ... это лучшее решение этой проблемы со строго типизированными представлениями, которое я когда-либо видел ... Он работает с моделью, имя свойства которой соответствует имени раскрывающегося списка, и поэтому оно должно ... спасибо

Jalal El-Shaer 20.02.2010 02:42

Я согласен. Мантра «переименовать свое поле» убивает привязку модели к объектам впереди. Для меня это тоже было лучшим решением.

claco 23.02.2010 00:51

я думаю, что это ломается, если свойство является частью массива

Menace 11.10.2012 21:01

Если у вас есть проблемы с недопустимыми или нулевыми 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.

Просто хотел рассказать об этом. Я не мог найти никаких примеров этого.

Другие вопросы по теме