I'm using MVC5 with Razor views. My viewmodel has a property of type nullable enum. I made it nullable so that when the user loads the page they have to select an option and validates when they haven't selected anything.
public class PaymentViewModel
{
[Required(ErrorMessage = "Please select a payment method", AllowEmptyStrings = false)]
public PaymentType? SelectedPaymentType { get; set; }
}
public enum PaymentType
{
CreditCard,
DirectDebit
}
On my view I have a form and am calling submit which in turn calls a controller action as a post.
The relevant part of my view looks like this:
<div class="row button-group" data-toggle="buttons">
<div class="col-xs-6">
<label class="btn btn-tertiary">
@Html.RadioButtonFor(model => model.SelectedPaymentType, PaymentType.CreditCard, new {@Name = "payment-method", @Value = "credit", @Id="rdoCredit"})
Credit Card
</label>
</div>
<div class="col-xs-6">
<label class="btn btn-tertiary">
@Html.RadioButtonFor(model => model.SelectedPaymentType, PaymentType.DirectDebit, new {@Name = "payment-method", @Value = "debit", @Id="rdoDebit"})
Direct Debit
</label>
</div>
</div>
For some reason the value coming through on my model.PaymentType is always null, even though I've selected a radio button. I added the @Id attribute as I noticed it was being given the same Id if I didn't specify one but that didn't help.
I've also tested another string property is coming through on the post so it seems specific to this property / radio button group.
If I make the property not nullable it gets set to CreditCard (being the first value of the enum), and if I select the DirectDebit radio option and submit the form it still says it is CreditCard.
(I'm sure I could be doing the labels better but my concern for now is to get the binding working properly
Edit. The html being generated is:
<form method="post" action="/myapplication/payment" novalidate="novalidate">
....
<div data-toggle="buttons" class="row button-group">
<div class="col-xs-6">
<label class="btn btn-tertiary">
<input type="radio" checked="checked" value="credit" name="payment-method" id="rdoCredit">
Credit Card
</label>
</div>
<div class="col-xs-6">
<label class="btn btn-tertiary">
<input type="radio" value="debit" name="payment-method" id="rdoDebit">
Direct Debit
</label>
</div>
</div>
...
</form>
Your rendering the name attribute as name="payment-method"
but it should be SelectedPaymentType
to match you model property name. Remove the { @name = "payment-method",
You also don't need the value
attribute
For better usability (with <label>
)
@Html.RadioButtonFor(m=> m.SelectedPaymentType, PaymentType.CreditCard, new {@Id="rdoCredit"})
<label for="rdoCredit">Credit Card</label>
@Html.RadioButtonFor(m=> m.SelectedPaymentType, PaymentType.DirectDebit, new {@Id="rdoDebit"})
<label for="rdoDebit">Direct De</label>