我有一个ViewModel有一些DataAnnotations验证,然后对于更复杂的验证实现IValidatableObject并使用Validate方法。IValidatableObject当DataAnnotations失败时验证方法触发
我期待的行为是this one:首先是所有DataAnnotations,然后,只有在没有错误的情况下,Validate方法。我怎么会发现这并非总是如此。我的ViewModel(演示版)有三个分区,一个为string
,一个为decimal
,另一个为decimal?
。所有这三个属性都只有必需的属性。对于string
和decimal?
,行为是预期行为,但对于空行为decimal
,Required验证失败(迄今为止很好),然后执行Validate方法。如果我检查房产价值为零。
这是怎么回事?我错过了什么?
注意:我知道Required属性是假设检查值是否为空。所以我期望被告知不要在非空类型中使用Required属性(因为它不会触发),或者,不知何故该属性理解POST值并注意该字段未被填充。在第一种情况下,属性不应该触发,并且应该触发Validate方法。在第二种情况下,属性应该触发并且Validate方法不应该触发。但是我的结果是:属性触发器和Validate方法触发。
下面是代码(没有什么太特别的):
控制器:
public ActionResult Index()
{
return View(HomeModel.LoadHome());
}
[HttpPost]
public ActionResult Index(HomeViewModel viewModel)
{
try
{
if (ModelState.IsValid)
{
HomeModel.ProcessHome(viewModel);
return RedirectToAction("Index", "Result");
}
}
catch (ApplicationException ex)
{
ModelState.AddModelError(string.Empty, ex.Message);
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, "Internal error.");
}
return View(viewModel);
}
型号:
public static HomeViewModel LoadHome()
{
HomeViewModel viewModel = new HomeViewModel();
viewModel.String = string.Empty;
return viewModel;
}
public static void ProcessHome(HomeViewModel viewModel)
{
// Not relevant code
}
视图模型:
public class HomeViewModel : IValidatableObject
{
[Required(ErrorMessage = "Required {0}")]
[Display(Name = "string")]
public string String { get; set; }
[Required(ErrorMessage = "Required {0}")]
[Display(Name = "decimal")]
public decimal Decimal { get; set; }
[Required(ErrorMessage = "Required {0}")]
[Display(Name = "decimal?")]
public decimal? DecimalNullable { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
yield return new ValidationResult("Error from Validate method");
}
}
查看:
后评论只@model MVCTest1.ViewModels.HomeViewModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm(null, null, FormMethod.Post))
{
<div>
@Html.ValidationSummary()
</div>
<label id="lblNombre" for="Nombre">Nombre:</label>
@Html.TextBoxFor(m => m.Nombre)
<label id="lblDecimal" for="Decimal">Decimal:</label>
@Html.TextBoxFor(m => m.Decimal)
<label id="lblDecimalNullable" for="DecimalNullable">Decimal?:</label>
@Html.TextBoxFor(m => m.DecimalNullable)
<button type="submit" id="aceptar">Aceptar</button>
<button type="submit" id="superAceptar">SuperAceptar</button>
@Html.HiddenFor(m => m.Accion)
}
'decimal'不会为空。它不能像'字符串'或'小数?'那样空。你期待的行为是什么? – Joao
@Jota我会认为或必需属性将无法正常工作,因为'decimal'永远不会为null或Validate方法不会被调用,因为某些DataAnnotation验证失败。 – Diego
您必须将“decimal”设置为可空,否则[必需]将不会触发。任何理由不这样做? – Joao