【问题标题】:Trouble with ModelState on datetime field日期时间字段上的 ModelState 出现问题
【发布时间】:2013-08-07 17:08:34
【问题描述】:

在我们的 ASP MVC 3 站点中,我们希望用户能够输入不完整的表单,将该记录保存到数据库中,然后再返回表单。如果输入错误的字段,我们希望在用户点击保存时出现这些错误消息。

但是,特定于出生日期字段的问题正在发生。如果用户输入了错误的日期,例如14/01/2011,当用户点击保存并且模型对象返回到控制器操作时,出生日期将显示为空白。然后它不符合if (ModelState.IsValid) 条件,不保存到数据库,并被发送回具有空白出生日期的视图。

有没有办法允许用户在此字段中输入错误的日期,保留该值并使用该值和通常由模型生成的错误消息返回视图?由于我们使用的是 jQuery 输入掩码,因此输入的值将始终为数字并采用 MM/DD/YYYY 格式。

型号

    [DisplayName("Date of Birth")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Birthdate { get; set; }

控制器

    [HttpPost]
    public ActionResult Edit(Monet.Models.AgentTransmission agenttransmission)
    {
        //Date of birth field is null right here in 'agenttransmission' object if
        //user enters incorrect value/date

        //redirect if security is not met.  
        if (!Security.IsModifier(User)) return RedirectToAction("Message", "Home", new { id = 1 });

        //Tax Id security
        ViewBag.FullSSN = Security.IsFullSsn(User);

        try
        {
            agenttransmission = AgentTransmissionValidator.ReformatFields(agenttransmission);
            ViewBag.ErrorMessage = AgentTransmissionValidator.ValidateAgent(agenttransmission);

            if (ModelState.IsValid)
            {
                //Whole bunch of code to determine if input is complete/incomplete

                //Save the record
                db.Entry(agenttransmission).State = EntityState.Modified;
                db.SaveChanges();
            } //end if model state valid
        }
        catch (DbEntityValidationException dbEx)
        {
            ViewBag.ErrorMessage = "An error has occurred, we apologize for the incovenience. IT has been notified and will resolve the issue shortly.";
            SendEmail.ErrorMail(Common.ErrorCheck.CombineDbErrors(dbEx));
        }
        catch (Exception ex)
        {
            ViewBag.ErrorMessage = ErrorCheck.FriendlyError(ex);
            SendEmail.ErrorMail(ex);
        }

        return View(agenttransmission);
    }

查看

            <div class="M-editor-label">
                @Html.LabelFor(model => model.Birthdate)<span class="req">*</span>
            </div>
            <div class="M-editor-field">
                @Html.EditorFor(model => model.Birthdate)
                @Html.ValidationMessageFor(model => model.Birthdate)
            </div>

【问题讨论】:

  • 为什么要传回不正确的日期?让它为空会更容易让用户添加正确的日期。
  • 无法返回无效日期。它返回 null 因为 MVC 试图将发布的字符串解析为 DateTime 以便将其绑定到模型。模型上的属性必须是 DateTime,这意味着它要么是日期,要么是 null。由于无法将发布的字符串解析为有效日期,因此您最终会得到 null。
  • 如果你想得到这个值,即使它不是一个有效的日期,那么你需要接受它作为一个字符串并自己进行验证。

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 razor


【解决方案1】:

正如Queti Mporta 建议的那样,问题在于,当您回发时,模型绑定器尝试将“14/01/2011”解析为DateTime? 并失败,因此它使用默认值。对于可空类型,默认值为null,这就是您得到空白的原因。

如果您要将模型更改为...

[DisplayName("Date of Birth")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public string Birthdate { get; set; } // note: string instead of DateTime?

...用户现在可以输入格式为 MM/dd/yyyy 的任何内容,但是当它被回发时,它只会存储在一个字符串中。

您现在需要添加逻辑(在您的控制器中或从您的控制器可访问的地方)以尝试自己进行解析:

DateTime birthdate;
var isDateValid = DateTime.TryParse(agenttransmission.Birthdate, out birthday);
if (!isDateValid ) ModelState.AddModelError("Birthdate", "Birthday needs to be a valid date.");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多