Невозможно изменить выбранное значение для SelectList - MVC

Я пытаюсь создать DropDownList для каждой записи в таблице в представлении. Мне не удается установить выбранное значение для раскрывающегося списка.

В контроллере список уровней доступа каждого пользователя в модели заполняется путем вызова метода в репозитории. Кажется, я не могу правильно понять этот метод. Я могу изменить выбранное значение для элемента, и для accessLevels выбрано правильное значение. Но в представлении это не выбранное значение. Как я могу установить выбранное значение в списке выбора?

Я пробовал это:

Репозиторий:

public IEnumerable<SelectListItem> GetSelectListAccessLevelsWithSelectedItem(string selectedAccessLevelID)
        {

            IEnumerable<SelectListItem> accessLevelsFromDB = DB.AccessLevels
              .Select(x => new SelectListItem
              {
                  Value = x.AccessLevelID.ToString(),
                  Text = x.Name
              });


            SelectListItem item = null;
            foreach (SelectListItem a in accessLevelsFromDB)
            {
                if (a.Value == selectedAccessLevelID)
                {

                    item = a;
                    a.Selected = true;
                }
            }

            var accessLevels = new SelectList(accessLevelsFromDB, item.Value);
            return accessLevels;
        }

А также попытался вернуть accessLevelsFromDB:

return accessLevelsFromDB;

Вид:

@Html.DropDownList("Accesslevels", user.AccessLevelsWithSelectedItem, new { @class = "form-control", @name = "accessLevels"})

Правильно ли я использовал SelectList Constructor (IEnumerable, Object)? Или что еще мне не хватает? Я пытался погуглить, но все еще не понимаю, что делаю не так. Я посмотрел на этот вопрос SelectList Selected Value Issue - Stack Overflow, но это не так » кажется, не работает.

Обновлять:

это модель:

public class EditCustomerViewModel
{
    public Customer Customer { get; set; }
    public int CustomerID { get; set; }
    public List<User> Users { get; set; }
    public List<UserToView> UsersToView { get; set; }
    public IEnumerable<SelectListItem> AccessLevelListForSelectedUser { get; set; }

}

Обновление 2:

Теперь он работает, и я обновил свою модель и репозиторий.

Модель:

public class EditCustomerViewModel
    {
        public Customer Customer { get; set; }
        public int CustomerID { get; set; }
        public List<UserToView> UsersToView { get; set; }

    }

Репозиторий:

public IEnumerable<SelectListItem> GetSelectListAccessLevelsWithSelectedItem(string selectedAccessLevelID)
{
    IEnumerable<SelectListItem> accessLevelsFromDB = DB.AccessLevels
      .Select(x => new SelectListItem
      {
          Value = x.AccessLevelID.ToString(),
          Text = x.Name,
          Selected = x.AccessLevelID.ToString() == selectedAccessLevelID

      });
    return accessLevelsFromDB;
}

person user3215947    schedule 18.10.2016    source источник
comment
В вашей модели представления нет свойства с именем Accesslevels, поэтому вы даже ни к чему не привязываетесь. И вы не устанавливаете свойство Selected для SelectListItem при привязке к свойству (это значение свойства, которое определяет, что выбрано (внутренне метод строит свой собственный список SelectList). И var accessLevels = new SelectList(accessLevelsFromDB, item.Value); не имеет смысла, потому что accessLevelsFromDB уже является SelectList   -  person    schedule 19.10.2016
comment
И модели просмотра никогда не должны содержать модели данных при редактировании.   -  person    schedule 19.10.2016
comment
AccessLevelsWithSelectedItem - это свойство каждого пользователя в свойстве UsersToView в модели, и это свойство, к которому я пытаюсь привязаться. Следует ли мне указать AccessLevelsWithSelectedItem в качестве первого строкового аргумента раскрывающегося списка, или я неправильно понял?   -  person user3215947    schedule 19.10.2016
comment
Да, но даже это не будет связывать, если вы создаете это цикл. И ответ, который вы приняли, полностью вводит в заблуждение. Свойство Selected игнорируется методом DropDownList(), если вы не привязываетесь к свойству - а в вашем случае это не так (оно не будет привязано к вашей модели при отправке). И я рекомендую вам прочитать MVC5 Razor html.dropdownlist для набора, выбранного, когда значение находится в массиве   -  person    schedule 19.10.2016


Ответы (3)


Это должно дать вам выбранный элемент для раскрывающегося списка:

public IEnumerable<SelectListItem> AccessLevelsWithSelectedItem(string selectedAccessLevelID)
    {
        return DB.AccessLevels
          .Select(x => new SelectListItem
          {
              Value = x.AccessLevelID.ToString(),
              Text = x.Name,
              Selected = x.AccessLevelID.ToString() == selectedAccessLevelID
          });
    }
person Papa Burgundy    schedule 18.10.2016

Было бы полезно, если бы мы могли видеть модель, которую использует ваше представление. Как бы то ни было, вы слишком усложняете задачу.

Во-первых, DropDownList нужно только IEnumerable<SelectListItem>. Razor позаботится о создании SelectList экземпляра и привязке соответствующего выбранного значения. Фактически, он все равно это делает, поэтому ваши собственные попытки выбрать элемент будут бесплодны, пока вы не обнаружите, что вызывает неправильную привязку значения или отсутствие привязки.

В этом отношении все вращается вокруг ModelState, который состоит из значений из Request, _6 _ / _ 7_ и finally Model. Эта «окончательная» часть важна, потому что все, что есть в данных запроса или просмотра, всегда переопределяет все, что установлено в вашей модели.

Другими словами, если у вашего действия есть параметр типа accessLevels или вы устанавливаете что-то вроде ViewBag.AccessLevels. Эти значения будут использоваться как «выбранное» значение для раскрывающегося списка.

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

@Html.DropDownListFor(m => m.AccessLevels, Model.AccessLevelOptions)

Где AccessLevelOptions будет IEnumerable<SelectListItem> и содержать доступные уровни доступа. При этом у вас никогда не будет проблем с выбранным значением, потому что Razor будет обрабатывать все, и вы строго привязаны к определенному свойству в своей модели. Только когда вы начинаете играть с именами струн, не имея реальной связи ни с чем, все начинает идти наперекосяк.

person Chris Pratt    schedule 18.10.2016
comment
Я обновился с моделью. Но если я использую этот @ Html.DropDownListFor (m = ›m.AccessLevels, Model.AccessLevelOptions), как раскрывающийся список узнает, какое значение выбрать? Мне нужно выбрать конкретное значение, которое находится в модели в Model.UsersToView.UserToView.AccessLevel. - person user3215947; 18.10.2016
comment
Тогда вы должны быть к этому привязаны. Он знает на основе того, что находится в ModelState, поэтому вам нужно составить свою модель так, чтобы свойство, к которому вы привязываете, содержало то значение, которое оно имеет или должно иметь. - person Chris Pratt; 18.10.2016

Вы можете просто передать атрибут значения жестко запрограммированной строки или модельное значение для этого свойства:

@Html.DropDownList("Accesslevels", user.AccessLevelsWithSelectedItem, new { @class = "form-control", @name = "accessLevels", Value = "something" })

or

@Html.DropDownList("Accesslevels", user.AccessLevelsWithSelectedItem, new { @class = "form-control", @name = "accessLevels", Value = Model.MyProperty })
person Rob C    schedule 18.10.2016
comment
Не следует путать атрибут value. В лучшем случае вы замалчиваете более глубокую проблему. В худшем случае вы помешаете правильной привязке значений. - person Chris Pratt; 18.10.2016
comment
Я попробовал, но он все равно не изменил выбранное значение для раскрывающегося списка - person user3215947; 18.10.2016