无法通过JSON将DateTime值正确传递至ASP.NET CRUD接口
兑换券兑换功能日期写入异常问题排查与修复
问题概述
后端ASP.NET API实现了兑换券CRUD接口,通过Swagger测试时,传入以下JSON参数可正常完成兑换:
{ "dateAssigned": "2024-01-17T12:41:10.864Z" }
但前端React调用接口时,ExamVoucher表能正常更新,Exams表写入数据时触发日期溢出错误:
SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
通过日志排查发现,后端接收到的日期为1/1/0001 12:00,即DateTime类型的默认值。
根因分析
前端请求的JSON结构与后端RedeemVoucherDto的绑定要求不匹配:
- 前端发送的请求体嵌套了
redeemVoucherDto层级:{ redeemVoucherDto: { dateAssigned: formattedDate } } - 后端接口通过
[FromBody] RedeemVoucherDto直接接收Dto对象,期望请求体是{ dateAssigned: "..." }的扁平结构 - 结构不匹配导致Dto的
DateAssigned属性未被正确赋值,使用了DateTime的默认值(0001-01-01),该日期超出SQL ServerDATETIME类型的范围,触发溢出错误。
修复方案
1. 调整前端请求体结构
修改React代码中handleRedeem函数的请求体,移除多余的嵌套层级:
const handleRedeem = async () => { try { const formattedDate = examDate.toISOString(); const response = await fetch(`https://localhost:5888/api/ExamVouchers/RedeemVoucher/${voucherCode}`, { method: 'PUT', headers: { "Content-Type": "application/json", 'Authorization': `Bearer ${token}`, }, // 移除redeemVoucherDto嵌套,直接传递dateAssigned字段 body: JSON.stringify({ dateAssigned: formattedDate }) }); if (!response.ok) { const errorText = await response.text(); console.error('Response Status:', response.status, 'Response Text:', errorText); throw new Error('Network response was not ok'); } alert('Voucher redeemed successfully!'); } catch (error) { console.error('Error redeeming voucher:', error); alert('Error redeeming voucher: ' + error.message); } };
2. 后端Dto添加验证(可选)
为RedeemVoucherDto添加数据验证特性,确保日期参数必填且格式正确,提前拦截无效请求:
public class RedeemVoucherDto { [Required(ErrorMessage = "日期不能为空")] [DataType(DataType.DateTime)] public DateTime DateAssigned { get; set; } }
3. 优化数据库日期类型(可选)
如果业务需要支持更早的日期范围,可将Exam表的DateAssigned字段改为DATETIME2类型(支持范围:0001-01-01 到 9999-12-31):
ALTER TABLE Exam ALTER COLUMN DateAssigned DATETIME2;
验证
修改完成后,前端选择日期并提交兑换请求,后端将正确接收并绑定日期参数,Exams表可正常写入数据,不再触发日期溢出错误。
内容的提问来源于stack exchange,提问作者Scarlet D.
相关产品推荐
相关产品推荐

