Asp.net mvc datetime字段上的ModelState出现问题

Asp.net mvc datetime字段上的ModelState出现问题,asp.net-mvc,asp.net-mvc-3,asp.net-mvc-4,razor,Asp.net Mvc,Asp.net Mvc 3,Asp.net Mvc 4,Razor,在我们的ASP MVC 3站点中,我们希望用户能够输入一个不完整的表单,将该记录保存到数据库中,稍后再返回表单。如果输入的字段不正确,我们希望在用户点击“保存”时显示这些错误消息 然而,出生日期字段出现了一个问题。如果用户输入了不正确的日期,例如14/01/2011,当用户点击保存并将模型对象发回控制器操作时,出生日期将显示为空白。然后,它会使if(ModelState.IsValid)条件失败,不会保存到数据库中,并以空白的出生日期发送回视图 是否有方法允许用户在此字段中输入不正确的日期,保留

在我们的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>

@LabelFor(model=>model.Birthdate)*
@EditorFor(model=>model.Birthdate)
@Html.ValidationMessageFor(model=>model.Birthdate)
正如所建议的,问题在于,当您发回时,模型绑定器试图将“14/01/2011”解析为
日期时间?
,但失败了,因此它使用默认值。对于可为null的类型,默认值为
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.");

你为什么要把不正确的日期传回去?让它为空会让用户更容易添加正确的日期。不可能返回无效的日期。它返回null,因为MVC试图将发布的字符串解析为日期时间,以便将其绑定到模型。模型上的属性必须是DateTime,这意味着它是date或null。由于无法将发布的字符串解析为有效日期,因此结果为null。如果您希望获得该值,即使该值不是有效日期,则需要将其作为字符串接受,并自行进行验证。