Search code examples
asp.net-mvcasp.net-mvc-4entity-framework-5asp.net-mvc-controller

Why are the nested objects in my parent object null when posting to my MVC 4 Controller?


Let's say I have a complex model which contains a custom class:

    public class Car
{
    public Car() {}
    public Engine engine { get; set } // nested object
    public int FuelRemaining {get; set;}
    public int VehicleStatus {get; set;}
}

And an MVC 4 Controller that looks something like this:

    [HttpPost]
    public PartialViewResult ShowVehicleDetails(Car currentVehicle)
    {
        return PartialView(currentVehicle);
    }

If I pass an instance of this class to the controller using an ajax post, and then try to return a view, partial view, or even just peek into the object, all of the values of engine are null, but everything else is fine.

Here in example of the JSON that I see showing up in the form data of the request header for the POST:

{"engine":{"engineVIN":258736,"engineKM":160015,"EngineDesc":"EcoTech V8"},"FuelRemaining":90,"VehicleStatus":1}

Note: Values for FuelRemaining, and VehicleStatus are showing up just fine in the controller and in the resulting view.

Can someone explain to me why this is the case, and how best to work around this?

I did come across this blog article from the asp.net team, but it is dated 2010 and I haven't been able to find any more recent information.


Solution

  • A closer look at a sample I found online of passing complex objects to a controller clearly indicated that I was neglecting to set the contentType when making the ajax call.

    Specifically, a working call should look like this:

            var jsonData = { "StartDate": selectedDate, "EndDate": selectedDate };
    
        $.ajax(
                {
                    url: '@Url.Action("GetMyConcertTickets", "Main")',
                    type: 'POST',
                    data: JSON.stringify(jsonData),
                    contentType: 'application/json',
                    cache: false,
                    success: function (data) {
                        populateMyConcertTicketsOnGrid(data);
                    }
                });
    

    If you don't tell the controller that you are passing "application/json", then I think it will expect "text/html".