2

I'm writing a hotel reservation web site with Asp.net and MVC 4. it have a class named reservation which have a list of contacts. in create view i want to dynamically create contacts. (number of contacts = adults + kids and it will be determined in create reservation view) how could i post contact information to controller?

public partial class Reservation
{
    public int Id { get; set; }
    public int RoomType_Id { get; set; }
    public System.DateTime FromDate { get; set; }
    public System.DateTime ToDate { get; set; }
    public byte Adults { get; set; }
    public byte Kids { get; set; }
    public decimal Price { get; set; }
    public int User_Id { get; set; }
    public int State_Id { get; set; }
    public virtual ReservationState ReservationState { get; set; }
    public virtual RoomType RoomType { get; set; }
    public virtual User User { get; set; }
    public virtual ICollection<Transaction> Transactions { get; set; }
    public virtual ICollection<Contact> Contacts { get; set; }
}

should i set a maximum number for contacts(for example 5 and then write something like this?

    [HttpPost]
    public ActionResult Create(Reservation reservation,Contact Adult1,Contact Adult2, Contact Adult3, Contact Adult4, Contact Adult5, Contact Kid1,Contact Kid2, Contact Kid3)
    {
        if(reservation.Adults>0)
            reservation.Contacts.Add(Adult1);
        if(reservation.Adults>1)
            reservation.Contacts.Add(Adult2);
        ...
        if (ModelState.IsValid)
        {
            _db.Reservations.Add(reservation);
            _db.SaveChanges();
            return RedirectToAction("Index");
        }
    }

it's very dirty is there a better way? can i pass list of contacts?

Ali Esfahani
  • 119
  • 1
  • 3
  • 7
  • 1
    You can already pass it through the `Contacts` property of your `Reservation` class. However, have you considered using a viewmodel on your view instead of your entity? – von v. Apr 01 '13 at 11:52
  • beacuse Model.Contacts is empty. how can i create a editor for contact witch isn't exist? @Html.Editorfor(Model.Contacts.???) – Ali Esfahani Apr 01 '13 at 12:03
  • There are more than one way to achieve what you want. For your specific scenario, my preference would be to build the `Contacts` with jquery and post the "inputted" collection via ajax - all using viewmodels and not proxied objects. But... what you need is to understand **model binding** to achieve your goal. Here are two helpful SO links you can visit: [#1](http://stackoverflow.com/questions/14420964/mvc-binding-nested-list), [#2](http://stackoverflow.com/questions/12300281/asp-net-mvc-model-list-binding). – von v. Apr 01 '13 at 12:30

1 Answers1

4
@for (var i = 0; i < Model.Contacts.Count(); i++)
{
    @Html.EditorFor(m => m.Contacts[i])
}

The only thing you need to do is instantiate a list of new Contacts. This is why a view model is preferable as you could simply do this in the constructor based upon some value on your view model:

public class ReservationViewModel
{
    public ReservationViewModel()
    {
        Contacts = new List<Contact>();
        for (var i = 0; i < Adults + Kids; i++)
        {
            Contacts.Add(new Contact());
        }
    }

    ...
}

Alternatively, after you see the code that gets generated you'll understand how the modelbinder expects to receive the data back. Your inputs will look like:

<input id="Contacts_0__Name" name="Contacts[0].Name" />

Where 0 is the iteration count of contacts. If you simulate this structure manually, the modelbinder will pick up the data just as well.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444