Вот как мне нравится связывать списки RadioButtonLists. Модель представления имеет коллекцию моих строго типизированных объектов. Например, возможно, PaymentOptions - это кодовая таблица. Наряду с коллекцией есть SelectedPaymentOptionKey (или Selected * Id, если вы префикс своих первичных ключей с Id). Первоначально этот ключ будет иметь значение по умолчанию 0, но при обратной передаче он будет содержать значение выбранного элемента.
public class PaymentSelectionVM
{
public ICollection<PaymentOption> PaymentOptions { get; set; }
public int SelectedPaymentOptionKey { get; set; }
}
public ViewResult PaymentSelection()
{
var paymentOptions = db.PaymentOptions.ToList();
return View(
new PaymentSelectionVM {
PaymentOptions = paymentOptions,
//This is not required, but shows how to default the selected radiobutton
//Perhaps you have a relationship between a Customer and PaymentOption already,
//SelectedPaymentOptionKey = someCustomer.LastPaymentOptionUsed.PaymentOptionKey
// or maybe just grab the first one(note this would NullReferenceException on empty collection)
//SelectedPaymentOptionKey = paymentOptions.FirstOrDefault().PaymentOptionKey
});
}
Тогда в представлении:
@foreach (var opt in Model.PaymentOptions)
{
@*Any other HTML here that you want for displaying labels or styling*@
@Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey)
}
m.SelectedPaymentOptionKey служит двум целям. Во-первых, он группирует кнопки Radio вместе, так что выбор является взаимоисключающим (я бы посоветовал вам использовать что-то вроде FireBug для проверки сгенерированного html просто для вашего собственного понимания. Замечательная вещь в MVC - сгенерированный HTML довольно простой и стандартный так что вам не должно быть трудно в конечном итоге предсказать поведение ваших взглядов. Здесь очень мало магии.). Во-вторых, он будет содержать значение выбранного элемента при обратной передаче.
И, наконец, в обработчике поста у нас есть доступный SelectedPaymentOptionKey:
[HttpPost]
public ActionResult PaymentSelection(PaymentSelectionVM vm)
{
currentOrder.PaymentOption = db.PaymentOptions.Find(vm.SelectedPaymentOptionKey);
....
}
Преимущество этого по сравнению с использованием SelectListItems заключается в том, что у вас есть доступ к большему количеству свойств объекта в случае, если вы отображаете сетку / таблицу и вам необходимо отобразить много значений объекта. Мне также нравится, что в помощниках по Html не передаются жестко закодированные строки, как это делают некоторые другие подходы.
Недостаток в том, что вы получаете радио-кнопки с одинаковым идентификатором, что не очень хорошая практика. Это легко исправить, выбрав следующее:
@Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey, new { id = "PaymentOptions_" + opt.PaymentOptionKey})
Наконец, проверка немного странна с большинством всех техник переключателей, которые я видел. Если бы я действительно нуждался в этом, я бы подключил некоторые jquery для заполнения скрытого ключа SelectedPaymentOptions при каждом нажатии переключателей и поместил [Required]
или другую проверку в скрытое поле.
Еще один обходной путь для проблемы проверки
ASP.NET MVC 3 ненавязчивая проверка и переключатели
Это выглядит многообещающе, но у меня не было возможности проверить это:
http://memoriesdotnet.blogspot.com/2011/11/mvc-3-radiobuttonlist-including.html