是否有可能在ASP.NET MVC 5 ViewModel中同时使属性可以为空并且需要?

时间:2016-09-13 20:04:20

标签: c# asp.net asp.net-mvc mvvm asp.net-mvc-5

我有以下视图模型

public class FormViewModel
{
    [Required]
    public DateTime? LocalFrom { get; set; }

    [Required]
    public DateTime? LocalTo { get; set; }
}

然后在控制器中我有以下动作

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index([Bind(Include = "LocalFrom,LocalTo")] FormViewModel model)
{
    if (ModelState.IsValid)
    {
        var presenter = new ManagePresenter(model);
        return View(presenter);
    }
    return View(model); // here model.LocalFrom, model.LocalTo should be null
}

这是我的HTML表单

<form class="form-horizontal" action="/Manage/Index" method="post">

    @Html.AntiForgeryToken()
    <div class="form-group">
        <label class="control-label col-sm-2" for="LocalFrom">From</label>
        <div class="col-sm-10">
            <input type="datetime" class="form-control" id="LocalFrom" name="LocalFrom" value="@Model.LocalFrom" required>
        </div>
    </div>

    <div class="form-group">
        <label class="control-label col-sm-2" for="LocalTo">To</label>
        <div class="col-sm-10">
            <input type="datetime" class="form-control" id="LocalTo" name="LocalTo" value="@Model.LocalTo)" required>
        </div>
    </div>

    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>

</form>

我不确定所需的可空属性是否合乎逻辑。我基本上希望在LocalFrom为空时使用blank在视图中填充名称为Model.LocalFrom的输入,或者在Model.LocalFrom不为空时使用正确的值填充输入。

问题

即使我们所有必需的值都存在且有效,ModelState.IsValid总是返回false。

当我LocalFromLocalTo不可为空时,ModelState变为有效。但在视图中会显示开始时间的时间,如此

enter image description here

如何将null值传递给视图并使ModelState正确验证?

1 个答案:

答案 0 :(得分:3)

如果您想允许[Required]个值,则需要从DateTime属性中删除[Required]属性。 null属性表示该值不能为null,因此如果您提交空值(ModelState),则null将无效。

删除属性意味着提交有效日期或ModelState有效,但提交无效日期仍会导致DateTime无效。

此外,您手动生成html,因此您无法获得正确的双向模型绑定(这就是您返回视图时看到<div class="form-group"> @Html.LabelFor(m => m.LocalFrom, new { @class="control-label col-sm-2" }) // assumes you add [Display(Name = "From")] to the property <div class="col-sm-10"> @Html.TextBoxFor(m => m.LocalFrom) @Html.ValidationMessageFor(m => m.LocalFrom) </div> </div> 的默认值的原因)。你的观点应该是

[Bind]

作为旁注,您应该删除不必要的jquery.validate.js属性。您正在使用视图模型,这意味着您已经受到保护,免受过度发布攻击。

最后,在视图中包含jquery.validate.unobtrusive.jsCPUEmulator脚本,以便获得与服务器端验证属性匹配的客户端验证,并在视图中显示相应的错误消息。