0

I have a object in my javascript with a object array inside it. I want to send it to my controller via a ajax call. But my list never seems to get populated in my controller. I make my machineList object as following:

 var machineList = JSON.stringify({ 'machineList': objects.machines });

Console.log of this object

{"machineList":[{"Id":1,"Labour":"Hard","EnlistedMachine":"BEXTE","Type":"dz","Identifier":"ddd","IdentifierCode":"ddd"},{"Id":2,"Labour":"Easy","EnlistedMachine":"BEXTEss","Type":"dz","Identifier":null,"IdentifierCode":null}]}

My data object that gets send looks like this

 var data = {

        SalesPrice: $("#SalesPrice").val(),
        machineList: machineList

    };

Ajax call:

   $.ajax({
        url: currenturl + "/MyXmlAction",
        data: data,
        dataType: "json",
        type: "GET",
        contentType: 'application/json; charset=utf-8', //define a contentType of your request
        cache: false,
        success: function (type) {
            // data is your result from controller
            if (type.success) {
                XML = type.json;

            }
        },
        error: function (xhr) {
            alert('error');
        }
    });

My viewmodel looks like:

    public class ContractViewModel
    {
  public string SalesPrice { get; set; }
  List<MachineListDto> machineList = new List<MachineListDto>();
     }

My controllerMethod looks like:

public ActionResult MyXmlAction(ContractViewModel data)
{
    //Code
    return Json(new { success = true, data }, JsonRequestBehavior.AllowGet);
}

MachineListDto

    public class MachineListDto
    {
        public int Id { get; set; }

        public string EnlistedMachine { get; set; }

        public string Type { get; set; }

        public string Labour { get; set; }

        public string Identifier { get; set; }

        public string IdentifierCode { get; set; }
    }
}

Data object after changes by Tetsuya implemented

{"SalesPrice":"1000","machineList":[{"Id":1,"Labour":"Hard","EnlistedMachine":"BEXTE","Type":"dz","Identifier":"ddd","IdentifierCode":"ddd"},{"Id":2,"Labour":"Easy","EnlistedMachine":"BEXTEss","Type":"dz","Identifier":null,"IdentifierCode":null}]}

I tried doing the same I saw in the following post: Passing ListObject to controller

7
  • 1
    It needs to be var data = JSON.stringify({ SalesPrice: $("#SalesPrice").val(), machineList: objects.machines }); (you stringify the whole object, not parts of it ). And your model must have properties, not fields - public List<MachineListDto> machineList { get; set; }
    – user3559349
    Commented Nov 9, 2018 at 9:27
  • create one array varaible and push the data to array. Commented Nov 9, 2018 at 9:29
  • @StephenMuecke when I try to do as you suggested no data gets populated even SalesPrice who got populated before. Commented Nov 9, 2018 at 9:38
  • Just noticed you have type: "GET", - it must be a POST (a GET has no body)
    – user3559349
    Commented Nov 9, 2018 at 9:40
  • Maybe a stupid question. But the porpose of my call is to post data and get a XML document back after the post. Should I in this case not do a GET? Since I'm posting data to instantly get a reply back. I can see my data arrives in my controller even while I'm doing a Get ajax call. Is this just bad practice? Commented Nov 9, 2018 at 9:44

2 Answers 2

2

You have 3 major issues on the code:

1) The contentType in AJAX call set as application/json; charset=utf-8, means that the passed data must be a JSON string, but you're passing an object instead. You need to send both objects as JSON string by putting JSON.stringify() on entire object definition:

var data = JSON.stringify({
    SalesPrice: $("#SalesPrice").val(),
    machineList: objects.machines
});

2) The declaration of List<MachineListDto> machineList = new List<MachineListDto>(); defines a field, not a property which necessary for serialization. It must be declared as property:

public class ContractViewModel
{
    public string SalesPrice { get; set; }
    List<MachineListDto> machineList { get; set; } // define as property
}

3) The type of AJAX callback is set as GET, which means it will send as query string which is not recommended to pass collection objects. You need to use type: 'POST' in AJAX callback and set [HttpPost] attribute on the controller action:

AJAX

$.ajax({
    url: currenturl + "/MyXmlAction",
    data: data,
    dataType: "json",
    type: "POST", // use POST request
    contentType: 'application/json; charset=utf-8', //define a contentType of your request
    cache: false,
    success: function (type) {
        // data is your result from controller
        if (type.success) {
            XML = type.json;

        }
    },
    error: function (xhr) {
        alert('error');
    }
});

Controller action

[HttpPost]
public ActionResult MyXmlAction(ContractViewModel data)
{
    // do something
    return Json(new { success = true, data }, JsonRequestBehavior.AllowGet);
}
6
  • Ok thank you for explanation. Point 2 I just mistyped in my model. But I have a question regarding point 3 why Post should be used in this instance. In my case I'm doing a post to instantly get an XML document back. I can see if even when doing my call as Get my body arrives in my controller. Is this just not done because of best practices? Commented Nov 9, 2018 at 9:47
  • I did everything you told me but my machineList object still arrives as empty in my controller. Maybe I'm doing something wrong? Commented Nov 9, 2018 at 9:51
  • The GET method passing the request as query string, then it potentially exceeds query string limitations. Using POST method to pass collection objects is more recommended because data is included inside request body (see also: What is the difference between POST and GET?). Commented Nov 9, 2018 at 9:51
  • Also I want to know the provided JSON string after changing the code as provided, something may went wrong during serialization to JSON string. Commented Nov 9, 2018 at 10:02
  • Provided the object as Edit on the main Post Commented Nov 9, 2018 at 10:09
-1
var pushSalesprice = [];
var Machinelist_data = [];
pushSalesprice.push($("#SalesPrice").val());
Machinelist_data.push(machineList);
var data = {
  SalesPrice: pushSalesprice ,
  machineList: Machinelist_data 
};
1
  • 7
    Please consider adding some clarification Commented Nov 9, 2018 at 10:49

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.