简体   繁体   中英

Why is my posted data null in the Controller target of this AJAX call?

I have modeled (no pun intended) my AJAX call on the answer here from logan filley, which seems sensible and likely to work. This is the jquery I have in the View:

$("#btnSaveConfig").click(function () {

    var saveConfigModel = {
        unit: $('#unitsselect').val(),
        scheduleProduceUsage: $('#ckbx_produceusage').checked,
        scheduleDeliveryPerformance: $('#ckbx_deliveryperformance').checked,
        scheduleFillRate: $('#ckbx_fillratebycustomer_location').checked,
        schedulePriceCompliance: $('#ckbx_pricecompliance').checked,
        // TODO: Finish this by storing add'l emails in an array along with the three on the page; 
        recipients: $('#email1').val(),
        generationDayOfMonth: $('#dayofmonthselect').val(),
        generationOrdinal: $('#ordinalselect').val(),
        generationDayOfWeek: $('#dayofweekselect').val(),
        generationWeekOrMonth: $('#weekormonthselect').val(),
        daterangeFromProduceUsage: $('#produsagefrom').val(),
        daterangeToProduceUsage: $('#produsageto').val(),
        daterangeFromDeliveryPerformance: $('#delperffrom').val(),
        daterangeToDeliveryPerformance: $('#delperfto').val(),
        daterangeFromFillRate: $('#fillratefrom').val(),
        daterangeToFillRate: $('#fillrateto').val(),
        daterangeFromPriceCompliance: $('#pricecompliancefrom').val(),
        daterangeToPriceCompliance: $('#pricecomplianceto').val()
    }

    $.ajax({
        type:"POST",
        url:'@Url.Action("PostUnitConfig", "SaveConfig")', 
        async:true,
        contentType: 'application/json',
        dataType:"json",
        data: JSON.stringify(saveConfigModel)
    });
}); // $("#btnSaveConfig").click()

...and this is my Model:

public class SaveConfigModel
{
    public UnitConfigVals unitConfigVals { get; set; }

    public class UnitConfigVals
    {
        public string unit { get; set; }
        public bool scheduleProduceUsage { get; set; }
        public bool scheduleDeliveryPerformance { get; set; }
        public bool scheduleFillRate { get; set; }
        public bool schedulePriceCompliance { get; set; }
        public List<string> recipients { get; set; }
        public int generationDayOfMonth { get; set; }
        public string generationOrdinal { get; set; }
        public string generationDayOfWeek { get; set; }
        public string generationWeekOrMonth { get; set; }
        public int daterangeFromProduceUsage { get; set; }
        public int daterangeToProduceUsage { get; set; }
        public int daterangeFromDeliveryPerformance { get; set; }
        public int daterangeToDeliveryPerformance { get; set; }
        public int daterangeFromFillRate { get; set; }
        public int daterangeToFillRate { get; set; }
        public int daterangeFromPriceCompliance { get; set; }
        public int daterangeToPriceCompliance { get; set; }
    }
}

...and Controller (obviously ultra-spartan at the moment):

public class SaveConfigController : Controller
{
    public ActionResult PostUnitConfig(SaveConfigModel model) 
    {
        try
        {
            string s = model.unitConfigVals.unit;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return Json(new { success = true });
    }
}

I am reaching the breakpoint in my Controller (on the " string s = model.unitConfigVals.unit; " line), but it throws an exception because the value of "model" is null. Why? Have I got something in my AJAX call wrong, or...?!?

UPDATE

I changed my jquery to this (changed boolean assignments and appended a semicolon):

   $("#btnSaveConfig").click(function() {

      var saveConfigModel = {
        unit: $('#unitsselect').val(),
        scheduleProduceUsage: $('#ckbx_produceusage').attr('checked'),
        scheduleDeliveryPerformance: 
        . . .
    };

    $.ajax({
        type: "POST",
        url: '@Url.Action("PostUnitConfig", "SaveConfig")',
        async: true,
        //contentType: 'application/json',
        dataType: "json",
        data: JSON.stringify({ data: saveConfigModel })
    });
});

...but the Controller is still passed a null model.

UPDATE 2

Now I changed " attr('checked') " to " is('checked') " but no difference...

UPDATE 3

"model" is null here in the Controller:

public class SaveConfigController : Controller
{
    public ActionResult PostUnitConfig(SaveConfigModel model)

...when the AJAX call is like this:

$.ajax({
    type: "POST",
    url: '@Url.Action("PostUnitConfig", "SaveConfig")',
    async: true,
    dataType: "json",
    data: saveConfigModel
});

...and also when the AJAX call is like this:

$.ajax({
    type: "POST",
    url: '@Url.Action("PostUnitConfig", "SaveConfig")',
    async: true,
    data: saveConfigModel
});

...and this:

$.ajax({
    type: "POST",
    url: '@Url.Action("PostUnitConfig", "SaveConfig")',
    async: true,
    contentType: 'application/json',
    dataType: "json",
    data: JSON.stringify({ model: saveConfigModel })
});

Do I need the "async: true"? I don't use that in my (working) GET AJAX calls. Similarly, do I need "cache: false"? I do use that in those working GET AJAX calls...

UPDATE 4

Even when I provide just some bogus vals:

var saveConfigModel = {
    unit: 'Buford', //$('#unitsselect').val(),
    scheduleProduceUsage: true, //$('#ckbx_produceusage').is(':checked'),
    scheduleDeliveryPerformance: false, // $('#ckbx_deliveryperformance').is(':checked'),
    scheduleFillRate: false, //$('#ckbx_fillratebycustomer_location').is('checked'),
    schedulePriceCompliance: false, //$('#ckbx_pricecompliance').is('checked'),
    // TODO: Finish this by storing add'l emails in an array along with the three on the page; might be as easy as declaring an array like this one, and adding to it as necessary
    recipients: 'platypus@whatever.com', // $('#email1').val(),
    generationDayOfMonth: '2nd', //$('#dayofmonthselect').val(),
    generationOrdinal: 'First', //$('#ordinalselect').val(),
    generationDayOfWeek: 'Thursday', // $('#dayofweekselect').val(),
    generationWeekOrMonth: 'month', // $('#weekormonthselect').val(),
    daterangeFromProduceUsage: $('#produsagefrom').val(),
    daterangeToProduceUsage: $('#produsageto').val(),
    daterangeFromDeliveryPerformance: '1', // $('#delperffrom').val(),
    daterangeToDeliveryPerformance: '1', //$('#delperfto').val(),
    daterangeFromFillRate: '1', //$('#fillratefrom').val(),
    daterangeToFillRate: '1', //$('#fillrateto').val(),
    daterangeFromPriceCompliance: '1', //$('#pricecompliancefrom').val(),
    daterangeToPriceCompliance: '1' //$('#pricecomplianceto').val()
};

...it still winds up at the Controller null like forevermore before.

And then, grasping at straws, I even encased the boolean values in single quotes ('true' and 'false'), but that also (probably predictably) made no difference either.

UPDATE 5

For future generations, this is the AJAX that works:

$.ajax({
    type: "POST",
    url: '@Url.Action("PostUnitConfig", "SaveConfig")',
    async: true,
    contentType: 'application/json',
    dataType: "json",
    data: JSON.stringify({ model: saveConfigModel })
});

Since the values you posting back are for your nested UnitConfigVals class (not SaveConfigModel , then you controller method should be

public ActionResult PostUnitConfig(SaveConfigModel.UnitConfigVals model)

and the ajax data option needs to be

data: JSON.stringify({ model: saveConfigModel })

Alternatively you could keep the current controller method and use

data: JSON.stringify({ model: { unitConfigVals: saveConfigModel }})

although it seems a little odd that you using a nested class here.

A few other issues with your initial code

  1. $('#ckbx_produceusage').checked will return undefined , and it needs to be $('#ckbx_produceusage').is(':checked') which will return true or false
  2. Since recipients is List<string> , it will need to be recipients: [ 'someValue', 'anotherValue', etc ]

However all this code to build you json data not really necessary, and if your view is generated correctly using the strongly typed HtmlHelper methods, then your ajax call can be as simple as

$.ajax({
    type:"POST",
    url:'@Url.Action("PostUnitConfig", "SaveConfig")',
    dataType: "json",
    data: $('form').serialize(),
    success: function(data) {
        // do something
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM