ASP.NET MVC 3を取得して、複雑なネストされたオブジェクトからフォームを生成しようとしています。予期しない検証動作が1つ見つかりましたが、それがDefaultModelBinderのバグであるかどうかはわかりません。
2つのオブジェクトがある場合、「親」を「OuterObject」と呼び、タイプが「InnerObject」(子)のプロパティを持ちます。
public class OuterObject : IValidatableObject
{
[Required]
public string OuterObjectName { get; set; }
public InnerObject FirstInnerObject { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!string.IsNullOrWhiteSpace(OuterObjectName) && string.Equals(OuterObjectName, "test", StringComparison.CurrentCultureIgnoreCase))
{
yield return new ValidationResult("OuterObjectName must not be 'test'", new[] { "OuterObjectName" });
}
}
}
InnerObjectは次のとおりです。
public class InnerObject : IValidatableObject
{
[Required]
public string InnerObjectName { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!string.IsNullOrWhiteSpace(InnerObjectName) && string.Equals(InnerObjectName, "test", StringComparison.CurrentCultureIgnoreCase))
{
yield return new ValidationResult("InnerObjectName must not be 'test'", new[] { "InnerObjectName" });
}
}
}
あなたは私が両方に行った検証に気付くでしょう..いくつかの値が「テスト」に等しくないことを言うためのいくつかのダミー検証。
これが(Index.cshtml)に表示されるビューは次のとおりです。
@model MvcNestedObjectTest.Models.OuterObject
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm()) {
<div>
<fieldset>
<legend>Using "For" Lambda</legend>
<div class="editor-label">
@Html.LabelFor(m => m.OuterObjectName)
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.OuterObjectName)
@Html.ValidationMessageFor(m => m.OuterObjectName)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.FirstInnerObject.InnerObjectName)
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.FirstInnerObject.InnerObjectName)
@Html.ValidationMessageFor(m => m.FirstInnerObject.InnerObjectName)
</div>
<p>
<input type="submit" value="Test Submit" />
</p>
</fieldset>
</div>
}
..そして最後にここにHomeControllerがあります:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new OuterObject();
model.FirstInnerObject = new InnerObject();
return View(model);
}
[HttpPost]
public ActionResult Index(OuterObject model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index");
}
return View(model);
}
}
モデルがDefaultModelBinderによって検証されると、「InnerObject」の「Validate」メソッドは2回ヒットしますが、「OuterObject」の「Validate」メソッドはまったくヒットしません。
「InnerObject」からIValidatableObjectを削除すると、「OuterObject」のIValidatableObjectがヒットします。
これはバグですか、それともそのように機能することを期待する必要がありますか?私がそれを期待する必要がある場合、最良の回避策は何ですか?