如何修复MVC中daterange参数为非空DateTime类型的空值错误
点击模态框的保存按钮后无法完成数据保存,报错如下:
The parameters dictionary contains a null entry for parameter 'daterange' of non-nullable type 'System.DateTime' for method 'System.Web.Mvc.ActionResult Index(System.String, System.String, System.String, System.String, System.String, System.String, System.String, Int32, System.Web.HttpPostedFileBase, System.DateTime, System.String)' in 'TestWeb.Controllers.MainController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter
奇怪的是代码在其他电脑上能正常运行,本地清理浏览器、VS缓存,甚至重装VS都无法解决问题。
Controller代码
[HttpPost] public ActionResult Index(string StoreCode, string Purpose, string Dept, string Request, string Type, string detals, string size, int QTY, HttpPostedFileBase Picture, DateTime daterange, string Remarks) { using (DatawarehouseEntities db = new DatawarehouseEntities()) { string add = db.Add_PRW_Entries(StoreCode, Purpose, Dept, Request, Type, detals, size, QTY, "", Convert.ToDateTime(daterange), Remarks).FirstOrDefault().ToString(); string filename = Picture.FileName; string filepath = ""; string piclink = ""; piclink = "//local host link"; filepath = Path.Combine(Server.MapPath("~/Images/" + add), filename); if (!Directory.Exists(Server.MapPath("~/Images/" + add))) { Directory.CreateDirectory(Server.MapPath("~/Images/" + add));//create folder if it doesnt exist } Picture.SaveAs(filepath); db.Update_PictureLink_PRW(int.Parse(add), piclink); } return RedirectToAction("Index", "Main"); }
Views代码
<form action="~/Main/Index" class="needs-validation" enctype="multipart/form-data" id="insertmain" method="post"> <div class="input-group mb-3"> </div> <div id="additemmodal" class="modal fade"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header" style="background-color:#2c3e50"> <h2 style="color:white; text-align:center">Add Record</h2> <button type="button" class="close" data-bs-dismiss="modal">×</button> </div> <div class="modal-body row has-error"> <div class="col-6 mb-3"> <div> <label>Request Type:</label></div> <select id="RTYPE" name="RTYPE"> @foreach (var items in ViewBag.TYPE) { <option value="@items.Request_Name">@items.Request_Name</option> } </select> <div> <label>Business Unit:</label></div> <select id="StoreCode" name="StoreCode"> @foreach (var items in ViewBag.cbstore) { <option value="@items.STSHRT">@items.STSHRT - @items.STRNAM</option> } </select> <div><label><label>Purpose:</label></label></div> <input class="form-control" type="text" id="Purpose" name="Purpose" required /> <div><label><label>Department:</label></label></div> <input class="form-control" type="text" id="Dept" name="Dept" required /> <div><label><label>Request:</label></label></div> <input class="form-control" type="text" id="Request" name="Request" required /> <div><label><label>Type of Materials:</label></label></div> <input class="form-control" type="text" id="Type" name="Type" required /> <div><label><label>Image:</label></label></div> <input class="form-control" type="file" id="Picture" name="Picture" onchange="imagePreview()" required /> </div> <div class="col-6 mb-3"> <div><label><label>Details needed in materials:</label></label></div> <input class="form-control" type="text" id="detals" name="details" required /> <div><label><label>Size:</label></label></div> <input class="form-control" type="text" id="size" name="size" required /> <div><label><label>Quantity:</label></label></div> <input class="form-control" type="text" id="QTY" name="QTY" onkeypress="return isNumber(event);" required /> <div><label><label>Target Date:</label></label></div> <input type="text" name="daterange" id="daterange" required /> <div class="form-group mb-2 imgdiv"> <label class="control-label col-md-2" for="StoreNumber">Image Preview</label> <div class="col-md-10 imgprv"> <img id="imgPreview" src="" data-fancybox /> </div> </div> </div> <div><label><label>Remarks:</label></label></div> <textarea class="form-control" id="Remarks" name="Remarks" style="margin-left:10px; width:90%;" required></textarea> <div class="row"> <div class="col-6 mb-3"> </div> <div class="col-12 mb-3"> <button class="btn btn-success input-group-text" onclick="confirm()" type="button" id="submit" name="submit">Save</button> <button type="submit" id="Save" style="display:none"></button> </div> </div> </div> </div> </div> </div>
1. 修复参数绑定不匹配问题
- 视图中"Details needed in materials"对应的输入框
name="details",但Controller参数是string detals,名称不一致会导致参数接收失败。将视图中的name="details"改为name="detals",或者把Controller参数改为string details。 - 日期选择器提交的是字符串,不同电脑区域设置可能导致MVC无法自动解析为
DateTime。将Controller中的DateTime daterange改为可空类型DateTime? daterange,或者手动指定格式解析:[HttpPost] public ActionResult Index(string StoreCode, string Purpose, string Dept, string Request, string Type, string detals, string size, int QTY, HttpPostedFileBase Picture, string daterange, string Remarks) { DateTime targetDate = DateTime.ParseExact(daterange, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); // 后续代码中替换daterange为targetDate }
2. 统一日期选择器输出格式
确保前端日期选择器(如daterangepicker)输出的日期格式和后端解析格式一致,比如统一使用yyyy-MM-dd。如果未初始化日期选择器,需限制用户输入标准格式的日期。
3. 修复表单提交逻辑
视图中的保存按钮是type="button",依赖confirm()函数触发提交,需确保该函数正确执行表单提交:
function confirm() { const form = document.getElementById('insertmain'); if (form.checkValidity()) { form.submit(); } else { form.reportValidity(); } }
也可以直接将保存按钮改为type="submit",去掉隐藏的提交按钮,简化逻辑。
4. 统一本地区域设置
本地区域日期格式可能和其他电脑不一致,导致MVC模型绑定失败。在Web.config中添加全局配置统一区域:
<configuration> <system.web> <globalization culture="en-US" uiCulture="en-US" /> </system.web> </configuration>
内容的提问来源于stack exchange,提问作者Weboshii

