MVC 3 + EF 4.1 + POCO + ViewModel模式+带脚手架的控制器==混乱!

时间:2011-05-20 02:47:24

标签: asp.net-mvc-3 entity-framework-4 razor viewmodel poco

经过多年的ASP.NET表单开发后,我[终于!]处理了MVC(版本3)。我在n层应用程序架构方面有很强的背景,我正在尝试正确地处理这个新项目,明确区分关注点等。

我所做的是通过创建我的POCO以代码优先开始。由此,框架创建了我的数据库。

然后,我通过将所有我的EF查询和CRUD方法放在我的Models程序集中的每个POCO类的Repository类中来实现Repository模式。这样,我的控制器不需要知道如何通过EF访问我的数据。大。

最后,我在Models程序集中创建了一些ViewModel类。我的意图是,对于某些操作(例如创建和编辑),我从RAZOR视图中引用我的ViewModel类,而不是我的POCO类。这样,我可以使用我的POCO类和SelectList来填充ViewModel中的Dropdown。两者都通过引用相关的Repository类来填充,这些类是从我的Controller Actions中调用的。我想我现在正在滚动:

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...
    // ..........

}

问题......

在我开始使用Controller Create和Edit操作中的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)时,一切都崩溃了。

我可以通过在编辑视图顶部设置@model引用来引用我的ViewModel(MyViewModel)。然后我能够从我的POCO类(MyObject)填充我的表单字段,该类是ViewModel的一部分。我甚至能够从ViewModel中的SomeObjects集合填充DropDownList,并从我正在编辑的MyObject类中预选正确的DropDownList。一切似乎都很好 UNTIL ......

当我点击保存按钮并调用Controller的Edit ActionResult(POST动作)时,传递给ActionResult的MyObject类(公共ActionResult Edit(MyObject mine))为null。

然后,我尝试将传入的对象更改为我的ViewModel(公共ActionResult编辑(MyViewModel myVM)),其中引用的MyObject类(MyModel)为null。

我缺少什么?

我知道它必须是非常简单的东西,它正盯着我,我无法看到它!

2 个答案:

答案 0 :(得分:2)

查看FormCollection,键的名称应与要填充的类的属性相匹配。这就是MVC的默认模型绑定的工作原理。

答案 1 :(得分:1)

维姆,

非常感谢你的帮助。我确实有s参数构造函数,我刚从示例中省略了它。

我实际上已经找到了问题。平心而论,我输入的代码不是真正的代码,因为当我发布这个时,我没有把它放在我面前。问题是我的ViewModel中的实体模型类引用实际上将其set访问器设置为私有:

public MyObject MyModel {get;private set;}

这阻止了模型绑定器在控制器的保存方法期间回发时填充该属性。

我现在要做的就是将我的验证逻辑从我的EF POCO移到我的ViewModel,这似乎是这种模式中推荐的操作。

感谢您的时间,我希望这可以帮助那些对此框架不熟悉的类似问题的人。