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

Pedro Lopes
  • 353
  • 1
  • 5
  • 16
  • 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 machineList { get; set; }` –  Nov 09 '18 at 09:27
  • create one array varaible and push the data to array. – sukumar2267 Nov 09 '18 at 09:29
  • @StephenMuecke when I try to do as you suggested no data gets populated even SalesPrice who got populated before. – Pedro Lopes Nov 09 '18 at 09:38
  • Just noticed you have `type: "GET",` - it must be a POST (a GET has no body) –  Nov 09 '18 at 09: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? – Pedro Lopes Nov 09 '18 at 09:44
  • If you want to make a GET, then you would need `data{ machineList[0].SomeProperty: 'someValue', machineList[1].SomeProperty: 'someValue', .... }` etc and delete the `contentType` option (but passing a collection in a url risks exceeding the query string limit and throwing an exception –  Nov 09 '18 at 09:47
  • @StephenMuecke as always Stephen thank you for the explanation. – Pedro Lopes Nov 09 '18 at 09:53

2 Answers2

1

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);
}
Tetsuya Yamamoto
  • 21,982
  • 5
  • 34
  • 53
  • 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? – Pedro Lopes Nov 09 '18 at 09:47
  • I did everything you told me but my machineList object still arrives as empty in my controller. Maybe I'm doing something wrong? – Pedro Lopes Nov 09 '18 at 09: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?](https://stackoverflow.com/questions/3477333/what-is-the-difference-between-post-and-get)). – Tetsuya Yamamoto Nov 09 '18 at 09: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. – Tetsuya Yamamoto Nov 09 '18 at 10:02
  • Provided the object as Edit on the main Post – Pedro Lopes Nov 09 '18 at 10:09
  • Could this be because of the contentype in my request? – Pedro Lopes Nov 09 '18 at 10:50
-1
var pushSalesprice = [];
var Machinelist_data = [];
pushSalesprice.push($("#SalesPrice").val());
Machinelist_data.push(machineList);
var data = {
  SalesPrice: pushSalesprice ,
  machineList: Machinelist_data 
};
Adam Cooper
  • 6,436
  • 1
  • 25
  • 47
sukumar2267
  • 130
  • 6