Questo è il modo che mi piace di legare RadioButtonLists. Il modello di vista ha una collezione di oggetti fortemente tipizzati. Ad esempio, forse PaymentOptions è una tabella di codici. Insieme alla raccolta è selezionato SelectedPaymentOptionKey (o Selected * Id se si prefissano le chiavi primarie con Id). Inizialmente questa chiave sarà predefinita 0, ma sul postback, manterrà il valore dell'elemento selezionato.
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
});
}
Poi nel Vista:
@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)
}
Il m.SelectedPaymentOptionKey serve a due scopi. Innanzitutto, raggruppa i pulsanti Radio in modo che la selezione si escluda a vicenda (ti incoraggerei a utilizzare qualcosa come FireBug per ispezionare l'html generato solo per tua comprensione. La cosa meravigliosa di MVC è che l'HTML generato è abbastanza semplice e standard quindi non dovrebbe essere difficile per te essere in grado di prevedere il comportamento dei tuoi punti di vista. C'è pochissima magia in corso qui.). In secondo luogo, manterrà il valore dell'elemento selezionato sul postback.
E infine nel gestore di posta abbiamo la SelectedPaymentOptionKey disponibili:
[HttpPost]
public ActionResult PaymentSelection(PaymentSelectionVM vm)
{
currentOrder.PaymentOption = db.PaymentOptions.Find(vm.SelectedPaymentOptionKey);
....
}
Il vantaggio di questo rispetto all'utilizzo di SelectListItems è si ha accesso a più di proprietà dell'oggetto, nel caso che si sta visualizzando una griglia/tabella e devono visualizzare molti valori dell'oggetto. Mi piace anche che non ci siano stringhe codificate che vengono passate negli helper Html come hanno fatto altri approcci.
Lo svantaggio è che si ottengono i pulsanti di opzione che hanno tutti lo stesso ID, il che non è una buona pratica. Questo è facilmente risolto modificando a questo:
@Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey, new { id = "PaymentOptions_" + opt.PaymentOptionKey})
Infine, la convalida è un po 'eccentrico con la maggior parte tutte le tecniche del pulsante di scelta che ho visto. Se ne avessi davvero bisogno, collegherei qualche jquery per compilare una SelectedPaymentOptionsKey nascosta ogni volta che si fa clic sui pulsanti di opzione e posizionare lo [Required]
o altra convalida sul campo nascosto.
Un'altra soluzione per il problema di convalida ASP.NET MVC 3 unobtrusive validation and radio buttons
Questo sembra promettente, ma non ho avuto la possibilità di testarlo: http://memoriesdotnet.blogspot.com/2011/11/mvc-3-radiobuttonlist-including.html
C'è un aiutante html sul mio blog che possono aiutare a http://jonlanceley.blogspot.com/2011/06/mvc3-radiobuttonlist-helper.html – Jon