[asp.net-mvc] MVC4 Passing model from view to controller

I have a view with a model populated with data relating to booking a taxi.

In the model is a list of quotations with time, price, vehicle type in it which I display a list of using a foreach. Each time the foreah loops it builds a form and a submit button to take me to the "BookingStage1" action in the controller. I have also added a hidden field which is populated with the bookingrefernce for the particular quotation.

So, I was hoping that when it hit the action result in my controller that the model would be returned fully populated just like it was with the view. But it's null, no data in it whatsoever.

I was hoping to pass the populated model between a number of controllers as the user progresses through the various search, results and booking screens...

Is it possible to pass the fully populated model back from the view into the next controller?

Thanks

In my Search Results page I have the following form:

using (Html.BeginForm("BookingPage1", "SearchResults", FormMethod.Post))

I also have a hidden field in the form as below:

<input type="hidden" id="BookingID" name="ChosenBookingID" value='@item.QuotationID' />

which posts to my controller which looks like this:

[HttpPost]
    public ActionResult BookingPage1(string ChosenBookingID, Route theRoute)
    {
        //this does noting yet.
        return View();
    }

But theRoute is always empty :(

This question is related to asp.net-mvc asp.net-mvc-4

The answer is


I hope this complete example will help you.

This is the TaxiInfo class which holds information about a taxi ride:

namespace Taxi.Models
{
    public class TaxiInfo
    {
        public String Driver { get; set; }
        public Double Fare { get; set; }
        public Double Distance { get; set; }
        public String StartLocation { get; set; }
        public String EndLocation { get; set; }
    }
}

We also have a convenience model which holds a List of TaxiInfo(s):

namespace Taxi.Models
{
    public class TaxiInfoSet
    {
        public List<TaxiInfo> TaxiInfoList { get; set; }

        public TaxiInfoSet(params TaxiInfo[] TaxiInfos)
        {
            TaxiInfoList = new List<TaxiInfo>();

            foreach(var TaxiInfo in TaxiInfos)
            {
                TaxiInfoList.Add(TaxiInfo);
            }
        }
    }
}

Now in the home controller we have the default Index action which for this example makes two taxi drivers and adds them to the list contained in a TaxiInfo:

public ActionResult Index()
{
    var taxi1 = new TaxiInfo() { Fare = 20.2, Distance = 15, Driver = "Billy", StartLocation = "Perth", EndLocation = "Brisbane" };
    var taxi2 = new TaxiInfo() { Fare = 2339.2, Distance = 1500, Driver = "Smith", StartLocation = "Perth", EndLocation = "America" };

    return View(new TaxiInfoSet(taxi1,taxi2));
}

The code for the view is as follows:

@model Taxi.Models.TaxiInfoSet
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@foreach(var TaxiInfo in Model.TaxiInfoList){
    <form>
        <h1>Cost: [email protected]</h1>
        <h2>Distance: @(TaxiInfo.Distance) km</h2>
        <p>
            Our diver, @TaxiInfo.Driver will take you from @TaxiInfo.StartLocation to @TaxiInfo.EndLocation
        </p>
        @Html.ActionLink("Home","Booking",TaxiInfo)
    </form>
}

The ActionLink is responsible for the re-directing to the booking action of the Home controller (and passing in the appropriate TaxiInfo object) which is defiend as follows:

    public ActionResult Booking(TaxiInfo Taxi)
    {
        return View(Taxi);
    }

This returns a the following view:

@model Taxi.Models.TaxiInfo

@{
    ViewBag.Title = "Booking";
}

<h2>Booking For</h2>
<h1>@Model.Driver, going from @Model.StartLocation to @Model.EndLocation (a total of @Model.Distance km) for [email protected]</h1>

A visual tour:

The Index view

The Booking view