为什么我发布的数据在这个AJAX调用的Controller目标中为null

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

本文关键字:目标 调用 Controller null AJAX 数据 为什么      更新时间:2023-09-26

我已经根据logan filley的答案对我的AJAX调用进行了建模(并非双关语),这似乎是合理的,而且可能有效。这是我在视图中的jquery:

$("#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()

这是我的型号:

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; }
    }
}

和控制器(目前显然是超斯巴达式的):

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 });
    }
}

我正在到达控制器中的断点(在"string s=model.unitConfigVals.unit;"行上),但它抛出了一个异常,因为"model"的值为null。为什么?我的AJAX调用出错了吗,或者。。。?!?

更新

我把jquery改成了这个(更改了布尔赋值并添加了分号):

   $("#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 })
    });
});

但是控制器仍然被传递一个空模型。

更新2

现在我把"attr('checked')"改为"is('checked')",但没有区别。。。

更新3

控制器中的"模型"为空:

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

当AJAX调用是这样的时候:

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

当AJAX调用是这样的时候:

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

这个:

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

我需要"async:true"吗?我不会在我的(工作)GET AJAX调用中使用它。同样,我需要"cache:false"吗?我确实在那些正在工作的GET AJAX调用中使用它。。。

更新4

即使我只提供一些虚假的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()
};

它仍然像以前一样在控制器null处结束。

然后,抓住救命稻草,我甚至把布尔值用单引号("true"answers"false")括起来,但这也(可能是可以预见的)没有什么区别。

更新5

对于未来的几代人来说,这就是有效的AJAX:

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

由于返回的值用于嵌套的UnitConfigVals类(而不是SaveConfigModel,因此控制器方法应该是

public ActionResult PostUnitConfig(SaveConfigModel.UnitConfigVals model)

ajax data选项需要是

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

或者,您可以保留当前的控制器方法并使用

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

尽管在这里使用嵌套类似乎有点奇怪。

您的初始代码的一些其他问题

  1. $('#ckbx_produceusage').checked将返回undefined需要是$('#ckbx_produceusage').is(':checked')返回truefalse
  2. 由于recipientsList<string>,因此需要recipients: [ 'someValue', 'anotherValue', etc ]

然而,构建json数据的所有这些代码并不是真正必要的,如果您的视图是使用强类型HtmlHelper方法正确生成的,那么您的ajax调用可以像一样简单

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