Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 3.0 Model binding with Base and Derived classes?

Hi all I have a base class called Vehicle and I have all the properties common to all vehicles in there and I have multiple derived classes called Car, Jeep which derive from Vehicle and add more properties

Ex:

    public class Vehicle
{
    public int Color { get; set; }
    public double Cost { get; set; }
}


public class Car : Vehicle
{
    public SelectListItem Option { get; set; }
}

I have a Page class in which I have a list of vehicles like this

public class Page
{
    public List<Vehicle> vehicles { get; set; }
}

My view is strongly types to the Page class so in my view I am looping over all the vehicles to display on page like this, This code is inside @using(Html.BeginForm()) so we post back user selections

    for(int i=0;i<Model.Vehicles.Count;i++)
{
    <div id="Question">
        @{
            @Html.EditorFor(m => m.Vehicle[i], VehicleConstants.GetTemplateName(Model.Questions[i]));
         }
    <br />
    </div>
 }

I am using one Editor template for each type of vehicle so the function call VehicleConstants.GetTemplateName just returns the name of the template to use based on the type of vehicle

This template simply writes the properties on the car class or Jeep class (Derived class + Base class)

The problem I am having is when the form is posted back I can only access the properties of Base class Vehicle in my controller I cannot get the value for properties of sub class car or Jeep.

        [HttpPost]
    public string ReadPost(Page page)
    {
    }

What is the best way to get these values autobinded when the form is posted back?

Is creating Custom Binder Class my only option? Is so can someone provide me some sample code as to how to do this? Any help much appreciated.

like image 503
icoolguy Avatar asked May 04 '12 21:05

icoolguy


1 Answers

You will have to use a custom model binder for this. The default model binder doesn't know which concrete type to instantiate. You may include a hidden field inside each row indicating the concrete type that your custom model binder would create. I have shown this in action here. By the way notice that by using the standard templates naming convention you could get rid of the for loop that you are using as well as the VehicleConstants.GetTemplateName method.

like image 141
Darin Dimitrov Avatar answered Oct 26 '22 09:10

Darin Dimitrov