You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET非Core+EF+React提交后Checkbox参数值为null问题排查

ASP.NET非Core + React 参数接收为Null问题排查与修复

项目环境

  • ASP.NET(非Core版本)
  • Entity Framework
  • React.js

后端控制器Edit方法代码

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "UserID,UserName,UserPW,UserLoc,LngID,DictionaryChange,DateEtry,EntryBy,UserEnabled,UserDept,UpdateBy,UpdateDate,UserSafeBox,MainMenuBGColor,SubMenuBGColor,MainMenuFont,SubMenuFont,MainMenuForeColor,SubMenuForeColor,MainlblBGCol,SublblBGCol,CheckboxSelections,ModifiedCheckboxSelections")] tblUserInfo tblUserInfo, string CheckboxSelections, string ModifiedCheckboxSelections)
{
    Console.WriteLine($"Checkbox Selections: {CheckboxSelections}");

    if (ModelState.IsValid)
    {
        try
        {
            db.Entry(tblUserInfo).State = EntityState.Modified;
            db.SaveChanges();

            // Check if CheckboxSelections is not null
            if (!string.IsNullOrEmpty(CheckboxSelections))
            {
                // Convert the comma-separated string to an array
                var selectionsArray = CheckboxSelections.Split(',');

                // Remove unchecked checkboxes from tblUserMainForms
                var uncheckedMainForms = db.tblUserMainForms
                        .Where(u => u.UserID == tblUserInfo.UserID && selectionsArray.Contains(u.MformNm))
                        .ToList();

                foreach (var uncheckedMainForm in uncheckedMainForms)
                {
                    db.tblUserMainForms.Remove(uncheckedMainForm);
                }

                // Remove unchecked checkboxes from tblUserSubMenus
                var uncheckedSubMenus = db.tblUserSubMenus
                        .Where(u => u.UserID == tblUserInfo.UserID && selectionsArray.Contains(u.subFrmNm))
                        .ToList();

                foreach (var uncheckedSubMenu in uncheckedSubMenus)
                {
                    db.tblUserSubMenus.Remove(uncheckedSubMenu);
                }

                // Process CheckboxSelections (for new selections)
                foreach (var newSelection in selectionsArray)
                {
                    if (!db.tblUserMainForms.Any(u => u.UserID == tblUserInfo.UserID && u.MformNm == newSelection))
                    {
                        // Checkbox is the first from any select item, save to tblUserMainForm
                        tblUserMainForm userMainForm = new tblUserMainForm
                            {
                                UserID = tblUserInfo.UserID,
                                MformNm = newSelection
                            };

                        db.tblUserMainForms.Add(userMainForm);
                    }
                    else if (!db.tblUserSubMenus.Any(u => u.UserID == tblUserInfo.UserID && u.subFrmNm == newSelection))
                    {
                        // Checkbox is not the first, save to tblUserSubMenu
                        tblUserSubMenu userSubMenu = new tblUserSubMenu
                            {
                                UserID = tblUserInfo.UserID,
                                subFrmNm = newSelection
                            };
                        db.tblUserSubMenus.Add(userSubMenu);
                    }
                }

                // Process ModifiedCheckboxSelections
                if (!string.IsNullOrEmpty(ModifiedCheckboxSelections))
                {
                    var modifiedSelectionsArray = JsonConvert.DeserializeObject<List<string>>(ModifiedCheckboxSelections);

                    // Handle the modified selections as needed
                }

                db.SaveChanges();
            }

            return RedirectToAction("Index");
        }
        catch (Exception ex)
        {
            // Log the exception for debugging
            Console.WriteLine($"Exception: {ex.Message}");
            // You might want to handle the exception differently, e.g., return a custom error view
            return View("Error");
        }
    }

    return View(tblUserInfo);
}

React组件SelectMenu.jsx的handleSubmit方法代码

handleSubmit = async (event) => {
     event.preventDefault();

     const { checkboxSelections, modifiedCheckboxSelections } = this.state;

     // Debug: Check if data is correctly populated
     console.log("Selected Checkboxes:", checkboxSelections);
     console.log("Modified Checkboxes:", modifiedCheckboxSelections);

     const formData = new FormData(document.forms[0]);

     // Append UserID
     formData.append('UserID', document.getElementById("UserID").value);

     // Append CheckboxSelections as a comma-separated string
     formData.append('CheckboxSelections', checkboxSelections.join(','));

     // Append ModifiedCheckboxSelections as JSON string
     formData.append('ModifiedCheckboxSelections', JSON.stringify(modifiedCheckboxSelections));

     // Log FormData content
     for (var pair of formData.entries()) {
         console.log(pair[0] + ', ' + pair[1]);
     }

     try {
         const response = await fetch("/UserInfoForm/edit", {
                    method: 'POST',
                    body: formData,
         });

         if (response.ok) {
             console.log('Form submitted successfully');
         } else {
             console.error('Form submission failed');
         }
     } catch (error) {
         console.error('Error:', error);
     }
 };

问题描述

点击前端提交按钮时,CheckboxSelections和ModifiedCheckboxSelections在前端控制台显示有值,但后端控制器接收时这两个参数变为null。

原因分析

  1. 参数命名冲突:控制器方法的tblUserInfo模型通过[Bind]包含了CheckboxSelections和ModifiedCheckboxSelections,同时方法又定义了同名的独立参数。ASP.NET模型绑定会优先填充模型属性,导致独立参数无法获取值。如果tblUserInfo实体类中没有这两个属性,[Bind]配置还会引发模型绑定错误,进一步导致参数值丢失。
  2. AntiForgeryToken缺失:前端fetch请求未携带__RequestVerificationToken,但控制器标注了[ValidateAntiForgeryToken]特性,可能导致请求被拦截或模型绑定逻辑异常。

修复方案

方案1:解决参数命名冲突

移除方法中的独立参数,直接从Request.Form获取提交的值,同时调整[Bind]配置(如果实体类无对应属性则移除相关字段):

[HttpPost]
[ValidateAntiForgeryToken]
// 若tblUserInfo无CheckboxSelections/ModifiedCheckboxSelections属性,从Bind中移除这两个字段
public ActionResult Edit([Bind(Include = "UserID,UserName,UserPW,UserLoc,LngID,DictionaryChange,DateEtry,EntryBy,UserEnabled,UserDept,UpdateBy,UpdateDate,UserSafeBox,MainMenuBGColor,SubMenuBGColor,MainMenuFont,SubMenuFont,MainMenuForeColor,SubMenuForeColor,MainlblBGCol,SublblBGCol")] tblUserInfo tblUserInfo)
{
    // 直接从Request.Form读取参数
    var checkboxSelections = Request.Form["CheckboxSelections"];
    var modifiedCheckboxSelections = Request.Form["ModifiedCheckboxSelections"];

    Console.WriteLine($"Checkbox Selections: {checkboxSelections}");

    // 后续逻辑保持不变,替换原参数为上述变量
    if (!string.IsNullOrEmpty(checkboxSelections))
    {
        var selectionsArray = checkboxSelections.Split(',');
        // ... 原有处理逻辑
    }

    if (!string.IsNullOrEmpty(modifiedCheckboxSelections))
    {
        var modifiedSelectionsArray = JsonConvert.DeserializeObject<List<string>>(modifiedCheckboxSelections);
        // ... 原有处理逻辑
    }

    // ... 其他代码
}

方案2:前端添加AntiForgeryToken

在React的handleSubmit方法中,获取页面上的验证令牌并添加到FormData中:

handleSubmit = async (event) => {
    event.preventDefault();

    const { checkboxSelections, modifiedCheckboxSelections } = this.state;

    console.log("Selected Checkboxes:", checkboxSelections);
    console.log("Modified Checkboxes:", modifiedCheckboxSelections);

    const formData = new FormData(document.forms[0]);

    // 获取并添加AntiForgeryToken
    const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
    formData.append('__RequestVerificationToken', token);

    // Append UserID
    formData.append('UserID', document.getElementById("UserID").value);

    // Append CheckboxSelections as a comma-separated string
    formData.append('CheckboxSelections', checkboxSelections.join(','));

    // Append ModifiedCheckboxSelections as JSON string
    formData.append('ModifiedCheckboxSelections', JSON.stringify(modifiedCheckboxSelections));

    for (var pair of formData.entries()) {
        console.log(pair[0] + ', ' + pair[1]);
    }

    try {
        const response = await fetch("/UserInfoForm/edit", {
            method: 'POST',
            body: formData,
        });

        if (response.ok) {
            console.log('Form submitted successfully');
        } else {
            console.error('Form submission failed');
        }
    } catch (error) {
        console.error('Error:', error);
    }
};

方案3:调整模型绑定逻辑(可选)

如果需要保留独立参数,确保[Bind]中不包含这两个字段,避免绑定冲突:

// Bind列表中移除CheckboxSelections和ModifiedCheckboxSelections
[Bind(Include = "UserID,UserName,UserPW,UserLoc,LngID,DictionaryChange,DateEtry,EntryBy,UserEnabled,UserDept,UpdateBy,UpdateDate,UserSafeBox,MainMenuBGColor,SubMenuBGColor,MainMenuFont,SubMenuFont,MainMenuForeColor,SubMenuForeColor,MainlblBGCol,SublblBGCol")]

内容的提问来源于stack exchange,提问作者alkhaldy omran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:30:56