Как внести в белый / черный список дочерних полей объекта в методе ModelBinder / UpdateModel? - PullRequest
7 голосов
/ 05 июня 2009

У меня есть вопрос относительно того, как получить функцию белого и черного списков в UpdateModel / TryUpdateModel контроллера MVC для работы с отдельными свойствами дочерних объектов. Например, допустим, у меня есть вопросник, собирающий информацию о человеке, заполняющем форму, и о его или ее компании.

Мои [упрощенные] поля формы будут названы, например:

YourName
YourEmail
Company.Name
Company.Phone

Теперь в моей модели допустим, что я не хочу, чтобы подделывали Company.ID или Company.IsPremiumMember, поэтому я бы хотел исключить их из привязки модели. Я попробовал комбинацию белого списка, черного списка, и обоих, чтобы заставить это работать. У меня не было никакого успеха. Вот то, с чем я сталкиваюсь:

Когда я явно включаю в свой белый список те же четыре имени поля, которые я написал выше, вся Компания не становится связанной (т. Е. Вопросник. Компания не имеет значения), если только я не включаю "Компанию" в свой белый список. Но тогда это имеет нежелательный эффект связывания ВСЕЙ компании, а не только двух свойств, которые я хочу.

Итак, я попытался включить Company.ID и Company.IsPremiumMember в свой черный список, но это похоже на белый список, и оно не отфильтровывает эти свойства «после факта», я полагаю.

Я знаю, что есть и другие способы выражения «привязываемости», например, через атрибут [Bind] для членов, но это не идеально, так как я хотел бы использовать те же классы моделей, которые используются в других ситуациях с другим связыванием правила, такие как разрешение администратору устанавливать любые свойства, которые ему нравятся.

Я ожидаю, что очевидный ответ заключается в том, что я должен написать свой собственный механизм связывания моделей, и я уже начал пытаться разобраться, как, возможно, сделать это, но я действительно надеялся использовать "из коробки" «Решение для того, что (на мой взгляд) кажется очень распространенным сценарием. Еще одна идея, над которой я размышляю, состоит в том, чтобы изготовить свой собственный словарь ValueProvider для передачи в метод UpdateModel, но, опять же, я бы предпочел этого избежать, если есть более простой способ.

Спасибо за любую помощь! -Mike

<ч /> Приложение № 1

Вот поля, которые я представляю в моей форме:

YourName
YourEmail
Company.Name
Company.Phone

А вот что посылает мне черная шляпа:

YourName=Joe+Smith&YourEmail=joe@example.com&Company.Name=ACME+Corp&Company.Phone=555-555-5555&Company.CreditLimit=10000000

(убедитесь, что вы заметили дополнительный параметр, добавленный в конце!)

А вот и проблема:

Как я писал ранее, не представляется возможным (с использованием связывателя модели по умолчанию) помешать установке CreditLimit - либо всей компании, либо ничего - без какого-либо большого обходного пути. Я не прав?

<час /> Приложение № 2

Теперь я почти уверен, что простая цель, которую я имею, невозможна "из коробки". Мое решение состояло в том, чтобы пройтись по полям опубликованной формы и создать свой собственный словарь ValueProvider, составив таким образом белый список полей, которые я хочу разрешить, и передать его в UpdateModel.

<ч /> Приложение № 3

Я до сих пор еще не опробовал AutoMapper, но с чем-то вроде этого под рукой решение по созданию некоторых ViewModels / DTO для обработки такого типа сложных белых списков --- плюс возможность легко присоединить ту же проверку на стороне сервера (FluentValidation) Я уже использую свои доменные объекты - кажется жизнеспособным решением. Спасибо всем!

Ответы [ 3 ]

1 голос
/ 08 июня 2009

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

1 голос
/ 06 июня 2009

Я обошел эту проблему, приняв действие, принимающее два объекта (родительский и дочерний объект)

Пример:
Предположим, у нас есть следующая модель:

 public class Employee
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Company Comapany { get; set; }
    }
    public class Company
    {
        public int Phone { get; set; }
    }

Вы строите свою форму так:

    <form action="Home/Create" method="post">
   <label for="Employee.Name">Name</label>
    <%=Html.TextBox("Employee.Name") %><br />
   <label for="Employee.Name">Age</label>    
    <%=Html.TextBox("Employee.Age") %><br />
   <label for="Employee.Name">Comapany Phone</label>    
    <%=Html.TextBox("Company.Phone") %><br />
    <input type="submit" value="Send" />
   </form>

Затем создайте действие «Создать», которое принимает два объекта, один из которых имеет тип Employee, а другой - тип Comapny, и присваивает объект Company свойству Employee.Company внутри действия:

 public ActionResult Create(Employee employee,Company company)
        {
            employee.Comapany = company;
            UpdateModel(employee);
            return View();
        }

Надеюсь, это поможет вам.

Редактировать:

public ActionResult Create(Employee employee,Company company)
{
   employee.Comapany = company;
   UpdateModel(employee,new[] {"Name","Email","Phone"});
   return View();
}
0 голосов
/ 01 июля 2009

Вы пробовали использовать следующее?

public ActionResult Create ([Bind (Exclude = "PropertyToExclude1, PropertyToExclude2")] сотрудник сотрудника) {

// код действия здесь

}

или используйте «Включить» вместо «Исключить в список», какие поля могут быть связаны, а какие нет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...