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

问题描述 投票:2回答:1

我有以下视图模型

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为null时,我基本上想要在blank视图中使用名称Model.LocalFrom填充输入,或者当Model.LocalFrom不为null时使用正确的值填充输入。

问题

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

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

enter image description here

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

c# asp.net asp.net-mvc mvvm asp.net-mvc-5
1个回答
3
投票

如果要允许null值,则需要从[Required]属性中删除DateTime属性。 [Required]属性意味着该值不能是null所以如果你提交一个空值(null),那么ModelState将无效。

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

此外,您手动生成html,因此您无法获得正确的双向模型绑定(这就是为什么在返回视图时会看到DateTime的默认值)。你的观点应该是

<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.jsjquery.validate.unobtrusive.js脚本,以便获得与服务器端验证属性匹配的客户端验证,并在视图中显示相应的错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.