我有一个嵌套模型,即:
MySuperClass
ConfigClass
DataClass
我将“MySuperClass”传递给包含Form的View。此表单上的元素使用LINQ进行模型绑定,即:
EditorFor(model=>model.DataClass.Name)
EditorFor(model=>model.DataClass.DateOfBirth)
我在View中使用MySuperClass.ConfigClass属性。
我在DataClass属性上有Validation DataAnnotations,例如“Required”。
我回到控制器中的表单处理程序:
[HttpPost]
public ActionResult Index(MySuperClass mySC, string unused = "")
//ModelState not firing.... on empty required columns
if (ModelState.IsValid))
我认为“mySuperClass”就像一个ViewModel。
如何让验证工作?
修改
还使用验证助手:
@Html.EditorFor(model=>model.DataClass.Name)
@Html.ValidationMessageFor(model => model.DataClass.Name)
答案 0 :(得分:1)
嵌套对象将进行验证,只要它们不为空,因此您只需要确保Model.DataClass
是DataClass
的实例而不是null。最简单的方法是在MySuperClass
:
public MySuperClass()
{
DataClass = new DataClass();
}
答案 1 :(得分:1)
我在我的一个项目中解决了和你一样的麻烦,你需要创建过滤器并在从动作发送到视图以及从视图到动作发布(后期动作)时使用它:
public abstract class ModelStateBase : ActionFilterAttribute
{
protected static readonly string Key = typeof(ModelStateBase).FullName;
}
public class OnGetMetaData : ModelStateBase
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (!filterContext.Controller.ViewData.ModelState.IsValid)
{
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
}
}
base.OnActionExecuted(filterContext);
}
}
public class OnPostMetaData : ModelStateBase
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;
if (modelState != null)
{
if (filterContext.Result is ViewResult)
{
filterContext.Controller.ViewData.ModelState.Merge(modelState);
}
else
{
filterContext.Controller.TempData.Remove(Key);
}
}
base.OnActionExecuted(filterContext);
}
}
在获取和发布操作中,您可以这样做:
[OnPostMetaData]
public ActionResult Index()
{
return View();
}
[HttpPost, OnGetMetaData]
public ActionResult Index(MySuperClass mySuperClass)
{
if (ModelState.IsValid)
{
//do something
}
return View();
}
最后视图与您使用的常规表单相同。
答案 2 :(得分:1)
嵌套模型应该适用于MVC 3.请尝试使用此示例。
public class HomeController : Controller
{
public ActionResult IndexNew()
{
Sample obj = new Sample() {MyTest=new Test() };
return View(obj);
}
[HttpPost]
public ActionResult IndexNew(Sample test)
{
return View(test);
}
}
public class Sample
{
public Test MyTest { get; set; }
}
public class Test
{
[Required]
public string Name { get; set; }
}
@model MvcApplication2.Controllers.Sample
@{
ViewBag.Title = "IndexNew";
}
<h2>IndexNew</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Sample</legend>
@Html.TextBoxFor(e => e.MyTest.Name);
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>