React Hooks与ASP.NET Core API嵌套数据提交报Error 400
问题分析与解决方案
核心错误点
1. 表单值绑定错误
你的orders和expensesses是数组类型,但表单里直接用trackings.orders.orderNo、trackings.expensesses.petrol这种方式取值,这是错误的——数组必须通过索引访问元素,比如trackings.orders[0].orderNo。这种错误会导致表单无法正确读取/设置值,甚至引发渲染异常。
2. onChange函数无法处理嵌套属性
当前的onInputChange只能更新顶层属性(比如trackingDate),对于嵌套在数组对象里的属性(如orderNo、petrol),无法正确更新状态。因为你直接给trackings添加[e.target.name]属性,而这些属性实际属于数组里的子对象。
3. 数据类型不匹配
API定义里的orderNo、ordertotal、paymentId、driverId、petrol、service都是数字类型,但你在React里初始值设为空字符串,提交时如果没有转换类型,会把字符串传给后端,导致模型验证失败,返回400错误。
修正步骤
步骤1:修复表单值绑定
修改所有嵌套属性的value绑定,使用数组索引访问,同时给onChange传递目标数组和索引参数:
// 订单编号输入框示例 <input type={"text"} className="form-control" placeholder="Enter Order No" name="orderNo" value={trackings.orders[0].orderNo} onChange={(e) => onInputChange(e, 'orders', 0)} /> // 汽油费用输入框示例 <input type={"text"} className="form-control" placeholder="Enter Petrol Total" name="petrol" value={trackings.expensesses[0].petrol} onChange={(e) => onInputChange(e, 'expensesses', 0)} /> // 顶层属性(trackingDate)单独处理 <input type={"date"} className="form-control" placeholder="Enter Date" name="trackingDate" value={trackings.trackingDate} onChange={(e) => onTopInputChange(e)} />
所有涉及orders、expensesses子属性的输入框、下拉框都要做同样修改。
步骤2:重写onChange函数,支持嵌套属性与类型转换
更新状态处理函数,区分顶层属性和嵌套数组属性,同时自动转换数字类型:
// 处理顶层属性(如trackingDate) const onTopInputChange = (e) => { const { name, value } = e.target; setTracking(prev => ({...prev, [name]: value})); }; // 处理嵌套在数组中的子属性 const onInputChange = (e, targetArray, index) => { const { name, value } = e.target; // 自动将指定属性转为数字,空值保留为空字符串 const processedValue = ['orderNo', 'ordertotal', 'paymentId', 'driverId', 'petrol', 'service'].includes(name) ? (value === '' ? '' : Number(value)) : value; setTracking(prevState => { const newState = {...prevState}; // 复制目标数组元素并更新指定属性 newState[targetArray][index] = { ...newState[targetArray][index], [name]: processedValue }; return newState; }); };
步骤3:提交前统一处理数据格式
在onSubmit中补全空值的默认数字,确保提交数据完全匹配API要求:
const onSubmit = async (e) => { e.preventDefault(); // 处理空字符串为默认数字(可根据后端要求调整) const submitData = { ...trackings, orders: trackings.orders.map(order => ({ ...order, orderNo: order.orderNo === '' ? 0 : order.orderNo, ordertotal: order.ordertotal === '' ? 0 : order.ordertotal, paymentId: order.paymentId === '' ? 0 : order.paymentId, driverId: order.driverId === '' ? 0 : order.driverId })), expensesses: trackings.expensesses.map(expense => ({ ...expense, petrol: expense.petrol === '' ? 0 : expense.petrol, service: expense.service === '' ? 0 : expense.service })) }; // 可先打印数据对比API格式 console.log(submitData); await axios.post('https://localhost:7139/api/Trackings', submitData); navigate("/AllTrackings"); };
内容的提问来源于stack exchange,提问作者Ibrahim Al-Habian
相关产品推荐
相关产品推荐

