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

18

Я попробовал поиск и не нашел ничего, что фиксировало мою проблему. У меня есть 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?

    
задан azorr 06.04.2012 в 06:05
источник
  • , пожалуйста, обратитесь к приведенной ниже ссылке. stackoverflow.com/questions/5188563/... –  alok_dida 06.04.2012 в 06:42
  • alok_dida, я просмотрел это, он выглядит очень похоже, за исключением того, что значение, выбранное при построении SelectList, использует весь объект по сравнению с ID.ToString (), как я делаю. Однако я изменил свой код, чтобы сделать то же самое, и это не решило проблему. Есть ли разница между двумя недостатками, которые могут решить мою проблему? –  azorr 06.04.2012 в 06:48
  • Я добавил подробный пример того, как это можно сделать. –  Brendan Vogt 06.04.2012 в 15:23
  • это может решить проблему dd stackoverflow.com/questions/11042660/... Спасибо. –  user2571883 11.07.2013 в 11:07

4 ответа

43

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

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

Модель:

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)
    
ответ дан Darin Dimitrov 06.04.2012 в 08:19
источник
  • Отличный ответ, спасибо за объяснение проблемы и пример того, как ее исправить. Спасибо вам за помощь. –  azorr 07.04.2012 в 20:48
  • Я действительно не понимаю, где связывается StatusID? Не является ли четвертое значение SelectList выбранным значением? Вы на самом деле ничего не сказали в избранном списке? Знает ли он, или я схожу с ума? Я не могу заставить это работать, чтобы выбрать многие выпадающие списки :( –  ppumkin 06.06.2013 в 14:26
  • @ppumkin, нет, когда вы используете модель представления и строго типизированный помощник, вам не нужен четвертый аргумент конструктора SelectList. Вот что делает x => x.StatusID. Кстати, как вы можете видеть из моего примера, я даже не использовал конструктор SelectList, потому что мое свойство модели просмотра является IEnumerable <SelectListItem> и может напрямую привязываться к DropDownListFor. –  Darin Dimitrov 06.06.2013 в 15:37
  • Я этого никогда не знал. Еще раз спасибо. У меня все работает сейчас :) Так счастливо :) –  ppumkin 06.06.2013 в 16:47
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
}

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

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

    
ответ дан Brendan Vogt 06.04.2012 в 15:23
источник
1

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

Пример:

public class MyModel
{
    public string StatusID { get; set; }
}
    
ответ дан p.sturge 02.11.2017 в 18:13
источник
-3

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

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)
    
ответ дан alok_dida 06.04.2012 в 08:30
источник
  • Мои глаза горят ggg .... aaaaaaaaaaa .. Что это? –  ppumkin 06.06.2013 в 14:22
  • Надеюсь, вы просто скопировали и ввели этот код из некоторого примера кода. Это можно было легко сделать в цикле for. Извините за код наци, но, честно говоря, мы должны прекратить распространять плохой код, даже если не используете производственный код. Если вы не вступаете в программирование, это совершенно другой уровень. –  pqsk 29.04.2014 в 18:37
  • Ребята, это был просто пример. Пользователь может создать список в любом случае. То, как я создал список, который не имеет для него никакого смысла, потому что у него будет своя коллекция. Строка, которая имеет для него значение, - это последние 2 строки кодов из C # и 2 строки кода из HTML. Пожалуйста, не уменьшайте код без логики. Вы также можете отредактировать сообщение. Вы можете опросить ответ, если он неверен. Что случилось в этом коде? –  alok_dida 26.12.2017 в 11:20
  • @ppumkin - если ваши глаза горят, тогда отредактируйте код. Что не так в коде? –  alok_dida 26.12.2017 в 11:22
  • @pqsk - я не копировал его из примера кода. Я только начал писать код и копировал пасту. Если вы делаете это плохой код, тогда отредактируйте его или напишите мне, но почему вы подали голос? Нет причин для понижения. –  alok_dida 26.12.2017 в 11:23