2009-09-02 2 views
2

Возможность позволить модели обрабатывать собственную проверку позволяет мне начать воспроизведение с предварительного просмотра MVC 2. До сих пор мне нравилась простота схемы проверки. Однако я столкнулся с препятствием. Этот стиль проверки отлично подходит для простых объектов модели просмотра. Например, если у меня есть модель объекта с именем автомобиль и я ищу, чтобы создать представление, чтобы создать новый автомобиль:ASP.NET MVC 2 Предварительный просмотр 1 - Проверка данных с объектами комплексных моделей

----- Модель -------

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> 

Это работает l Это очарование. Но не все мои взгляды, или модельные объекты в этом отношении, просты. Я мог бы объект модели автомобиля, как:

----- Модель -------

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?

+1

Я думаю, что название должно быть изменено на нечто вроде «ASP.NET MVC Binding Nested Object Properties», поскольку оно, похоже, вообще не связано с DataAnnotations. –

ответ

1
  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.

+0

Он оставил их для краткости. – mxmissile

+0

Хорошо. Кажется, я понимаю, что случилось. Обновил ответ соответственно. –

+0

Это было именно то, чего мне не хватало. Спасибо, Дмитрий. –

0

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

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

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

+0

Зачем выравнивать и вводить другую зависимость, а не просто * правильно * использовать функцию (ModelBinding)? Показанная модель не является сложной для ее разбиения. –

+0

Поддержание разделения проблем от слоя к слою почти всегда делает вещи более чистыми. –

Смежные вопросы