1

The Json I wish to pass into an MVC 5 controller is as follows:

var searchInputs = { "Id": [ "1", "2" ] }; 

As you can see, It is just an array of strings called Id.

I have created a class which should receive this array.

public class SearchList
{
    public SearchList()
    {
        Id = new List<string>();
    }
    public List<string> Id { get; set; }
}

The controller is defined as:

[HttpPost]
public FilePathResult DownloadSelectedPDF(SearchList data)
{
...
}

No errors are thrown, but the controller does not get the data, but returns a zero collection.

As per request, I have added the Ajax call.

$.ajax({
            url: url,
            method: 'POST',
            dataType: "json",
            data: data,
            success: function (result) {
                console.log();
            if (result.Success) {
                    console.log("ajax: result successful");

                    if (result.SuccessMessage !== null)
                        showSuccess(result.SuccessMessage);

                    successCallBack(result.Data);
                } else {
                    console.warn("ajax: result unsuccessful");
                    showError(result.ErrorMessage);
                    failCallBack(result.ErrorMessage);
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                if (!supressWaitingPopup)
                    waitingModal(false);

                console.warn("ajax error");
                showError(errorThrown);

                failCallBack(errorThrown);
            }
        });

Where the data is the searchInputs varaiable.

UPDATE:

The searchInput can have multiples so I should have defined it as:

var searchInputs = { "Id": [ "1", "2", ... ] };

FURTHER UPDATE:

I have used the ajax params suggested, both together and separately.

Using the same ajax call, if these params are present, then a call using this structure fails:

this.JsonData = {
            "__RequestVerificationToken": $('input[name=__RequestVerificationToken]').val(),
            "searchMode": 
                {
                    "mode": Number(mode.val()),
                    "pageSize": Number(pagesize.val()) || 5,                   //Initial Page Size Set Here
                    "pageNumber": Number(pagenumber.val()) || 1,                //Start on page one
                    "sortField": sortfield.val() || "PODRef",
                    "sortDirection": sortdirection.val() || "desc"
                },
            "searchData": 
                {
                    "Compare": Number(StdComparison.val()),
                    "SearchTextFrom": searchText.val(),
                    "SearchTextTo": searchTextTo.val()
                }

This is true if I JSON.stringify the data or not.

gilesrpa
  • 969
  • 1
  • 12
  • 35
  • Show your ajax call –  Feb 17 '17 at 11:25
  • 1
    Is that supposed to be `data: searchInputs.`? –  Feb 17 '17 at 11:30
  • Either stringify the data (`JSON.strngify(searchInputs`) and set the `contentType: 'application/json; charset=utf-8',` option or use `traditional: true` –  Feb 17 '17 at 11:33
  • Stephen, that just confused the issue more – gilesrpa Feb 17 '17 at 11:51
  • Sorry, did not understand your comment. It needs to be `data: JSON.stringify({ Id: [ '1, '2' ] }),` with `contentType: 'application/json; charset=utf-8'` OR `data: { Id: [ '1, '2' ] }` with `traditional: true,` (note the second option will not work with the code in your edit, but then again you have not shown what that posts back to so not sure why you have added it) –  Feb 17 '17 at 11:56
  • Sorry, not trying to confuse. I use a global javascript class for calling ajax. What I was trying to say is that if I use any of the parameters you supplied, it causes other calls within the application that use complex objects to fail when ajax is called. Once I remove the parameters, these calls work again. – gilesrpa Feb 17 '17 at 12:08
  • Using `JSON.stringify()` with `contentType: 'application/json; charset=utf-8'` will work for the example in your edit assuming the data correctly matches up with the model your binding to. –  Feb 17 '17 at 12:14

3 Answers3

0
   var obj = { pVar: val, pVar1: val1 };
        $.ajax({
            type: "POST",
            url: '@Url.Action("DownloadSelectedPDF", "Controller")',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(obj),
            dataType: 'json',
            success: function (data) {  
            $("#divID").html(data.Html);

            },
            error: errorFunc
        });


 [HttpPost]
 public FilePathResult DownloadSelectedPDF(string pVar, string pVar1)
 {
 return Json(new { Html = "someStuff")});
 }
  • This is fine when I only have two values in the array, but I should have defined the array to contain a variable amount of values. I have updated the post to reflect this – gilesrpa Feb 17 '17 at 11:33
0

Ok, I have found a solution that enables my NOT to have to add the parameters of contentType or tradional to the ajax call.

var searchInputs = { "Id": [ "1", "2", ... ] };

This is an Array of string objects, so what I have done is changed it to:

var postData = { Id: _self.Array }

Then all that was needed was to change the parameter on the controller to

List<string> Id

Note: Parameter name matches the name given for the array

That's it. I know that this solution is not Json based, but it works and gets me out of a hole.

Many thanks to all that looked at this and special thanks to d.popov for this contribution: how-can-i-post-an-array-of-string-to-asp-net-mvc-controller-without-a-form

Community
  • 1
  • 1
gilesrpa
  • 969
  • 1
  • 12
  • 35
0

Have you tried this?

[HttpPost]
public FilePathResult DownloadSelectedPDF([FromBody]SearchList data)
{
...
}

It would be worth adding this to your ajax call as well:

contentType: "application/json; charset=utf-8",

I use this in my controllers and I receive an initialized object (some properties are null if the sender does not include the "property": "value" pair).

I am not sure how it'll deal with List<string> though. If that property comes null maybe try changing it to string[] just to see if it works.

André Mantas
  • 482
  • 4
  • 13