简体   繁体   中英

JSON doesn't post array with 1 item in MVC 4

I have my MVC 4 project. I have 2 select with multiple options.

<select id="ReportDetailsSelectList" class="form-control ListBox valid" size="10" multiple="">
    <option value="ADMN">Administration</option>
    <option value="ARC">Adminstrative Resource Center</option>
    <option value="BALS">Balance Sheet</option>
</select>

<select id="ReportDetailsSelectList2" class="form-control ListBox valid" size="10" multiple="">
    <option value="ATL">Atlanta</option>
    <option value="BALT">Baltimore</option>
    <option value="BETH">Betheseda</option>
    <option value="CAMD">Camden</option>
</select>

<button id="btnSubmit" name="btnSubmit" type="button" class="btn btn-primary">Submit</button>

I need to collect all selected values from 2 select lists and post it in my Action

Here's my JavaScript Code:

$('#btnSubmit').click(function () {
    var result = [];
    // Go through Details List
    $('select#ReportDetailsSelectList option:selected').each(function () {
        // Collect Name and Value
        var item = {};
        item.Key = $(this).val();
        item.Value = $(this).text();
        result.push(item);
    });

    var result2 = [];
    // Go through Details List
    $('select#ReportDetailsSelectList2 option:selected').each(function () {
        // Collect Name and Value
        var item = {};
        item.Key = $(this).val();
        item.Value = $(this).text();
        result2.push(item);
    });

    CollectPostData(result, result2);
});

function CollectPostData(result, result2) {
    // Post collected data to the action
    $.ajax({
        url: "/Home/GenerateReport",
        type: "POST",
        data: JSON.stringify({ 'detailList': result, 'detailList2': result2 }),
        dataType: "json",
        traditional: true,
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            if (data.status == "Success") {
                alert(data.message);
            } else {
                alert("Error occurs on the Database level!");
            }
        },
        error: function () {
            alert("An error has occurred!!!");
        }
    });
}

I have a simple class to store my objects:

public class DetailList
{
    public string Key { get; set; }
    public string Value { get; set; }
}

And here's my Controller ActionResult:

[HttpPost]
public ActionResult GenerateReport(DetailList[] detailList, DetailList[] detailList2)
{
    return Json(new { status = "Success", message = "Success" }, JsonRequestBehavior.AllowGet);
}

And here's start my problem... A few scenarios:

1) I have multiple option selected in both lists - data posted correctly:

在此处输入图片说明

2) Multiple options in 1st list, 1 option in 2nd list - data posted correctly

在此处输入图片说明

3) 1 option in 1st list, 1 option in 2nd list - First array is null, but the second array posted correctly:

在此处输入图片说明

I have no idea why is that happening? I collect both my arrays absolutely the same way and I post it the same way, but for some reasons, it posted differently. I checked in Firefox debugger and I see that all data has collected just fine. Both result and result2 has data, even with 1 item...

Anyone, please help, what am I doing wrong here?

Got it to work.

The problem is that MVC doesn't like when you have multiple parameters for a POST, at least not by default in MVC 4. It expects that all of your POST data will be sent as one object.

Here are the changes I made to your code.

Add the following class:

public class GenerateReportViewModel
{
    public DetailList[] ListA { get; set; }
    public DetailList[] ListB { get; set; }
}

Change your action method signature:

[HttpPost]
public ActionResult GenerateReport(GenerateReportViewModel viewModel)
{
    return Json(new { status = "Success", message = "Success" }, JsonRequestBehavior.AllowGet);
}

Change your CollectPostData JavaScript function:

function CollectPostData(result, result2) {
    // Post collected data to the action
    $.ajax({
        url: "/Home/GenerateReport",
        type: "POST",
        data: JSON.stringify({
            ListA: result,
            ListB: result2
        }),
        dataType: "json",
        contentType: 'application/json; charset=utf-8',
        success: function (data) {
            if (data.status == "Success") {
                alert(data.message);
            } else {
                alert("Error occurs on the Database level!");
            }
        },
        error: function () {
            alert("An error has occurred!!!");
        }
    });
}

MVC 5 seems to have made some changes that allow you be more flexible in the patterns you choose, which is why I wasn't able to reproduce it there. Generally, it's easier to manage your POST data if it's all in one object anyway. Your action method will have fewer parameters (one).

Here's another similar SO question that may provide more insight:

Post multiple parameters to MVC Controller using C#

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM