Ajax Post上的数据为空

I'm learning about ajax to make my life a little easier moving forward. I was able to follow an example and get a constant array to POST to my controller normally.

Now that I am trying to get data from an html form, I get a null array in my controller.

using .serialize() I get [0] = "item=teststring1&item=teststring2"

using .serializeArray() I get an array of length 2 (the correct size), with both values null.

I've read about the issues with serializeArray() and how it requires certain tags.

How can I resolve the issue of a null array posting to my controller?

JS

// #EditDate is form id
var data = $('#EditDate').serializeArray();  

        $.ajax({
                url: '@Url.Action("Index", "TrainingDates")',
                type: "POST",
                dataType: "json",
                data: {'dates' : data},
                success: function (result) {
                    alert("success" + result);
                },
                error: function (result) {
                    alert("failure" + result);
                }
        });

        $(element).val('Edit');

HTML

@model List<string>
@{
    ViewBag.Title = "Dates";
}
@using (Html.BeginForm("Index", "TrainingDates", FormMethod.Post, new { @id = "EditDate", @class = "collapse" }))
        {
            foreach (var item in Model)
            {
                <tr>
                    <td>
                        <input type="button" class="btn btn-primary btn-sm" style="width:inherit" onclick="editable('@item', this)" value="Edit">
                    </td>
                    <td>
                            @Html.TextBoxFor(m => item, new { @id = item, name = item, @class = "form-control", @readonly = "readonly" })
                    </td>
                </tr>
            }
        }

Controller

[HttpPost]
public ActionResult Index(List<string> dates)
{
        if(dates != null)
        {
            var json = new { success = true };
            return Json(json);
        }
        return Json(false);
 }

Your action method parameter is a list of strings. So basically for model binding to properly work, you should be sending an array like this from your ajax call

["12-12-2011","10-10-2011"]

Your current code uses jquery serializeArray method which will create an array of items,each with name and value properties. So basically your code is sending something like this in the ajax request.

dates[0][name]:item
dates[0][value]:12-12-2011
dates[1][name]:item
dates[1][value]:10-10-2011

The default model binder cannot map this to a list of strings.

All you need to do is, sending a an array of string(or dates) to server. You may simply use the jQuery map method to create an array from the input field values.

This should work.

var d = $.map($("[name='item']"), function(v, k) {
    return v.value;
});              

$.ajax({
    url: '@Url.Action("Index", "TrainingDates")',
    type: "POST",
    data: JSON.stringify(d),
    contentType: "application/json",
    success: function (result) {
        console.log("success" , result);
    },
    error: function (result) {
        alert("failure" + result);
    }
});

I would also strongly advise to use the correct datatype. If you are dealing with dates, why not use DateTime class instead of string ? DateTime class was created to handle usecases like these :)

[HttpPost]
public ActionResult Index(List<DateTime> dates)
{
  // to do  : return something
}

Your posted data does not match the variable name and data type in your controller. make these minor adjustments: Javascript - remove dataType: "json" and pass data as form-url-encoded directly data: $('#EditDate').serializeArray(). No need to convert to JSON format.

$.ajax({
                url: '@Url.Action("Index", "TrainingDates")',
                type: "POST",
                data: $('#EditDate').serializeArray(),
                success: function (result) {
                    alert("success" + result);
                },
                error: function (result) {
                    alert("failure" + result);
                }
        });

Controller - change variable name "dates" to "item" to matched your JavaScript ajax call.

[HttpPost]
public ActionResult Index(List<string> item)
{
        if(item != null)
        {
            var json = new { success = true };
            return Json(json);
        }
        return Json(false);
 }