MVC 3 + EF 4.1 + POCOs + шаблон ViewModel + Контроллер с лесами == путаница! - PullRequest
2 голосов
/ 20 мая 2011

Я [наконец-то!] Занимаюсь MVC (версия 3) после многих лет разработки форм ASP.NET. У меня большой опыт работы в n-уровневой архитектуре приложений, и я стараюсь подходить к этому новому проекту правильно, с четким разделением интересов и т. Д.

То, что я сделал, это начнем с кода вначале, создав мои POCO. Исходя из этого, фреймворк создал мою базу данных.

Затем я реализовал шаблон Repository, поместив все мои EF-запросы и методы CRUD в класс Repository для каждого из моих классов POCO в моей сборке Models. Таким образом, моим контроллерам не нужно ничего знать о том, как я получаю доступ к своим данным через EF. Отлично.

Наконец, я создал несколько классов ViewModel в моей сборке Models. Мое намерение состоит в том, чтобы при определенных действиях (таких как создание и редактирование) я ссылался на мои классы ViewModel из представлений RAZOR, а не на мои классы POCO. Таким образом, у меня может быть свой класс POCO, а также список SelectList для заполнения раскрывающегося списка в моей 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 из действий Controller Create и Edit, я напрямую перешел в класс 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 в верхней части моего представления Edit. Затем я смог заполнить поля формы из моего класса POCO (MyObject), который является частью ViewModel. Я даже смог заполнить DropDownList из коллекции SomeObjects в ViewModel и предварительно выбрать правильный из моего класса MyObject, который я редактировал. Все выглядело хорошо ДО ...

Когда я нажал кнопку «Сохранить», и мой контроллер вызвал команду Edit ActionResult (действие POST), класс MyObject, который передается в ActionResult (общедоступное действие ActionResult (MyObject mine)), был равен нулю.

Затем я попытался изменить переданный объект на мой ViewModel (общедоступное редактирование ActionResult (MyViewModel myVM)), в котором класс MyObject (MyModel), на который ссылаются, равен нулю.

Чего мне не хватает?

Я знаю, что это должно быть что-то настолько невероятно простое, что это смотрит мне в лицо, и я не могу этого видеть!

Ответы [ 2 ]

2 голосов
/ 20 мая 2011

Посмотрите на FormCollection, имена ключей должны соответствовать свойствам класса, который вы хотите заполнить.Так работает привязка модели MVC по умолчанию.

1 голос
/ 23 мая 2011

Wim

Большое спасибо за вашу помощь. У меня был конструктор без параметров, я просто опустил его из примера.

Я на самом деле разыскал проблему. Справедливости ради, код, который я набрал, не был реальным кодом, так как у меня не было его передо мной, когда я отправил это. Проблема заключалась в том, что моя ссылка на класс модели сущности в моей ViewModel фактически имела установленный метод доступа как private:

public MyObject MyModel {get;private set;}

Это помешало связующему с моделями заполнить это свойство при повторной публикации во время метода сохранения контроллера.

Что мне осталось сделать, так это переместить мою логику проверки из моего EF POCO в мою ViewModel, что, как представляется, является рекомендуемым действием в этом типе шаблона.

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

...