ASP.NET MVC - Html.DropDownList - значение не задано с помощью ViewData.Model

17

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

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

    
задан chrisb 23.12.2008 в 22:09
источник

7 ответов

5

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

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

, что означает, что MVC пытается разрешить значение, только глядя на словарь ViewData & lt; gt; объект, а не перемещение вниз в объект ViewData.Model.

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

<%= Html.TextBox("MyTextBox", ViewData.Model.MyTextBox) %>
    
ответ дан Todd Smith 24.12.2008 в 00:13
источник
  • Спасибо за предложение. Тодд. Как я упоминал в сообщении, если вы используете модель, вы можете обойти ее с помощью: var model {MyList = new SelectList (элементы, «Значение», «Текст», selected_value)} и просто : <% = Html.DropDownList ("MyList")%> –  chrisb 24.12.2008 в 12:25
  • В основном это было поведение, которое меня озадачило - по крайней мере, вы дали мне начало - подумайте, что мне нужно выяснить весь поток ModelState - если его выход оттуда должен быть шагом, который загружает вещи из ViewData и т. Д. –  chrisb 24.12.2008 в 12:27
  • Эй, это даже не ответ ... как вы могли это поднять? Вы не можете установить выбранное значение в методе расширения Html, вы должны сделать это в контроллере при создании ViewData –  Jalal El-Shaer 17.01.2010 в 13:28
23

На самом деле вам нужно передать null для Html.DropDownList() .
У меня была такая же точная проблема, и я использовал рефлектор, чтобы посмотреть исходный код MVC.

В методе System.Web.Mvc.Extensions.SelectExtensions класса 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 с тем же именем свойства как свойство модели в метод Html.EditorFor() .

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

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

    
ответ дан stun 24.11.2009 в 02:51
источник
  • Спасибо ... это лучшее решение для этой проблемы с сильно типизированными видами, которые я когда-либо видел ... Он работает с Model, у которого есть имя свойства, которое соответствует выпадающему имени, и поэтому оно должно ... спасибо –  Jalal El-Shaer 20.02.2010 в 00:42
  • Я согласен. Мантра «переименовать свое поле» убивает модель, привязывающую объекты к фронту. Это было лучшим решением для меня. –  claco 22.02.2010 в 22:51
  • Я думаю, что это ломается, если свойство является частью массива –  Menace 11.10.2012 в 19:01
2

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

ViewData ["AddressTypeId"] = новый SelectList (CustomerService.AddressType_List (), "AddressTypeId", "Name", myItem.AddressTypeId );

    
ответ дан IamNotaRobot 25.03.2009 в 15:32
источник
  • Это решило проблему для меня при попытке получить выбранное значение для элементов выпадающего списка. Спасибо! –  p.campbell 18.07.2009 в 00:47
  • Это также решило мою проблему. –  Red Swan 27.09.2010 в 11:51
2

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

В 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.

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

ответ дан Michael 11.12.2010 в 17:49
источник
-1

Если у вас возникли проблемы с неверными или нулевыми ViewData, обратите внимание на действия вашего контроллера.

Предположим, у вас есть ViewData, называемый MyList для Html.DropDownlist, называемый MyList.

Если вы вызовете ModelState.AddModelError("MyList","Please select the profession") , вы замените содержимое списка ViewData этим предупреждающим текстом.

Вот почему у людей вокруг Интернета возникают проблемы с ViewData в DropDownList.

В нижней строке, обратите внимание на свои идентификаторы на модели ошибок, они не должны мешать вашим элементам управления html.

    
ответ дан Junior M 09.04.2010 в 23:11
источник
-1

Мое беспокойство в том, что вы можете использовать только список для одного поля. У меня есть объекты с несколькими полями пользователя, поэтому я использую следующее:

< %= Html.DropDownList("fieldAAA", 
                       new SelectList( (IEnumerable) ViewData["Users"], "Value", "Text", fieldAAA))

%> 
    
ответ дан user448862 15.09.2010 в 22:42
источник
-1

Хорошо, я могу что-то пропустить из этого потока, однако в C # работает следующее:

Html.DropDownList("ProfessionGuid", (SelectList)ViewData["Professions"])

Где ' ProfessionGuid ' - это значение, которое должно быть выбрано в списке.

В VB.Net я считаю, что это будет:

Html.DropDownList("ProfessionGuid", ViewData["Professions"] AS SelectList)
    
ответ дан Aracnid 27.10.2009 в 13:05
источник