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。
原因分析
- 参数命名冲突:控制器方法的
tblUserInfo模型通过[Bind]包含了CheckboxSelections和ModifiedCheckboxSelections,同时方法又定义了同名的独立参数。ASP.NET模型绑定会优先填充模型属性,导致独立参数无法获取值。如果tblUserInfo实体类中没有这两个属性,[Bind]配置还会引发模型绑定错误,进一步导致参数值丢失。 - 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
相关产品推荐
相关产品推荐

