dafie
dafie

Reputation: 1169

string array is not properly projected when passing with ajax

Using ajax I want to pass 2 objects: string[] and Options to my controller. The problem is that every time string[] in controller scope is set to null.

Thats js code:

$("#exportCsv").click(function () {
    var checkboxes = $('.TableChBox:checkbox:checked');
    var allIds = [];
    for (var i = 0, n = checkboxes.length; i < n; ++i) {
        var el = checkboxes[i];
        if (el.id) {
            allIds.push(el.id);
        }
    }
    console.log(allIds); // it prints ["RId1604678", "RId1604679"]
    
    var form = $('#SearchForm').serialize();

    $.ajax({
        url: '@Url.Action("ExportToCsv", "Bank")',
        type: 'POST',
        data: JSON.stringify({
            ids: allIds,
            options: form
        }),

        dataType: 'json',
        error: function (xhr) {
            alert('Error: ' + xhr.statusText);
        },
        async: true,
    });
});

And thats c# code:

public void ExportToCsv(string[] ids, Options options)
{
    // ids is null here
    // options is not null
}

When I use debugger I can see, that options is successfully filled, but ids is null. Why does that happen?

Edit 1

As someone suggested I should Add contentType. So I added:

url: '@Url.Action("ExportToCsv", "Bank")',
type: 'POST',
contentType: "application/json; charset=utf-8",

And still - ids is not null, but options is.

Edit 2

Someone suggested to change two parameters in function to one. So I changed my code to:

part of controller

public class ExportModel
{
    [JsonProperty(PropertyName = "one")]
    public string One { get; set; }

    [JsonProperty(PropertyName = "two")]
    public string Two { get; set; }
}

[System.Web.Mvc.HttpPost]
public void ExportToCsv([System.Web.Http.FromBody] ExportModel model)
{
    //model.One is null
    //model.Two is null
}

part of js code

data: JSON.stringify({
    one: "foo",
    two: "bar"
}),

And even with that simple example with two strings it is not working.

Upvotes: 0

Views: 58

Answers (2)

Ramesh Malviya
Ramesh Malviya

Reputation: 62

You should use list of string instead of array & try.

public List<string> Ids {get;set;}

Upvotes: 0

ProgrammingLlama
ProgrammingLlama

Reputation: 38850

In your controller method you should declare it as accepting a model like so:

public void ExportToCsv(ExportModel model)
{

}

And then define your model like so:

public class ExportModel
{
    [JsonProperty(PropertyName = "ids")]
    public string[] Ids {get;set;}

    [JsonProperty(PropertyName = "options")]
    public Options Options {get;set;}
}

As patilprashant6792 pointed out, your ajax request is missing the content type, so you should replace it with this:

$("#exportCsv").click(function () {
    var checkboxes = $('.TableChBox:checkbox:checked');
    var allIds = [];
    for (var i = 0, n = checkboxes.length; i < n; ++i) {
        var el = checkboxes[i];
        if (el.id) {
            allIds.push(el.id);
        }
    }
    console.log(allIds); // it prints ["RId1604678", "RId1604679"]

    var form = $('#SearchForm').serialize();

    $.ajax({
        url: '@Url.Action("ExportToCsv", "Bank")',
        type: 'POST',
        data: JSON.stringify({
            ids: allIds,
            options: form
        }),
        contentType: 'application/json',
        dataType: 'json',
        error: function (xhr) {
            alert('Error: ' + xhr.statusText);
        },
        async: true,
    });
});

If you don't declare the content type, it will default to application/x-www-form-urlencoded; charset=UTF-8

Upvotes: 1

Related Questions