ASP.NET MVC 2, предварительная версия 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 не удовлетворен в представлении.Измените соответствующую часть представления на это:
<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>