0

I am experiencing an issue when trying to send an entity framework form to my controller as a model thru ajax. The problem is that in some cases it doesn't passes an empty model. Here's what I have:

Manufacturer.cs

public class Manufacturer 
{
    [HiddenInput(DisplayValue = false)]
    public int ManufacturerID { get; set; }

    public string Name { get; set; }
}

Car.cs

public class Car
{
    [HiddenInput(DisplayValue = false)]
    public int CarID { get; set; }

    public string Model { get; set; }
    public int ManufacturerID { get; set; }
    public int Year { get; set; }
    public decimal Mpg { get; set; }
}

Manufacturers.cshtml

<div id="manufacturer-list">
    @Html.Partial("ManufacturerList")
</div>
<div id="manufacturer-form">
    @Html.Partial("ManufacturerForm")
</div>

ManufacturerForm.cshtml

@model Manufacturer

<form id="create-manufacturer-form" method="post">
    @Html.EditorForModel()
    <a onclick="CreateEntity('@Url.Action("CreateManufacturer", "Home")', 'manufacturer')">Add Manufacturer</a>
</form>

Cars.cshtml

<div id="car-list">
    @Html.Partial("CarList")
</div>
<div id="car-form">
    @Html.Partial("CarForm")
</div>

CarForm.cshtml

@model Car

<form id="create-car-form" method="post">
    @Html.EditorForModel()
    <a onclick="CreateEntity('@Url.Action("CreateCar", "Home")', 'car')">Add Car</a>
</form>

Javascript

function CreateEntity(createAction, modelType) {
    var $form = $('#create-' + modelType + '-form');

    $.ajax({
        type: "POST",
        url: createAction,
        data: $form.serialize(),
        dataType: 'html',
        success: function (data) {
            //do stuff
        }
    });
}

Controller

public class HomeController : Controller
{
    private readonly CarsDbContext _context;

    public HomeController(CarsDbContext context)
    {
        _context = context;
    }

    [HttpPost]
    public IActionResult CreateManufacturer(Manufacturer model)
    {
        //do stuff
    }

    [HttpPost]
    public IActionResult CreateCar(Car model)
    {
        //do stuff
    }
}

So in the case of filling out a Manufacturer form and submitting it $form.serialize() gives "ManufacturerID=0&Name=Toyota". The Controller action receives a full model with the values given and I can add that model to my database using Entity Framework.

The problem comes when trying to do the same with a Car. I fill out the form and submit it. $form.serialize() gives something like "CarID=0&Model=Camry&ManufacturerID=1&Year=2010&Mpg=24.4". The Controller action in this case recieves an empty model with 0s for any value fields and null for string fields.

Further inspection into the DOM elements created shows that the form created for Manufacturer has a hidden input field for the ManufacturerID that ends with value="0"> and the same hidden input for CarID has the attribute value>. Not sure if this is a problem but I figured it was worth noting.

I need to know why I'm receiving a complete model in the case of Manufacturer but not in the case of Car.

Joe Higley
  • 1,762
  • 3
  • 20
  • 33

1 Answers1

1

Assuming you meant to post to CreateCar(Car model) action method inside your controller,

It seems like a bug inside the default model binder when your posted form data has an item with the name Model. If your posted data does not have the FormData item with key Model, model binding works fine (Hence your manufacturer form worked for you)

It should work if you change the property name from Model to ModelName

public class Car
{
    [HiddenInput(DisplayValue = false)]
    public int CarID { get; set; }

    public string ModelName { get; set; }
    public int ManufacturerID { get; set; }
    public int Year { get; set; }
    public decimal Mpg { get; set; }
}

I will post an update to this answer as i learn more.

Shyju
  • 214,206
  • 104
  • 411
  • 497
  • This was it. Thanks. @Shyju Do you know if this is because my parameter in the controller action was named 'model' or is it an issue with 'Model' being a sort of reserved word in Entity Framework? – Joe Higley Nov 18 '17 at 21:28
  • No.It is because your form data has an item with key `Model`. So if you include an input element like `` inside your manufacturer form, that will also not work (even though you use Car as the parameter of the action method). I filed [an issue](https://github.com/aspnet/Mvc/issues/7064) in the asp.net mvc repo for this and i will update the answer as i hear something from those folks. – Shyju Nov 18 '17 at 21:39