0

I'm trying to post a list of models to the server, using ASP.NET's model binding and manipulating a bunch of values with JavaScript. When I send the values to the server, this is what I get:

model.inventory.processed_items[0].id: GA-6570
model.inventory.processed_items[0].event: 
model.inventory.processed_items[0].subevent: 
model.inventory.processed_items[0].restrict_marking: 
model.inventory.processed_items[0].cecp_string: 
model.inventory.processed_items[0].discrepancies: 
model.inventory.processed_items.Index: 0
model.inventory.processed_items[1].id: GD-1000
model.inventory.processed_items[1].event: 
model.inventory.processed_items[1].subevent: 
model.inventory.processed_items[1].restrict_marking: 
model.inventory.processed_items[1].cecp_string: 
model.inventory.processed_items[1].discrepancies: 
model.inventory.processed_items.Index: 1

These are my model classes that I'm binding to (I've omitted any fields that don't really matter to the question):

public class PackageViewModel
{
    public InventoryViewModel inventory { get; set; }
}

public class InventoryViewModel
{
    public List<ProcessedItemViewModel> processed_items { get; set; }
}

public class ProcessedItemViewModel
{
    public string id { get; set; }
    public int @event { get; set; }
    public string subevent { get; set; }
    public string cecp_string { get; set; }
    public string restrict_marking { get; set; }
    public string discrepancies { get; set; }
    public string highest_classification { get; set; }
    public int occurences_count { get; set; }

    public IEnumerable<ProcessedOccurenceViewModel> occurences { get; set; }
}

public class ProcessedOccurenceViewModel
{
    public string text { get; set; }
    public string security_num { get; set; }
    public Nullable<int> media_count { get; set; }
    public string classification { get; set; }
}

This is my controller:

[HttpGet]
public ActionResult Create()
{
    var inventoryVM = new InventoryViewModel
    {
        processed_items = new List<ProcessedItemViewModel>()
    };

    var packageVM = new PackageViewModel {
        inventory = inventoryVM
    };
    return View(packageVM);
}

[HttpPost]
public ActionResult Create(PackageViewModel packageVM)
{
    if (ModelState.IsValid)
    {
         ...
    }
}

When I check packageVM in debugger, the values are not bound to the view model. However, other values excluding this nested list of models are included in the packageVM model during the POST request. I don't understand why this portion is not binding because I have supplied indices and also passed in an empty list to the view.

3
  • Based on what you show that you're getting at the server, it looks like at least the ID is binding properly. You may want to show some of your view code that shows how you are creating your form inputs - that's probably where your problem is. Commented Aug 8, 2018 at 20:37
  • 1
    The property names in the data you are sending is wrong - its inventory.processed_items[0].id: GA-6570, not model.inventory.processed_items[0].id: GA-6570 (your PackageViewModel dos not contain a property named model) Commented Aug 8, 2018 at 22:02
  • @StephenMuecke Thanks, didn't notice that, can you put that as an answer? Commented Aug 9, 2018 at 14:30

1 Answer 1

1

The property names for the values you are sending do not match the model you are binding to. PackageViewModel does not contain a property named model (it contains one named inventory), so instead of

model.inventory.processed_items[0].id: GA-6570

it needs to be

inventory.processed_items[0].id: GA-6570

An easy way to think about this is to consider how you would access the value of a property of the model in the POST method

public ActionResult Create(PackageViewModel packageVM)
{
    // get the id of the first item in processed_items
    string id = packageVM.inventory.processed_items[0].id

Because the parameter in the method is named packageVM, just drop that prefix, (i.e. becomes inventory.processed_items[0].id), and that is what the name of the data needs to be in order to bind.

As a side note, it you are using the strong typed ***For() methods inside a for loop to generate your form controls based on your model, they will generate the correct name attributes, and you can just use $('form').serialize() to correctly generate the data to be sent via your ajax call.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.