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