Подтвердить что ты не робот

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

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

4b9b3361

Ответ 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))

%>