ASP.NET MVC 2预览1 - 使用复杂模型对象进行DataAnnotation验证

时间:2009-09-02 01:50:47

标签: asp.net-mvc asp.net-mvc-2 asp.net-mvc-validation

让模型处理自己的验证的能力使我开始玩MVC 2预览版。到目前为止,我喜欢验证方案的简单性。但是,我遇到了障碍。此验证样式适用于简单视图模型对象。例如,如果我有一个名为 car 的模型对象,并且我想创建一个视图来创建一辆新车:

----- -------模型

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>

当我将 PaintScheme 属性添加到我的视图中时,它们不会被传递到我的控制器操作中的“myCar”对象。有没有办法解决这个问题,而无需从表单集合重建对象,然后检查ModelState?

3 个答案:

答案 0 :(得分:1)

  1. 您应该为要绑定的属性设置公共设置器。 我想知道第一个样本是如何为你工作的,因为一切都是私有的。
  2. 您必须发布至少一个值的PaintScheme属性才能绑定它。
  3. 所有子属性都应以路径作为前缀。其中 path 可以定义为*(PropertyName。)**。
  4. 在View中似乎不满足第3点。将视图的相应部分更改为:

            <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。

答案 1 :(得分:1)

处理此问题的最简单方法是使用dto展平您的模型。然后使用automapper将域对象映射到视图模型。可以通过将枚举转换为字符串并将其转换为这种方式来定义此转换。然后验证将起作用,你的bom将不会触及视图,保持你对关注点的分离。

答案 2 :(得分:0)

对于颜色部分你可以有这样的东西, 是一个int我不认为你会使用文本框,但这将绑定你的红色(如果输入值是一个数字)

 <p>
                <label for="Red">Color:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
 </p>