#asp.net-mvc-3 #entity-framework-4 #razor #viewmodel #poco
#asp.net-mvc-3 #entity-framework-4 #бритва #viewmodel #poco
Вопрос:
Я [наконец-то!] решение MVC (версии 3) после многих лет ASP.NET разработка форм. У меня большой опыт работы с n-уровневой архитектурой приложений, и я пытаюсь подойти к этому новому проекту должным образом, с четким разделением задач и т.д.
Что я сделал, так это начал с кода -сначала создав свои POCOs. На основе этого фреймворка была создана моя база данных.
Затем я реализовал шаблон репозитория, поместив все мои методы EF query и CRUD в класс репозитория для каждого из моих классов POCO в сборке моих моделей. Таким образом, моим контроллерам не нужно ничего знать о том, как я получаю доступ к своим данным через EF. Отлично.
Наконец, я создал несколько классов ViewModel в моей сборке Models. Мое намерение состоит в том, чтобы для определенных действий (таких как создание и редактирование) я ссылался на свои классы ViewModel из представлений RAZOR, а не на свои классы POCO. Таким образом, у меня может быть свой класс POCO, а также список выбора для заполнения выпадающего списка в моей ViewModel. Оба заполнены ссылками на связанные классы репозитория, которые вызываются из моих действий контроллера. Я думаю, что теперь я в ударе:
class MyObject
{
public int ID {get;set}
[Required]
[StringLength(512)]
public string Name {get;set;}
}
class MyViewModel // ViewModel for a specific view
{
public MyObject MyModel {get;set;} // the model that is being edited
// other data the view might need, set by the controller
public string SomeMessage { get; set; }
public List<SomeObject> SomeObjects {get;set;} /// e.g. for a drop-down list
// My constructor below that populates the "SomeObjects" list, and accepts the
// "MyObject" class as a parameter in order to set the "MyModel" property above...
// ..........
}
Проблема…
Прежде чем я начал использовать свои классы ViewModel из действий создания и редактирования моего контроллера, я передал класс POCO напрямую. Все работало нормально, когда я нажал кнопку сохранения из моей формы редактирования в моем представлении:
Старый код:
[HttpPost]
public ActionResult Edit(MyObject mine)
{
if (ModelState.IsValid)
{
myRepository.Update(mine);
myRepository.SaveChanges();
return RedirectToAction("Index");
}
return View(mine);
}
Когда я нажимал сохранить, мой класс POCO (MyObject) возвращался, автоматически заполнялся значениями из формы, он успешно сохранялся, и жизнь была прекрасна.
Когда я переключился на передачу моей ViewModel (MyViewModel), все развалилось.
Я смог ссылаться на свою ViewModel (MyViewModel), установив ссылку @model в верхней части моего вида редактирования. Затем я смог заполнить поля моей формы из моего класса POCO (MyObject), который является частью ViewModel. Я даже смог заполнить выпадающий список из коллекции SomeObjects в ViewModel и предварительно выбрать правильный из моего класса MyObject, который я редактировал. Все казалось прекрасным, ПОКА…
Когда я нажал кнопку сохранения и был вызван результат редактирования ActionResult моего контроллера (POST action), класс MyObject, который передается в ActionResult (public ActionResult Edit(MyObject mine)), был равен нулю.
Затем я попытался изменить переданный объект на мой ViewModel (public ActionResult Edit(MyViewModel myVM)), в котором класс MyObject, на который ссылается MyObject (MyModel), равен null.
Чего мне не хватает?
Я знаю, что это должно быть что-то настолько невероятно простое, что это бросается мне в глаза, и я не могу этого видеть!
Ответ №1:
Посмотрите на FormCollection, имена ключей должны соответствовать свойствам класса, который вы хотите заполнить. Вот как работает привязка модели MVC по умолчанию.
Комментарии:
1. Дело в том, что я не менял названия ключей в FormCollection. Это работало, когда я изначально ссылался только на свой класс POCO в объявлении @model представления. Когда я изменил объявление @model на свой класс ViewModel, именно тогда все перестало работать. Я знаю, что здесь мне не хватает чего-то простого.
2. Я только что увидел комментарий о конструкторе MyViewModel. Modelbinder ожидает конструктор без параметров.
Ответ №2:
Wim,
Большое спасибо за вашу помощь. У меня действительно был конструктор без параметров, я просто опустил его из примера.
Я действительно отследил проблему. Справедливости ради, код, который я ввел, не был фактическим кодом, поскольку у меня его не было передо мной, когда я публиковал это. Проблема заключалась в том, что ссылка на класс моей модели объекта в моей ViewModel фактически имела свой набор доступа как закрытый:
public MyObject MyModel {get;private set;}
Это помешало modelbinder заполнить это свойство при повторной публикации во время метода сохранения контроллера.
Что мне осталось сделать сейчас, так это перенести мою логику проверки из моего EF POCO в мою ViewModel, как, кажется, рекомендуемое действие в шаблоне такого типа.
Спасибо за ваше время, и я надеюсь, что это поможет другим людям с подобными проблемами, которые являются новичками в этом фреймворке.
Комментарии:
1. Здорово, что вы решили свою проблему! Задайте свой ответ в качестве решения, чтобы другие могли видеть, что на вопрос дан ответ.