Tania Marinova
Tania Marinova

Reputation: 1908

how to bind mvc4 radiobutton to a model

Hello I've got a simple user class and in this user classs I've got property of type List<Contact>

public  class User
{
  public User()
  {
    this.AddressContact = new List<Contact>();
  }           
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string Email { get; set; }
  public List<Contact> AddressContact { get; set; }                         
}

public class Contact
{
  public int Id { get;set; }
  public string NameCompany {get;set;}
  public string Street {get; set; }
  public string Town {get; set; }
  public string Telephone {get; set;}
  public string Fax {get; set;}
}

I've got an action which return a view model

public ActionResult ConfirmationOrder()
{
  ConfirmationModel confmodel = new ConfirmationModel();
  Cart cart = (Cart)Session["Cart"];
  User contactUser = WebServiceBea.GetUserAddress(HttpContext.User.Identity.Name);
  confmodel.cart = cart;
  confmodel.user = contactUser;
  return PartialView(confmodel);
}

Here is my View

@model MvcBeaWeb.Models.ConfirmationModel
<div class="pmc-page-container" id="" style="position: relative; width: 85%; ">
  <!-- Address Div -->
  @using (Html.BeginForm("Index", "OrderSummary", new { mod = Model }, FormMethod.Get, null))
  { 
    <div class="address" style="overflow: hidden;">
      <div style="width: 100%; float: left; line-height: 15px; margin: 5px 0px;" class="radio-line">
        @foreach (var item in Model.user.AddressContact)
        {
          <div>
            @Html.RadioButtonFor(model => model.user.AddressContact, new { id = "item" + item.Id })
            @Html.Label(item.NameCompany, item.NameCompany)
          </div>
        }
      </div>
    </div>      
    <input type="submit" value="Submit" />
  }
</div>   

The problem is : I've got an radiobutton which should present all the address from the List of an user. But when I click the submit button I've got no selection (I cannot get the selected address) and actually the ConfirmationModel in my OrderSummary Controller is empty (my form is posting to this controller)- like the binding is not working at all

public class OrderSummaryController : Controller
{
  [Authorize]
  public ActionResult Index(ConfirmationModel mod)

Upvotes: 1

Views: 1341

Answers (1)

user3559349
user3559349

Reputation:

You have numerous issue with your code. Firstly, a radio button group posts back a single value but your trying to bind to a complex object. Your view indicates your creating a form for selecting the contact so create a view model that represents what you want to display and edit

View model

public class ContactVM
{
  public int SelectedContact { get; set; }
  public List<Contact> ContactList { get; set; }
  // Add any other properties that you want to display/edit
}

Controller

public ActionResult ConfirmationOrder()
{
  ContactVM model= new ContactVM();
  // populate the collection of contacts (and set the value of SelectedContact if you want a default item selected)
  return View(model);
}

public ActionResult ConfirmationOrder(ContactVM model)
{
  // model.SelectedContact now contains the ID of the selected contact
}

View

@model ContactVM
@using (Html.BeginForm())
{
  @foreach (var contact in Model.Contacts)
  {
    @Html.RadioButtonFor(m => m.SelectedContact, contact.ID, new { id = contact.Id })
    <label for="@contact.Id>@contact.NameCompany</label>
  }
  <input type="submit" value="Submit" />
}

Note the for attribute in the label tag to associate the text with the button.

Next you have stated your want a POST but use FormMethod.Get in BeginForm, but worse, you attempt to pass the model as route parameters. In the case of a simple model with just a few value type properties this will work, however you have a model with complex properties and collections. Apart from the ugly query string this would create, and the fact that it would soon exceed the query string limit (throwing an exception), it just wont work. Inspect the html in the form tag. You will see things like user=MvcBeaWeb.Models.User" so when you submit the model binder tries to set your user property to the string "MvcBeaWeb.Models.User" which fails (you can assign a string to a complex object) and the user property is reset to null. Its unclear why your trying to do this (why would you degrade performance by sending your whole model to the client, then post it all back unchanged?).

You should post back your view model to a POST method, save the data, then redirect to your Index() method (but you have not posted your ConfirmationModel or the main view so its a little hard to be more specific).

Upvotes: 1

Related Questions