Рекомендации по обновлению модели модели и модели с подмножеством полей

Выбирая MVC для разработки нашего нового сайта, я нахожусь в разгаре "лучших практик", разрабатываемых вокруг меня в явном реальном времени. Две недели назад NerdDinner был моим проводником, но с разработкой MVC 2, даже он устарел. Это захватывающий опыт, и я чувствую себя привилегированным в тесном контакте с умными программистами ежедневно.

Прямо сейчас я наткнулся на проблему, на которую я не могу ответить, - со всех блогов, и я хотел бы получить некоторое представление от сообщества. Это о редактировании (см. Действие "Изменить" ). Основная часть материала, учебники и блоги, посвящена созданию и просмотру модели. Поэтому, хотя этот вопрос может и не задавать вопрос, я надеюсь, что вы продолжите обсуждение, внося свой вклад в мое решение о пути развития, который я должен предпринять.

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

Несмотря на то, что это привлекательно для нас, и наши макеты, по разным причинам, следует избегать серьезных MVC-разработчиков. Я читал о некоторых шаблонах и лучших практиках, и кажется, что это не является ключом к парадигме viewmodel == view. Или я ошибаюсь?

В любом случае, NerdDinner диктует использование FormCollection och UpdateModel. Все нулевые поля счастливо игнорируются. С тех пор сообщество MVC отказалось от такого подхода до такой степени, что ошибка в MVC 2 не была обнаружена. UpdateModel не работает без полной модели в вашем формате.

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

В соответствии с этими парадигмами дизайна я должен создать представление и связанный с ним вид для каждого из моих расширяющихся наборов полей. Модели просмотра будут почти одинаковыми, отличающимися только полями, доступными только для чтения, и представления, которые также содержат много повторяющуюся разметку. Мне это кажется абсурдным. В будущем я могу захотеть одновременно отображать два, более или все наборы полей.

Я очень внимательно прочитаю дискуссию, которую я надеюсь испустить. Большое спасибо заранее.

Ответы

Ответ 1

Я делаю это так (сопоставление выполняется автоматически внутри modelBuilder с ValueInjecter)

У меня есть приложение sample asp.net-mvc application, где я демонстрирую лучшие практики этого в mvc, вы можете увидеть его в загрузка значения инжектора

 public ActionResult Edit(long id)
 {
      return View(modelBuilder.BuildModel(personService.Get(id)));
 }

 [HttpPost]
 public ActionResult Edit(PersonViewModel model)
 {
    if (!ModelState.IsValid)
       return View(modelBuilder.RebuildModel(model));    
       personService.Save(modelBuilder.BuildEntity(model));
       return RedirectToAction("Index");
 }

краткое описание ValueInjecter:

//build viewmodel
    personViewModel.InjectFrom(person)
                   .InjectFrom<CountryToLookup>(person);

//build entity
    person.InjectFrom(personViewModel)
          .InjectFrom<LookupToCountry>(personViewModel);

Ответ 2

Недавно появилось несколько сообщений о проверке ваших моделей, в результате чего этот пост от Брэда Уилсона "" Вводная проверка "или" Проверка модели в ASP ".NET MVC".

Первоначальная проблема заключалась в том, как ASP.NET MVC обработала проверку опубликованной модели, и если бы были элементы вашей модели, которые вы не хотели редактировать и не предоставляли поля для представления, но ваши контроллеры работали со всей моделью, возможно, что кто-то может создать POST для вашего контроллера с дополнительными полями.

Поэтому использование View Spec Model позволяет вам отредактировать только те поля, которые вы хотите отредактировать.

Ответ 3

У меня есть одна и та же проблема, но я бы не смог ее правильно сформулировать.

В моем случае было бы много ViewModels, потому что разные пользователи будут видеть разные формы на основе набора ролей. Я думаю, что соотношение 1:1 между ViewModel и View очень расплывчато. Что делать, если я пишу uber-View, который просто использует EditorForModel и не намного больше? Теперь у меня есть один, хотя и сильно вырожденный, взгляд на все, поэтому у меня также есть только один ViewModel?

Моя идея состояла в том, чтобы написать EditorForModel, который работает не только на основе рефлексии (то есть информации, известной во время компиляции), но также и на (определенных для домена) правилах выполнения, например, определяемых текущей ролью пользователя, текущее время и т.д. Следовательно, также необходимо написать пользовательский ModelBinder с проверкой, а также настраиваемое сопоставление от Model to ViewModel. Тем не менее, это мешает мне писать глупый и, следовательно, код, подверженный ошибкам.

Так как моя модель (или DomainModel) содержит много логики, я не хочу, чтобы она была модифицирована с помощью ModelBinding. Более того, поскольку невозможно узнать, какие поля будут присутствовать во время компиляции, обеспечить подходящую ViewModel невозможно. Тем не менее, "полный", т.е. Максимальный ViewModel, известен. Картирование из ViewModel в модель снова включает в себя настраиваемый код, но до тех пор, пока правила могут быть формализованы, это должно получиться.

Извините, мой текст очень запутан, но я очень смущен прямо сейчас, плюс я должен бежать. Подобно C.T., также не мог комментировать.

Ответ 4

Проверьте это. Это путь к ASP.NET MVC 2.

        public void Update(MyModel model)
        {
            var myModelObject = MyRepository.GetInstance(model.Id);
            if(myModelObject != null)
            {
                ModelCopier.CopyModel(model, myModelObject);
            }
            MyRepository.Save(myModelObject);
        }

ModelCopier.CopyModel(obj from, obj to) - это новая функция в последнем MvcFutures. Также обязательно ознакомьтесь с расширительной вставкой модели в MVC Futures 2.