noo*_*otn 7 validation asp.net-mvc defaultmodelbinder asp.net-mvc-3
我试图让ASP.NET MVC 3从复杂的嵌套对象生成表单.我发现有一个验证行为是意外的,我不确定它是否是DefaultModelBinder中的错误.
如果我有两个对象,让我们调用"父"一个"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" });
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是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" });
}
}
}
Run Code Online (Sandbox Code Playgroud)
你会注意到我在两者上的验证......只是一些虚拟验证,说某些值不能等于"测试".
以下是将在(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>
}
Run Code Online (Sandbox Code Playgroud)
..最后这里是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);
}
}
Run Code Online (Sandbox Code Playgroud)
你会发现,当模型被DefaultModelBinder验证时,"InnerObject"中的"Validate"方法被击中两次,但"OuterObject"中的"Validate"方法根本没有被击中.
如果你从"InnerObject"中取下IValidatableObject,那么"OuterObject"上的那个就会被击中.
这是一个错误,还是我希望它能以这种方式工作?如果我期待它,最好的解决方法是什么?
您是否应该为 InnerObject 创建 OuterObject 基类,而不是像您那样创建关系?(反之亦然)并提供视图基础对象作为 ViewModel?
这意味着当模型绑定时,将调用 OuterObject(或您的基类)的默认构造函数,从而间接调用两个对象上的 Validate。
即类:
public class OuterObject : InnerObject, IValidateableObject
{
...
}
Run Code Online (Sandbox Code Playgroud)
看法:
@model MvcNestedObjectTest.Models.OuterObject
Run Code Online (Sandbox Code Playgroud)
控制器动作:
public ActionResult Index(OuterObject model)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5786 次 |
| 最近记录: |