Asp.net mvc 3 mvc3 DropDownFor未验证嵌套属性

Asp.net mvc 3 mvc3 DropDownFor未验证嵌套属性,asp.net-mvc-3,validation,Asp.net Mvc 3,Validation,为了简单起见,我在视图中添加了person类型的对象。但是,例如,在所有汽车中选择哪一辆汽车的下拉列表的验证将不会显示在帖子之前。让我详细说明一下 在我的控制器中,我设置了一个要传入的viewmodel。人口不是问题。以下是这些模型的简单版本 public class PersonViewModel { public Person Person { get; set;} public List<Car> Cars { get; set;} } public class Car

为了简单起见,我在视图中添加了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>
}
渲染此视图时,将创建用于创建人员的表单。在表单中,将生成一个包含汽车名称的下拉列表,并且可以使用人名字段。如果选择了一辆车并填写了一个人的姓名,然后单击“创建”,则帖子将顺利完成

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

未检查验证的原因是,由于某些原因,生成的html对象缺少添加的装饰类=输入验证错误数据val required=该字段是必需的。data val number=该字段必须是一个数字。数据值=真

如何确保包含此装饰?

我猜DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes以某种方式设置为false。这意味着不会为值类型(如整数)自动添加必需的属性。如果将其设置为true,则所需属性将自动添加到所有值类型的元数据中,并将发出HTML5数据-*属性。但其默认值为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被声明为可为null的整数,并用必需的属性修饰。因为在我们的下拉列表中,我们允许使用默认值-选择一辆车-我们必须使用可为空的类型在视图模型上正确反映这一点。

感谢您在这里的贡献,以及您的整体魅力。不幸的是,你的猜测没有帮助,我仍然没有得到额外的加价。我在问题中提到的,正如您在回答中所说的,是当前的解决方案,即在viewmodel中再次明确定义CarId及其注释、数据建议、过滤器等。。不幸的是,必须这样做,因为我厌倦了将数据模型中的值复制粘贴到视图模型中。复制粘贴会导致错误。此外,必须在视图模型中手动设置字段……意味着我必须在实体被持久化之前手动将它们映射到实体上,从而减弱了为视图使用特殊模型的优点。