是否可以通过数据注释进行“选择性”验证?

时间:2010-11-04 02:12:36

标签: asp.net-mvc validation data-annotations

我现在有一个发布13个对象的表单。一些对象可以是可选的,例如Referrer,其他对象不可以。问题是,如果我使用DAV并用[Required]等验证属性装饰对象,即使对象是可选的,整个帖子也会失败,因为ModelState将无效。

我可以从所有对象中删除[Required]装饰,但这不合适。那么,有没有办法在仍然使用DAV时有选择地验证单个对象?

考虑一下:

<form>
    <input type="hidden" name="Description.AuthorId" value="{?}" />
    <p>
        <label>Office</label>
        <select name="Job.OfficeId">{?}</select>
    </p>
    <p>
        <label>Description</label>
        <textarea name="Description.Text"></textarea>
    </p>
</form>

在这个简化的表单中,我正在使用JobDescriptionDescription实际上是Note类型,就数据库而言被关注到)。必须填写Job个信息,但说明是可选的。表单的问题是Description.AuthorId始终填充了当前授权用户的ID。

public class Note {
    [Required]
    public short AuthorId { get; set; }

    [Required, StringLength(XXX)]
    public string Text { get; set; }
}

public RedirectToRouteResult Jobs(
    [Bind(Prefix = "Job", Include = "OfficeId")] Job Job,
    [Bind(Prefix = "Description", Include = "AuthorId,Text")] Note Description) {
    if (ModelState.IsValid) {
        if (Description != null) {
            Description.Job = Job;
        };

        DataContext.Jobs.InsertOnSubmit(Job);
        DataContext.SubmitChanges();
    };
}

该方法的第一个问题是,因为表单Description将始终生成,因为表单将始终通过Description.AuthorId所以条件检查Description是否为null将永远不会即使Description.Text从未填写过,也会调用。

第二个问题是由于DAV未填充Description.Text,因此整个模型将无法通过验证,因为它是Note的必填字段。因此,我甚至没有机会做任何其他事情。

所以,我想我的问题是,对于在UI表单中可选的对象实现验证(DAV?)的正确方法是什么,但由于数据库设计本身具有必需的字段?

我想到的一种方法是,不是将对象传递给,而是将方法实例化为 方法,然后执行TryUpdateModel每个按顺序,检查模型状态并继续基于条件。这可能会占用很多代码,所以我想在进入该解决方案之前看看是否有更自动的版本。

帮助将受到高度赞赏!

1 个答案:

答案 0 :(得分:0)

对于这种情况,我的建议是创建视图模型(用于视图数据/验证和模型绑定的简单模型,并在以后映射到数据库模型)。尝试使用所有验证来推动业务/数据库模型并不总是可行的。如果模型在某些地方的验证方式不同,那么你很可能只是因为它们都是绿色而在方孔中强制进行圆形钉。如果由于某些限制绝对必须使用相同的对象,则可以选择忽略验证或从控制器上的ModelState字典中删除有问题的错误,但这不是一个好主意。