mvc3 DropDown不验证嵌套属性

时间:2012-03-08 00:15:25

标签: asp.net-mvc-3 validation

在视图中,我添加了person类型的对象(为简单起见)。但是,对于所有选择的汽车(例如)的下拉列表的验证将不会在帖子之前显示。让我详细说明一下。

在我的控制器中,我设置了一个viewmodel来传入。填充不是问题。以下是模型的简单版本。

public class PersonViewModel
{
 public Person Person { get; set;}

 public List<Car> Cars { get; set;}
}

public class Car
{
 [Key]
 public int CarId { get; set;}
 [Required]
 public string Name { get; set;}
}

public class Person
{
 [Key]
 public int PersonId { get; set;}
 [Required]
 public int CarId { get; set;}
 [Required]
 public string FullName { get; set;}
}

好的,到目前为止非常基本。在视图中是问题。

在视图中:

@model PersonViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" 
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" 
type="text/javascript"></script>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
    <legend>Add Person</legend>

    <div class="editor-label">Car</div>
    <div class="editor-field">
        @Html.DropDownListFor(
            m => m.Person.CarId,
            new SelectList(
                Model.Cars,
                "CarId",
                "Name",
                0
            ),
            "-- Select A Car --"
        )
        @Html.ValidationMessageFor(m=> m.Person.CarId)
    </div>
    <div class="editor-label">
        @Html.LabelFor(m=> m.Person.FullName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Person.FullName)
        @Html.ValidationMessageFor(model => model.Person.FullName)
    </div>

    <p>
        <input type="submit" value="Create Person" />
    </p>
</fieldset>
}

呈现此视图时,会创建一个用于创建人员的表单。在表单中,使用汽车名称生成下拉列表,并且可以使用人员姓名字段。如果选择了汽车并且填写了某个人的姓名,则点击创建,该帖子没有任何问题。

然而,这是差异。如果未填写某个人的姓名并单击“创建”,则输入框将以红色突出显示,并显示需要名称的消息。如果未选择汽车,则表格将提交。在控制器中,这很容易在if(ModelState.isValid)下捕获,但我想向用户指出他们的人没有车。将字段[Required] public int CarId添加到viewmodel然后通过绑定引用该字段将停止提交表单,如果没有选择汽车但似乎是一个hacky解决方案。

未经检查验证的原因是,由于某种原因,生成的<select> html对象缺少添加的装饰class="input-validation-error" data-val-required="The field is required." data-val-number="The field must be a number." data-val="true"

如何确保包含此装饰?

1 个答案:

答案 0 :(得分:1)

我猜DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes以某种方式设置为false。这意味着不会为整数等值类型自动添加Required属性。如果将其设置为true,则必需属性将自动添加到所有值类型的元数据中,并将发出HTML5 data-*属性。它的默认值是true

为避免此类问题,您可以使用真实的视图模型:

public class CreatePersonViewModel
{
    public PersonViewModel Person { get; set;}
    public List<CarViewModel> Cars { get; set;}
}

public class CarViewModel
{
    public int CarId { get; set;}

    public string Name { get; set;}
}

public class PersonViewModel
{
    [Required]
    public int? CarId { get; set;}

    [Required]
    public string FullName { get; set;}
}

请注意,我们不再需要此视图模型的PersonId属性,因为我们正在创建一个尚未分配id的新人。另请注意,CarId声明为可为空的整数,并使用Required属性进行修饰。由于在我们的下拉列表中我们允许使用默认值(-- Select A Car --),因此我们必须使用可空类型在视图模型上正确反映该值。