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

MVC DropDownList SelectedValue отображается неправильно

Я попробовал поиск и не нашел ничего, что фиксировало мою проблему. У меня есть DropDownList в представлении Razor, который не покажет элемент, который отмечен как Selected в SelectList. Вот код контроллера, который заполняет список:

var statuses  = new SelectList(db.OrderStatuses, "ID", "Name", order.Status.ID.ToString());
ViewBag.Statuses = statuses;
return View(vm);

Вот код вида:

<div class="display-label">
   Order Status</div>
<div class="editor-field">
   @Html.DropDownListFor(model => model.StatusID, (SelectList)ViewBag.Statuses)
   @Html.ValidationMessageFor(model => model.StatusID)
</div>

Я просматриваю его, и даже в представлении он имеет правильный SelectedValue, однако DDL всегда показывает первый элемент в списке, независимо от выбранного значения. Может ли кто-нибудь указать, что я делаю неправильно, чтобы получить DDL по умолчанию для SelectValue?

4b9b3361

Ответ 1

Последний аргумент конструктора SelectList (в котором вы надеетесь передать идентификатор выбранного значения) игнорируется, потому что помощник DropDownListFor использует выражение лямбда, которое вы передали в качестве первого аргумента, и использует значение конкретного свойства.

Итак, уродливый способ сделать это:

Модель:

public class MyModel
{
    public int StatusID { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: obviously this comes from your DB,
        // but I hate showing code on SO that people are
        // not able to compile and play with because it has 
        // gazzilion of external dependencies
        var statuses = new SelectList(
            new[] 
            {
                new { ID = 1, Name = "status 1" },
                new { ID = 2, Name = "status 2" },
                new { ID = 3, Name = "status 3" },
                new { ID = 4, Name = "status 4" },
            }, 
            "ID", 
            "Name"
        );
        ViewBag.Statuses = statuses;

        var model = new MyModel();
        model.StatusID = 3; // preselect the element with ID=3 in the list
        return View(model);
    }
}

Вид:

@model MyModel
...    
@Html.DropDownListFor(model => model.StatusID, (SelectList)ViewBag.Statuses)

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

Model

public class MyModel
{
    public int StatusID { get; set; }
    public IEnumerable<SelectListItem> Statuses { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: obviously this comes from your DB,
        // but I hate showing code on SO that people are
        // not able to compile and play with because it has 
        // gazzilion of external dependencies
        var statuses = new SelectList(
            new[] 
            {
                new { ID = 1, Name = "status 1" },
                new { ID = 2, Name = "status 2" },
                new { ID = 3, Name = "status 3" },
                new { ID = 4, Name = "status 4" },
            }, 
            "ID", 
            "Name"
        );
        var model = new MyModel();
        model.Statuses = statuses;
        model.StatusID = 3; // preselect the element with ID=3 in the list
        return View(model);
    }
}

Вид:

@model MyModel
...    
@Html.DropDownListFor(model => model.StatusID, Model.Statuses)

Ответ 2

Создайте модель представления для каждого вида. Таким образом, вы будете включать только то, что необходимо на экране. Поскольку я не знаю, где вы используете этот код, предположим, что у вас есть представление Create, чтобы добавить новый порядок.

Создайте новую модель представления для вашего представления Create:

public class OrderCreateViewModel
{
     // Include other properties if needed, these are just for demo purposes

     // This is the unique identifier of your order status,
     // i.e. foreign key in your order table
     public int OrderStatusId { get; set; }
     // This is a list of all your order statuses populated from your order status table
     public IEnumerable<OrderStatus> OrderStatuses { get; set; }
}

Класс статуса заказа:

public class OrderStatus
{
     public int Id { get; set; }
     public string Name { get; set; }
}

В представлении "Создать" у вас будет следующее:

@model MyProject.ViewModels.OrderCreateViewModel

@using (Html.BeginForm())
{
     <table>
          <tr>
               <td><b>Order Status:</b></td>
               <td>
                    @Html.DropDownListFor(x => x.OrderStatusId,
                         new SelectList(Model.OrderStatuses, "Id", "Name", Model.OrderStatusId),
                         "-- Select --"
                    )
                    @Html.ValidationMessageFor(x => x.OrderStatusId)
               </td>
          </tr>
     </table>

     <!-- Add other HTML controls if required and your submit button -->
}

Ваши действия:

public ActionResult Create()
{
     OrderCreateViewModel viewModel = new OrderCreateViewModel
     {
          // Here you do database call to populate your dropdown
          OrderStatuses = orderStatusService.GetAllOrderStatuses()
     };

     return View(viewModel);
}

[HttpPost]
public ActionResult Create(OrderCreateViewModel viewModel)
{
     // Check that viewModel is not null

     if (!ModelState.IsValid)
     {
          viewModel.OrderStatuses = orderStatusService.GetAllOrderStatuses();

          return View(viewModel);
     }

     // Mapping

     // Insert order into database

     // Return the view where you need to be
}

Это будет сохраняться при выборе кнопки отправки и перенаправляется обратно в представление создания для обработки ошибок.

Надеюсь, это поможет.

Ответ 3

Уверен, что ваше возвращаемое значение выбора - это строка, а не и int, когда вы объявляете ее в своей модели.

Пример:

public class MyModel
{
    public string StatusID { get; set; }
}

Ответ 4

Для меня проблема была вызвана большими числами заполнения CSS (верхний и нижний отступы внутри выпадающего поля). По сути, этот предмет показывался, но не был виден, потому что был далеко внизу. Я ИСПРАВЛЕНО, уменьшив число отступов.

Ответ 5

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

У меня было свойство в ViewData с тем же именем, что и у селектора лямбда-выражения, в основном, как если бы вы имели ViewData["StatusId"] установленным на что-то.

После того как я изменил имя анонимного свойства в ViewData, помощник DropDownList работал как положено.

Странно, хотя.

Ответ 6

Пожалуйста, найдите пример кода ниже.

public class Temp
    {
        public int id { get; set; }
        public string valueString { get; set; }
    }

Контроллер

public ActionResult Index()
        {
            // Assuming here that you have written a method which will return the list of Temp objects.
            List<Temp> temps = GetList();

            var tempData = new SelectList(temps, "id", "valueString",3);
            ViewBag.Statuses = tempData;

            return View();
        }

Вид

 @Html.DropDownListFor(model => model.id, (SelectList)ViewBag.Statuses)
    @Html.ValidationMessageFor(model => model.id)