ASP.NET MVC 2 Preview 1 - 使用复杂模型对象进行数据注释验证
-
21-09-2019 - |
题
让模型处理自己的验证的能力使我开始使用 MVC 2 预览版。到目前为止,我喜欢验证方案的简单性。然而,我遇到了障碍。这种验证样式适用于简单的视图模型对象。例如,如果我有一个名为的模型对象 车 我正在创建一个视图来创建一辆新车:
- - -模型 - - - -
public class Car
{
public string Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
}
- - -控制器 - - - - -
public class CarController : Controller
{
public ActionResult Create()
{
Car myCar = new Car();
return View("Create", myCar);
}
[HttpPost]
public ActionResult Create(Car myCar)
{
if (!ModelState.IsValid)
{
return View("Create", myCar);
}
//Do something on success
return View("Index");
}
}
- - - -看法 - - - - - - -
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Car>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<%
using (Html.BeginForm()) {%>
<fieldset>
<legend>Edit User Profile</legend>
<p>
<label for="Id">Id:</label>
<%= Html.TextBox("Id", Model.Id)%>
<%= Html.ValidationMessage("Id") %>
</p>
<p>
<label for="Name">Name:</label>
<%= Html.TextBox("Name", Model.Name)%>
<%= Html.ValidationMessage("Name") %>
</p>
<p>
<label for="Color">Color:</label>
<%= Html.TextBox("Color", Model.Color)%>
<%= Html.ValidationMessage("Color") %>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
</asp:Content>
这就像一个魅力。但并非我的所有观点或模型对象都是简单的。我可能有一个汽车模型对象,例如:
- - -模型 - - - -
public class PaintScheme
{
public int Red { get; set; }
public int Blue { get; set; }
public int Green { get; set; }
}
public class Car
{
public string Id { get; set; }
public string Name { get; set; }
public PaintScheme Paint{ get; set; }
}
- - - -看法 - - - - - - -
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Car>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<%
using (Html.BeginForm()) {%>
<fieldset>
<legend>Edit User Profile</legend>
<p>
<label for="Id">Id:</label>
<%= Html.TextBox("Id", Model.Id)%>
<%= Html.ValidationMessage("Id") %>
</p>
<p>
<label for="Name">Name:</label>
<%= Html.TextBox("Name", Model.Name)%>
<%= Html.ValidationMessage("Name") %>
</p>
<p>
<label for="Red">Color Red:</label>
<%= Html.TextBox("Red", Model.Paint.Red)%>
<%= Html.ValidationMessage("Red") %>
</p>
<p>
<label for="Blue">Color Blue:</label>
<%= Html.TextBox("Blue", Model.Paint.Blue)%>
<%= Html.ValidationMessage("Blue") %>
</p>
<p>
<label for="Green">Color Green:</label>
<%= Html.TextBox("Green", Model.Paint.Green)%>
<%= Html.ValidationMessage("Green") %>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
</asp:Content>
当我添加 绘制方案 在我看来,这些属性不会随传递到我的控制器操作中的“myCar”对象一起继承。有没有办法解决这个问题,而不必从表单集合重建对象,然后检查 ModelState?
解决方案
- 你应该有 公共设置者 对于您想要绑定的属性。我想知道第一个示例对您来说如何工作,因为一切都是私人的。
- 你必须 发布至少一个值 PaintScheme 属性能够绑定它。
- 所有子属性都应以前缀 小路 到它。在哪里 小路 可以定义为 *(PropertyName.)**。
看来第3点在View中并没有得到满足。将视图的适当部分更改为:
<p>
<label for="Red">Color Red:</label>
<%= Html.TextBox("Paint.Red")%>
<%= Html.ValidationMessage("Red") %>
</p>
<p>
<label for="Blue">Color Blue:</label>
<%= Html.TextBox("Paint.Blue")%>
<%= Html.ValidationMessage("Blue") %>
</p>
<p>
<label for="Green">Color Green:</label>
<%= Html.TextBox("Paint.Green")%>
<%= Html.ValidationMessage("Green") %>
</p>
另外请注意,我从 TextBox 帮助器中删除了显式值,以避免可能的 NullReferenceException。
其他提示
要解决这个问题最简单的方法是使用DTO扁平化模型。然后使用automapper到您的域对象映射到您的视图模型。这种转换可能会在您的枚举转换为字符串,并回这样的方式来定义。然后验证将工作和你的BOM不会碰维护您的关注点分离相当不错的观点。
有关颜色的部分,你可以有这样的事情, 作为一个int我不认为你会使用一个文本框,但是这会绑定你的红色(如果输入值是一个数字)
<p>
<label for="Red">Color:</label>
<%= Html.TextBox("Red", Model.Paint.Red)%>
<%= Html.ValidationMessage("Red") %>
</p>
不隶属于 StackOverflow