Рекомендации по обновлению модели модели и модели с подмножеством полей
Выбирая 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.