我試圖讓ASP.NET MVC 3從複雜的嵌套對象中生成表單。有一種驗證行爲,我發現這是意外的,我不確定它是否是DefaultModelBinder中的錯誤。關於嵌套對象的ASP.NET MVC 3驗證不能按預期方式工作 - 驗證子對象兩次而不是父對象
如果我有兩個對象,讓我們稱之爲 「父」 一個 「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」方法被擊兩次,但「OuterObject」中的「Validate」方法根本沒有被擊中。
如果從「InnerObject」中取下IValidatableObject,則「OuterObject」上的那個將會被擊中。
這是一個錯誤,或者我應該期望它的工作方式?如果我期望它,什麼是最好的解決方法?
感謝我曾想過這一點,並會工作了這種特殊的情況,但作爲德對象變得更復雜,它不會工作。例如,如果我需要InnerObject1,SomeString,InnerObject2,SomeOtherString(即其他屬性之間的嵌套對象).. – nootn 2012-03-20 21:01:57
@nootn您是否嘗試過[流暢驗證](http:// http://fluentvalidation.codeplex.com/wikipage?title = mvc&referTitle = Documentation)這是驗證依賴性和嵌套驗證規則的高級方法嗎? – amythn04 2012-03-22 07:52:32
我已經研究過它,它看起來不錯,但在我們的組織中,我們選擇使用內置的數據註釋作爲驗證MVC中的模型的標準。我想我們可以使用一個組合,但它仍然沒有解決這個問題,並不像預期的那樣,這有點陷阱。 – nootn 2012-03-23 06:27:58