我用一种解决方法解决了这个问题。首先,我在模型中添加了一个不在数据库中的字符串,然后在模型中添加了一些方法。如果从数据库中刷新模型,这将导致问题,所以要小心!
这是添加到模型中的内容:
[DisplayName("Daily Print Time")]
[RegularExpression("^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9][\\s]*[apAP][mM][\\s]*", ErrorMessage="Invalid Time Format")]
[Required]
public string sPrintTime { get; set; }
[DisplayName("Daily Print Time")]
[DisplayFormat(DataFormatString = "{0:h:mm tt}", ApplyFormatInEditMode = true)]
[Required]
public System.DateTime PrintTime { get; set; }
方法:
public void UpdatePrintTime()
{
//This is a workaround to get past jquery validation errors when
//attempting to edit a DateTime value directly with just a time string.
DateTime dt = DateTime.MinValue;
DateTime.TryParse("12/30/1899 " + sPrintTime.ToUpper(), out dt);
if (dt != DateTime.MinValue)
{
PrintTime = dt;
}
}
public void UpdatePrintString()
{
sPrintTime = PrintTime.ToString("h:mm tt");
}
正则表达式验证并不完美(例如,它仍然允许您输入“23:59 am”,但方法 UpdatePrintTime() 使用 TryParse() 处理了这一点。
接下来,我更新了 Edit.cshtml 文件,如下所示:
@Html.HiddenFor(model => model.PrintTime)
需要添加上述行以避免由于缺少字段而导致的运行时错误
<div class="editor-field">
@Html.EditorFor(model => model.sPrintTime)
@Html.ValidationMessageFor(model => model.sPrintTime)
</div>
我还必须用上面的 <div> 更新 Create.cshtml 文件。注意:我没有包含隐藏的 PrintTime 字段,因为我添加了方法,我在控制器操作 Edit 和 Create 中使用如下:
[HttpPost]
public ActionResult Create(PrintJob printjob)
{
if (ModelState.IsValid)
{
printjob.UpdatePrintTime();
db.PrintJobs.Add(printjob);
db.SaveChanges();
return RedirectToAction("Index");
}
...
return View(printjob);
}
public ActionResult Edit(int id = 0)
{
PrintJob printjob = db.PrintJobs.Find(id);
if (printjob == null)
{
return HttpNotFound();
}
printjob.UpdatePrintString();
...
return View(printjob);
}
[HttpPost]
public ActionResult Edit(PrintJob printjob)
{
if (ModelState.IsValid)
{
printjob.UpdatePrintTime();
db.Entry(printjob).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
printjob.UpdatePrintString();
...
return View(printjob);
}
所有这些都是让它工作所必需的。现在,当我尝试输入错误的内容时,它会给我一个不同的验证错误,并仔细检查输入的内容,即使它通过了验证。如果它通过了客户端验证,但没有通过 TryParse(),那么如果处于编辑模式,它将完全保持时间不变。如果处于创建模式,则会引发异常。
所以这两个缺陷是 1) 验证与 TryParse() 不匹配,因此 2) 可能会漏掉一个错误的时间字符串,这会导致异常。
除此之外,这是我提出的完整解决方案。:)