ModelState.IsValid忽略[Required]属性

时间:2015-01-27 18:54:14

标签: c# asp.net-mvc entity-framework validation asp.net-mvc-5

出于某种原因,我的控制器中的ModelState.IsValid检查返回true,即使我的实体和viewmodel属性在字段上的[Required]属性为0。

这是实体:

public class Ticket
{
    public int Id { get; set; }

    [Required]
    public int FareId { get; set; }
    public virtual Fare Fare { get; set; }
}

我的视图使用的视图模型:

public class BaseTicketViewModel
{
    [Required, Display(Name = "Fare")]
    public int FareId { get; set; }
    public Fare Fare { get; set; }
}

在我看来,我使用过多个单选按钮而不是下拉列表,这可能是导致问题的原因,我只是不知道如何:

<div class="form-group">
    @Html.LabelFor(model => model.FareId, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @foreach (FareGroup fareGroup in Model.FareList)
        {
            <h5><strong>@fareGroup.Name</strong></h5>

            foreach (Fare fare in fareGroup.Fares)
            {
                <label class="checkbox-inline">
                    @Html.RadioButtonFor(model => model.FareId, fare.Id)
                    @fare.Name
                </label>
            }
        }
        @Html.ValidationMessageFor(model => model.FareId, "", new { @class = "text-danger" })
    </div>
</div>

当我在没有选择票价的情况下提交表单时,我的控制器会引发一个DbUpdateException,告诉我INSERT语句与FOREIGN KEY约束冲突,基本上ID为{0}的Fare并不是; t存在:

  

{&#34; INSERT语句与FOREIGN KEY约束冲突   &#34; FK_dbo.Tickets_dbo.Fares_FareId&#34 ;.冲突发生在数据库中   &#34;编辑&#34;,表&#34; dbo.Fares&#34;,列   &#39; Id&#39;。\ r \ n声明已终止。&#34;}

据我了解,如果viewmodel / ticket实体上的FareId属性为0,那么ModelState.IsValid应该为false,因为该属性上有[Required]注释?

1 个答案:

答案 0 :(得分:7)

Integers默认为0,因为它们是值类型。因此,它符合Required属性的要求,但对于您的方案来说却很差。

Required Attribute文档声明:

  

RequiredAttribute属性指定表单上的字段   验证后,该字段必须包含值。验证异常   如果属性为null,则引发,包含空字符串(&#34;&#34;)或   仅包含空格字符。

由于你的int不可为空,因为它显然不能是空字符串,所以它会通过验证。

如果您想确保您的Id不是默认值,您可以使用Range属性,但如果您的Id值为0,则会导致问题。

[Range(1, int.MaxValue,
   ErrorMessage = "Value for {0} must be between {1} and {2}.")]

最后,正如Chris Peterson指出的那样,如果FareId可以为空,那么它将能够正确使用Required属性,因为如果没有发布值,它将默认为null,从而触发验证。 / p>

[Required]
public int? FareId { get; set; }