0

I am populating an array with an [int,bool]:

$.each(ownedChecked, function (key, val) {
    /*code to set id as int and paintedTrue as bool*/
    ownedIDs.push([id,paintedTrue]);
});

I create a var that will be stringified:

var saveData = { OwnedListEntryIDs:ownedIDs };

//send data
$.ajax({
    url: '/ListEntry/OwnedModels',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(saveData),
    success: function (data) { alert('Update success: ' + data); },
    failure: function (data) { alert('Update failed: ' + data); }
});

Here is the ViewModel:

public class OwnedPaintedSave
{
    //collection contains a ListEntryID and a bool indicating whether it is painted or not
    public Dictionary<int,bool> OwnedListEntryIDs { get; set; }
}

Once in the controller method, ModelState.Isvalid passes and code gets to the foreach loop, but models is always NULL:

[HttpPost]
public JsonResult OwnedModels(OwnedPaintedSave models)
{
    if (ModelState.IsValid)
    {
        foreach (var id in models.OwnedListEntryIDs)
        { }
    }
}

I tried setting traditional:true in the $.ajax method, but same issue. I'm guessing the Dictionary in the ViewModel is not what I need to bind to, but I'm not sure what it should be. Thanks for any help.

2 Answers 2

1

I gave the OwnedPaintedSave object two int[] properties, one for OwnedIDs and one for PaintedIDs.

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

Comments

0

I think the problem lies in your controller. You are passing var saveData = { OwnedListEntryIDs:ownedIDs }; (essentially a Dictionary<int, bool> - yes?) as your data but the parameter in the action result is of type OwnedPaintedSave

I think if you change your controller parameter to Dictionary<int, bool> ownedListEntryIDs and don't stringify the javascript object, the framework is clever enough to serialize and deserialize your object. So you would have this...

var saveData = { OwnedListEntryIDs:ownedIDs };

//send data
$.ajax({
    url: '/ListEntry/OwnedModels',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: saveData,
    success: function (data) { alert('Update success: ' + data); },
    failure: function (data) { alert('Update failed: ' + data); }
});

And then this in your controller...

[HttpPost]
public JsonResult OwnedModels(Dictionary<int, bool> ownedListEntryIDs)
{
    if (ModelState.IsValid)
    {
        foreach (var id in ownedListEntryIDs)
        { }
    }
}

2 Comments

Correct me if I am wrong, but accepting an OwnedPaintedSave object with properties of the types I'm passing in is referred to as a ViewModel or DataTransferObject. I've used this pattern in other places, but this is the first time I want a property to contain a Dictionary-style parameter. In any case, I decided to work around this by defining the OwnedPaintedSave object to have two properties: int[] OnwedIDs and int[] PaintedIDs, and let the Controller method decide if painted is true. Thanks for the assistance! -C
Correct, but you were not passing the view model back to the controller. You were passing the property inside the view model to the controller. thinking about it, if you just changed the name of the JS var from saveData to models (the name of the parameter in your controller), it should work.

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.