2

Here is the javascript code I use to create the array and send it on it's way:

<script type="text/javascript" language="javascript">
    $(document).ready(function () {
        $("#update-cart-btn").click(function() {
            var items = [];
            $(".item").each(function () {
                var productKey = $(this).find("input[name='item.ProductId']").val();
                var productQuantity = $(this).find("input[type='text']").val();
                items[productKey] = productQuantity;
            });

            $.ajax({
                type: "POST",
                url: "@Url.Action("UpdateCart", "Cart")",
                data: items,
                success: function () {
                    alert("Successfully updated your cart!");
                }
            });
        });
    });
</script>

The items object is properly constructed with the values I need.

What data type must my object be on the backend of my controller?

I tried this but the variable remains null and is not bound.

[Authorize]
[HttpPost]
public ActionResult UpdateCart(object[] items) // items remains null.
{

    // Some magic here.
    return RedirectToAction("Index");
}

1 Answer 1

10

If you are going to send JSON to the server you need to JSON.stringify the data and specify the contentType as application/json to play nice with the MVC3 model binder:

    $.ajax({
            type: "POST",
            url: "@Url.Action("UpdateCart", "Cart")",
            data: JSON.stringify(items),
            success: function () {
                alert("Successfully updated your cart!");
            },
            contentType: 'application/json'
        });

And as the datatype on the server you can use strongly typed classes eg:

public class Product
{
    public int ProductKey { get; set; }
    public int ProductQuantity { get; set; }
}

[HttpPost]
public ActionResult UpdateCart(Product[] items)
{

    // Some magic here.
    return RedirectToAction("Index");
}

But you need to tweak the items list a bit:

var items = [];
$(".item").each(function () {
   var productKey = $(this).find("input[name='item.ProductId']").val();
   var productQuantity = $(this).find("input[type='text']").val();
   items.push({ "ProductKey": productKey, "ProductQuantity": productQuantity });
});

Basically the JSON object structure should match the C# model class structure (also the property name should match) and then the model binder in MVC takes care to populate your server side models with the JSON data that you've sent. You can read more about model binders here.

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

6 Comments

Are you sure you need a , in between the key when invoking push? I'm getting a parser error there.
@SergioTapia yes, you are there was a typo. See my updated answer.
Items are still not bound when reaching the backend. Any ideas? I remembered to add `contentType: 'application/json'´.
Is the controller action reached? Try to remove Authorize maybe that is causing the problem. I've tried my sample with some hard coded items : items.push({ "ProductKey": 1, "ProductQuantity": 11 }); items.push({ "ProductKey": 2, "ProductQuantity": 12 }); and it works for me... Maybe there is data type mismatch. Can you post your model and your items look like before the ajax call?
Strange, I removed the Authorize attribute from the Action Method and the items are properly bound. I guess I can leave this action unprotected as it doesn't touch sensitive information. Thanks!
|

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.