C# ModelState.IsValid忽略[Required]属性
出于某种原因,签入我的控制器的C# ModelState.IsValid忽略[Required]属性,c#,asp.net-mvc,entity-framework,validation,asp.net-mvc-5,C#,Asp.net Mvc,Entity Framework,Validation,Asp.net Mvc 5,出于某种原因,签入我的控制器的ModelState.IsValid将返回true,即使我的entity和viewmodel属性在字段上的[Required]属性为0 这是实体: public class Ticket { public int Id { get; set; } [Required] public int FareId { get; set; } public virtual Fare Fare { get; set; } } 以及我的视图使用的
ModelState.IsValid
将返回true,即使我的entity和viewmodel属性在字段上的[Required]属性为0
这是实体:
public class Ticket
{
public int Id { get; set; }
[Required]
public int FareId { get; set; }
public virtual Fare Fare { get; set; }
}
以及我的视图使用的viewmodel:
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>
@LabelFor(model=>model.FareId,htmlAttributes:new{@class=“controllabel col-md-2”})
@foreach(模型中的FareGroup FareList)
{
@fareGroup.Name
foreach(票价组中的票价。票价)
{
@Html.radioButton(model=>model.FareId,fare.Id)
@车费.姓名
}
}
@Html.ValidationMessageFor(model=>model.FareId,“,new{@class=“text danger”})
当我提交表单而不选择票价时,我的控制器会引发一个DbUpdateException
,它告诉我INSERT语句与外键约束冲突,基本上ID为0的票价不存在:
{“INSERT语句与外键约束冲突
“FK_dbo.Tickets_dbo.Fares_FareId”。数据库中发生冲突
“修订”,表“dbo.票价”,第列
“Id”。\r\n语句已终止。“}
根据我的理解,如果viewmodel/ticket实体上的FareId
属性为0,则ModelState.IsValid
应为false,因为该属性上的[必需]
注释将默认为0,因为它们是值类型。因此,它满足了Required属性的要求,尽管对于您的场景来说相当糟糕
文件规定:
RequiredAttribute属性指定窗体上的字段
验证后,该字段必须包含一个值。验证异常
如果属性为null、包含空字符串(“”),或
仅包含空白字符
由于int不可为null,并且显然不能为空字符串,因此它通过了验证
[Required]
public int? FareId { get; set; }
如果要确保Id不是默认值,可以使用Range属性,但如果Id为0,则会导致问题
[Range(1, int.MaxValue,
ErrorMessage = "Value for {0} must be between {1} and {2}.")]
最后,正如Chris Peterson指出的那样,如果FareId可为null,它将能够正确地利用所需的属性,因为如果没有发布值,它将默认为null,从而触发验证
[Required]
public int? FareId { get; set; }
粘贴控制器的代码。0
是有效的int。由于int
不能为空,您将始终通过必需的测试。您需要一个int?
,或者一个可为空的int。0仍然是一个值。当它说Required is时,意味着它不能为Null。为了这篇文章的目的,我缩减了我的实体/视图模型,并且我还有另一个名为TimetableId
的属性,它的定义方式与FareId
相同,只是它在视图中由下拉列表表示。当您没有选择任何内容时,它也会发送值0
,但是ModelState.IsValid
会像我预期的那样工作(当TimetableId==0
时返回false)。有什么区别?@ChrisWhite必须有另一种情况发生在TimetableId上,但由于您没有发布任何有关TimetableId的代码,因此无法告诉您区别是什么。另一种选择是使用具有所需属性的可为null的int。