いくつかのDataAnnotations検証を含むViewModelがあり、より複雑な検証ではIValidatableObjectを実装し、Validateメソッドを使用します。
私が期待していた動作はこれでした。最初にすべてのDataAnnotationsを実行し、次にエラーがない場合にのみValidateメソッドを実行しました。しかし、これが常に正しいとは限らないことがわかりました。私のViewModel(デモ1)には、1つstring
、1つ、decimal
および1つの3つのファイルがありdecimal?
ます。3つのプロパティはすべて、必須属性のみを持っています。string
およびの動作decimal?
は期待どおりですが、がdecimal
空の場合、必須の検証は失敗し(これまでのところ良好)、Validateメソッドを実行します。プロパティを調べると、その値はゼロです。
ここで何が起こっているのですか?私は何が欠けていますか?
注:Required属性は、値がnullかどうかをチェックすることを想定していることを知っています。したがって、null許容型では必須属性を使用しないように指示されるか(トリガーされないため)、または、属性がPOST値を理解し、フィールドが入力されていないことに注意してください。最初のケースでは、属性はトリガーされず、Validateメソッドが起動する必要があります。2番目のケースでは、属性がトリガーされ、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
}
ViewModel:
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)
}