0

从数据库优先方法开始,我试图仅编辑 DateTime 字段中的时间,该字段是从我无法更改的表中生成的(因此将其从 SQL 的日期时间更改为其他内容是不可能的)。我遇到的问题是验证器一直告诉我,除非我还包括日期,否则框中的内容不是有效日期。

这是我到目前为止所拥有的:

模型:

[DisplayName("Time")]
[DisplayFormat(DataFormatString = "{0:h:mm tt}", ApplyFormatInEditMode = true)]
public System.DateTime PrintTime { get; set; }

看法:

    <div class="editor-field">
        @Html.EditorFor(model => model.PrintTime)
        @Html.ValidationMessageFor(model => model.PrintTime)
    </div>

我尝试了 ModelBinder,并且尝试使用自定义验证属性(两者都成功编译并从此处获取),但无论我做什么,即使使用这些解决方案,我在验证时遇到的错误是:

“时间字段必须是日期”

我已经看到其他线程表明 jquery 可能具有我无法过去的日期要求(就线程建议的解决方案而言),并且似乎解决方案可以完全禁用验证。显然,我想继续验证(它适用于其他一切)。

那么我能做些什么来解决这个问题呢?

4

1 回答 1

1

我用一种解决方法解决了这个问题。首先,我在模型中添加了一个不在数据库中的字符串,然后在模型中添加了一些方法。如果从数据库中刷新模型,这将导致问题,所以要小心!

这是添加到模型中的内容:

    [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) 可能会漏掉一个错误的时间字符串,这会导致异常。

除此之外,这是我提出的完整解决方案。:)

于 2013-02-27T18:43:34.987 回答