控制器在 ASP.NET Core 6.0 MVC 中从 Ajax 接收 null

问题描述 投票:0回答:2

我正在编写一个捕获变量数据列表的程序,我试图将其通过 jQuery 传递到 ASP.NET Core 6.0 MVC 控制器。

这是数据模型:

namespace RTS_RecruiterSystem.Models.ViewModels
{
    public class ScreeningViewModel
    {
        public int CandidateId { get; set; }
        public string TypeRequirement { get; set; } = string.Empty;
        public int ScreeningId { get; set; }
        public bool SelectedOption { get; set; }
    }
}

这是表单所在视图的部分

<form id="frmScreeningProcess" method="post" enctype="multipart/form-data" autocomplete="off">
    <div class="mt-4">
        <!-- Agregar una barra de botones Guardar/Limpiar/Regresar para ventana Modal -->
        <div class="row">
            <div class="col-md-3 offset-md-9 d-flex justify-content-end">
                @*<button type="submit" name="currentTab" value="screening-tab-pane" id="btnSaveScreening" class="btn btn-primary btn-md" title="Save Form"><i class="fa-solid fa-floppy-disk pe-2"></i> Save Result</button>*@
                <button type="submit" name="currentTab" value="screening-tab" id="btnSaveScreening" class="btn btn-primary btn-md" title="Save Form"><i class="fa-solid fa-floppy-disk pe-2"></i> Save Result</button>
            </div>
        </div>
        <hr />
        <div class="row">
            <div class="col-md-6">
                <div class="row">
                    <h4><i class="far fa-circle-check pe-2"></i> Must to have</h4>
                    <div class="col-md-12">
                        <hr class="blue-separator" />
                        <div class="table table-responsive">
                            <div class="scroll-container" style="max-height: 400px; overflow-y: auto; border: 1px solid #ccc;">
                                <table id="MustToHaveTable" class="table table-striped table-hover table-responsive">
                                    <thead class="table-blue-sm">
                                        <tr>
                                            <th>@Html.DisplayNameFor(m => m.ListCandidateScrViewModel[0].ScreeningId)</th>
                                            <th>@Html.DisplayNameFor(m => m.ListCandidateScrViewModel[0].ScreeningName)</th>
                                            <th>@Html.DisplayNameFor(m => m.ListCandidateScrViewModel[0].ScreeningValue)</th>
                                        </tr>
                                    </thead>
                                    <tbody class="dataTableBody-md">
                                    @{
                                        for (int i = 0; i < Model.ListCandidateScrViewModel.Count; i++)
                                        {
                                            idYes = "ListCandidateScrViewModel_" + i + "__SelectedOption";
                                            idNo = "ListCandidateScrViewModel_" + i + "__SelectedOptionNo";
                                    
                                            if (Model.ListCandidateScrViewModel[i].TypeRequirement == "M")
                                            {
                                                <tr id="ListCandidateScreeningViewModel_@i">
                                                    @Html.HiddenFor(m => m.ListCandidateScrViewModel[i].CandidateId, new { @class = "form-control" })
                                                    @Html.HiddenFor(m => m.ListCandidateScrViewModel[i].ScreeningId, new { @class = "form-control" })
                                                    @Html.HiddenFor(m => m.ListCandidateScrViewModel[i].ScreeningName, new { @class = "form-control" })
                                                    @Html.HiddenFor(m => m.ListCandidateScrViewModel[i].TypeRequirement, new { @class = "form-control" })
                                                    <td class="text-center" style="width:10%">@Html.DisplayFor(m => m.ListCandidateScrViewModel[i].ScreeningId)</td>
                                                    <td style="width:65%">@Html.DisplayFor(m => m.ListCandidateScrViewModel[i].ScreeningName)</td>
                                                    <td class="text-center" style="width:25%">
                                                        <div class="col-md-12">
                                                            <div class="form-check form-check-inline">
                                                                <input type="radio" class="form-check-input" asp-for="ListCandidateScrViewModel[i].SelectedOption" value="Yes">
                                                                <label class="form-check-label" for="@idYes">Yes</label>
                                                            </div>
                                                            <div class="form-check form-check-inline">
                                                                <input type="radio" class="form-check-input" asp-for="ListCandidateScrViewModel[i].SelectedOption" id="@idNo" value="No">
                                                                <label class="form-check-label" for="@idNo">No</label>
                                                            </div>
                                                        </div>
                                                    </td>
                                                </tr>
                                            }
                                        }
                                    }
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</form>

这是控制器:

[HttpPost]
public JsonResult SaveScreening(List<ScreeningViewModel> lstScreeningViewModel)
{
    // Acciones
    return Json(new { success = true, message = "Cambios guardados correctamente" });
}

在我的脚本中

$("#frmScreeningProcess").on("submit", function (e) {
    var lstScreeningViewModel = [];

    // Obtener el número de filas en la tabla
    var totalRows = $('#MustToHaveTable tr').length - 1;

    for (i = 0; i < totalRows; i++) {
        var candidateId = parseInt($("#ListCandidateScrViewModel_" + i + "__CandidateId").val());
        var typeRequirement = $("#ListCandidateScrViewModel_" + i + "__TypeRequirement").val();
        var screeningId = parseInt($("#ListCandidateScrViewModel_" + i + "__ScreeningId").val());
        var selectedOption = $("#ListCandidateScrViewModel_" + i + "__SelectedOption").prop("checked");

        lstScreeningViewModel.push({
            CandidateId: candidateId,
            TypeRequirement: typeRequirement,
            ScreeningId: screeningId,
            SelectedOption: selectedOption
        });
    };

    $.ajax({
        type: "POST",
        url: "/Candidate/SaveScreening",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: JSON.stringify({ lstScreeningViewModel: lstScreeningViewModel } ),
        success: function (response) {
            // Maneja la respuesta del servidor
            if (response.success) {
                console.log("Datos actualizados correctamente");
            } else {
                alert("Error al guardar los cambios");
            }
        },
        error: function () {
            alert("Error en la solicitud AJAX");
        }
    });
});

这是将 ajax 发送到控制器的数组:

[
    { "CandiateId": 1, "TypeRequirement": "M", "ScreeninigId": 1, "SelectedOption": true},
    { "CandiateId": 1, "TypeRequirement": "M", "ScreeninigId": 2, "SelectedOption": false },
    { "CandiateId": 1, "TypeRequirement": "M", "ScreeninigId": 3, "SelectedOption": true },
    { "CandiateId": 1, "TypeRequirement": "M", "ScreeninigId": 4, "SelectedOption": false },
    { "CandiateId": 1, "TypeRequirement": "M", "ScreeninigId": 5, "SelectedOption": true },
    { "CandiateId": 1, "TypeRequirement": "M", "ScreeninigId": 6, "SelectedOption": false }
]

问题是我无法让控制器正确接收数据,因为它没有接收到任何内容并且不会产生任何错误。

有什么建议可以解决这个问题吗?

asp.net-core-mvc asp.net-ajax asp.net-core-6.0
2个回答
0
投票

当您在输入参数中定义列表时,无论如何参数值(lstScreeningViewModel)必须有数据,以防这是空值,所以也许您需要在控制器中的 lstScreeningViewModel 之前添加 [FromBody] 属性

[HttpPost]
public JsonResult SaveScreening([FromBody] List<ScreeningViewModel> lstScreeningViewModel)
{
  // Acciones
  return Json(new { success = true, message = "Cambios guardados correctamente" });
}

最后我给你一个建议,使用 Postman 应用程序直接测试你的控制器并单独调试它的前端问题(ajax)。所以调试速度比现在更快!


0
投票

我花了三天时间研究、测试各个论坛的建议、ChatGpt 建议,但我找不到答案,直到我在 stackoverflow 上看到 sonicbabbler 的帖子([.Net Core AJAX Post Null][1])。 那里的问题与我的类似,但我没有使用

List<myModel>
对象,而是使用了
IEnumerable<myModel>
,并且在 ajax 部分中,我只有不同的 datacontentTypedataType 顺序 属性,但在模型中,所有属性都是 string 类型,我进行了更改并且它起作用了。 然而,对我来说,尝试类似的方法却不起作用,这非常令人沮丧,所以我将我的model返回到我最初的方式,到我添加的控制器操作[FromBody],就像这样:

[HttpPost]
public IActionResult SaveScreeningAjax([FromBody] List<ScreeningViewModel> lstScreeningViewModel)
{
    // Acciones
    return Json(new { success = true, message = "Cambios guardados correctamente" });
}

最后 js 文件如下所示:

$("#frmScreeningProcess").on("submit", function (e) {
    var data = [];

    // Obtener el número de filas en la tabla
    var totalRows = $('#MustToHaveTable tr').length - 1;

    for (i = 0; i < totalRows; i++) {
        var candidateId = parseInt($("#ListCandidateScrViewModel_" + i + "__CandidateId").val());
        var typeRequirement = $("#ListCandidateScrViewModel_" + i + "__TypeRequirement").val();
        var screeningId = parseInt($("#ListCandidateScrViewModel_" + i + "__ScreeningId").val());
        var selectedOption = $("#ListCandidateScrViewModel_" + i + "__SelectedOption").prop("checked");

        data.push(
            {
                candidateId: candidateId,
                typeRequirement: typeRequirement,
                screeningId: screeningId,
                selectedOption: selectedOption
            }
        );
    };

    console.log("Array: " + data);
    $.ajax({
        url: "/Candidate/SaveScreeningAjax",
        type: "POST",
        data: JSON.stringify(data),
        contentType: "application/json",
        dataType: "json",

        success: function (response) {
            // Maneja la respuesta del servidor
            if (response.success) {
                // Actualiza la parte específica de la vista
                console.log("Datos actualizados correctamente");
            } else {
                // Maneja cualquier error si es necesario
                alert("Error al guardar los cambios");
            }
        },
        error: function () {
            // Maneja errores de la solicitud AJAX
            alert("Error en la solicitud AJAX");
        }
    });
});

很抱歉,我无法对如何解决该问题给出技术解释,因为我自己不知道是什么解决了该问题,但据我所知,这个问题很常见,我希望这将有助于解决当别人遇到这个问题时。 感谢那些花时间帮助我的人。

© www.soinside.com 2019 - 2024. All rights reserved.