通过jQuery ajax将JSON对象数组发布到MVC3操作方法

时间:2022-08-06 21:32:46

Does the model binder not suport arrays of JSON objects? The code below works when sending a single JSON domain object as part of the ajax post. However, when sending an array of JSON domain objects, the action parameter is null.

模型绑定器是否不支持JSON对象的数组?下面的代码在发送单个JSON域对象作为ajax帖子的一部分时起作用。但是,在发送JSON域对象数组时,action参数为null。

     var domains = [{
                        DomainName: 'testt1',
                        Price: '19.99',
                        Available: true
                    }, {
                        DomainName: 'testt2',
                        Price: '15.99',
                        Available: false
                    }];

                $.ajax({
                    type: 'POST',
                    url: Url.BasketAddDomain,
                    dataType: "json",
                    data: domains,
                    success: function (basketHtml) {

                    },
                    error: function (a, b, c) {
                        alert('A problem ocurred');
                    }
            });

This is the action method:

这是动作方法:

public ActionResult AddDomain(IEnumerable<DomainBasketItemModel> domain)
{
    ...

Any ideas if it is possible to do this?

任何想法,如果有可能这样做?

EDIT

编辑

@Milimetric

@Milimetric

Your solution works! However, this is my fault, but the code I demonstrated isn't the real code of my problem, I was trying to show equivalent code that is easier to understand.

您的解决方案有效但是,这是我的错,但我演示的代码不是我的问题的真实代码,我试图显示更容易理解的等效代码。

I am actually creating an array, then interating some DOM elements and pushing a JSON object onto the array, then posting this array as the data...

我实际上正在创建一个数组,然后交换一些DOM元素并将JSON对象推送到数组上,然后将此数组作为数据发布...

var domains = [];

                $(this).parents('table').find('input:checked').each(function () {
                    var domain = {
                        DomainName: $(this).parent().parent().find('.name').html(),
                        Price: $(this).parent().parent().find('.price span').html(),
                        Available: $(this).parent().parent().find('.available').html() == "Available"
                    }

                    domains.push(domain);
                });

                $.ajax({
                    type: 'POST',
                    url: Url.BasketAddDomain,
                    dataType: "json",
                    data: { domain: domains },
                    success: function (basketHtml) {

                    },
                    error: function (a, b, c) {
                        alert('A problem ocurred');
                    }
                });

2 个解决方案

#1


31  

You need:

你需要:

var domains = { domains: [... your elements ...]};

            $.ajax({
                type: 'post',
                url: 'Your-URI',
                data: JSON.stringify(domains),
                contentType: "application/json; charset=utf-8",
                traditional: true,
                success: function (data) {
                    ...
                }
            });

In general, check out the Request object in the debugger, you'll see what's being passed and get an idea of how to "speak" HTTP.

通常,在调试器中检查Request对象,您将看到正在传递的内容,并了解如何“说”HTTP。

NOTE: Just found this out. The model binder chokes on nullable decimal properties like:

注意:刚刚发现了这一点。模型绑定器会阻塞可为空的十进制属性,例如:

public decimal? latitude { get; set; }

So it won't bind that if you're posting to it with a json string that looks like this:

因此,如果您使用看起来像这样的json字符串发布它,它将不会绑定它:

{"latitude":12.0}

But it WILL work if you post something like this:

但是如果你发布这样的东西它会起作用:

{"latitude":"12.0"}

See: http://syper-blogger.blogspot.com/2011/07/hello-world.html

请参阅:http://syper-blogger.blogspot.com/2011/07/hello-world.html

#2


1  

I had a similar problem. To solve it, I took a slightly different approach. Instead of a JSON object, I used arrays of hidden form variables. As long as the variable names matched up, model binding worked like a charm.

我有类似的问题。为了解决这个问题,我采取了略微不同的方法。我使用隐藏表单变量数组而不是JSON对象。只要变量名称匹配,模型绑定就像魅力一样。

function AddDomainBasket(domainName, price, available) {

    if ( typeof AddDomainBasket.counter == 'undefined' ) {
        AddDomainBasket.counter = 0;
    }

    $("#some_form").append('<input type="hidden" name="[' + AddDomainBasket.counter + '].DomainName" value="' + domainName_index + '" />');
    $("#some_form").append('<input type="hidden" name="[' + AddDomainBasket.counter + '].Price" value="' + price + '" />');
    $("#some_form").append('<input type="hidden" name="[' + AddDomainBasket.counter + '].Available" value="' + available + '" />');

    ++AddDomainBasket.counter;
}

And then submit the serlialized form

然后提交serlialized表单

$(this).parents('table').find('input:checked').each(function () {
    AddDomainBasket($(this).parent().parent().find('.name').html(),
                    $(this).parent().parent().find('.price span').html(),
                    $(this).parent().parent().find('.available').html() ==   "Available");
                }
            });

$.ajax({
    type: 'POST',
    url: Url.BasketAddDomain,
    data: $('#some_form').serialize(),
    success: function (basketHtml) {
        },
        error: function (a, b, c) {
            alert('A problem ocurred');
    }
});

#1


31  

You need:

你需要:

var domains = { domains: [... your elements ...]};

            $.ajax({
                type: 'post',
                url: 'Your-URI',
                data: JSON.stringify(domains),
                contentType: "application/json; charset=utf-8",
                traditional: true,
                success: function (data) {
                    ...
                }
            });

In general, check out the Request object in the debugger, you'll see what's being passed and get an idea of how to "speak" HTTP.

通常,在调试器中检查Request对象,您将看到正在传递的内容,并了解如何“说”HTTP。

NOTE: Just found this out. The model binder chokes on nullable decimal properties like:

注意:刚刚发现了这一点。模型绑定器会阻塞可为空的十进制属性,例如:

public decimal? latitude { get; set; }

So it won't bind that if you're posting to it with a json string that looks like this:

因此,如果您使用看起来像这样的json字符串发布它,它将不会绑定它:

{"latitude":12.0}

But it WILL work if you post something like this:

但是如果你发布这样的东西它会起作用:

{"latitude":"12.0"}

See: http://syper-blogger.blogspot.com/2011/07/hello-world.html

请参阅:http://syper-blogger.blogspot.com/2011/07/hello-world.html

#2


1  

I had a similar problem. To solve it, I took a slightly different approach. Instead of a JSON object, I used arrays of hidden form variables. As long as the variable names matched up, model binding worked like a charm.

我有类似的问题。为了解决这个问题,我采取了略微不同的方法。我使用隐藏表单变量数组而不是JSON对象。只要变量名称匹配,模型绑定就像魅力一样。

function AddDomainBasket(domainName, price, available) {

    if ( typeof AddDomainBasket.counter == 'undefined' ) {
        AddDomainBasket.counter = 0;
    }

    $("#some_form").append('<input type="hidden" name="[' + AddDomainBasket.counter + '].DomainName" value="' + domainName_index + '" />');
    $("#some_form").append('<input type="hidden" name="[' + AddDomainBasket.counter + '].Price" value="' + price + '" />');
    $("#some_form").append('<input type="hidden" name="[' + AddDomainBasket.counter + '].Available" value="' + available + '" />');

    ++AddDomainBasket.counter;
}

And then submit the serlialized form

然后提交serlialized表单

$(this).parents('table').find('input:checked').each(function () {
    AddDomainBasket($(this).parent().parent().find('.name').html(),
                    $(this).parent().parent().find('.price span').html(),
                    $(this).parent().parent().find('.available').html() ==   "Available");
                }
            });

$.ajax({
    type: 'POST',
    url: Url.BasketAddDomain,
    data: $('#some_form').serialize(),
    success: function (basketHtml) {
        },
        error: function (a, b, c) {
            alert('A problem ocurred');
    }
});