ASP.NET MVC 2, предварительная версия 1. Проверка аннотации данных с помощью сложного объекта модели

StackOverflow https://stackoverflow.com/questions/1365511

Вопрос

Возможность позволить модели выполнять собственную проверку побудила меня начать экспериментировать с предварительной версией 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?

Это было полезно?

Решение

  1. Вы должны иметь публичный установщик для свойств, которые вы хотите связать.Интересно, как для вас работает первый образец, поскольку все конфиденциально.
  2. Вы должны опубликуйте хотя бы одно значение свойства PaintScheme, чтобы иметь возможность привязать его.
  3. Все дочерние свойства должны иметь префикс путь к этому.Где путь может быть определено как *(PropertyName.)**.

Кажется, пункт 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.

Другие советы

Самый простой способ справиться с этим — сгладить вашу модель с помощью dto.Затем используйте automapper, чтобы сопоставить объект домена с вашей моделью представления.Этот перевод можно определить таким образом, чтобы вы преобразовывали перечисление в строку и обратно.Тогда проверка будет работать, и ваш бом не будет касаться представления, сохраняя достаточно хорошее разделение задач.

Для цветной части вы можете иметь что -то подобное, будучи Int, я не думаю, что вы будете использовать текстовое поле, но это свяжет ваш красный цвет (если входное значение - это число)

 <p>
                <label for="Red">Color:</label>
                <%= Html.TextBox("Red", Model.Paint.Red)%>
                <%= Html.ValidationMessage("Red") %>
 </p>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top