13

通过选择 MVC 来开发我们的新站点,我发现自己处于明显实时的“最佳实践”之中。两周前,NerdDinner 是我的向导,但随着 MVC 2 的发展,即使它似乎已经过时了。这是一次激动人心的经历,我很荣幸能每天与聪明的程序员密切接触。

现在我偶然发现了一个我似乎无法直接回答的问题 - 无论如何来自所有博客 - 我想从社区中获得一些见解。这是关于编辑(阅读:编辑操作)。那里的大部分材料、教程和博客都涉及创建和查看模型。因此,虽然这个问题可能无法说明问题,但我希望能够进行一些讨论,为我决定我要走的发展道路做出贡献。

我的模型代表一个具有多个字段(如姓名、地址和电子邮件)的用户。事实上,所有的名字都在字段上,分别是名字、姓氏和中间名。详细信息视图显示所有这些字段,但您一次只能更改一组字段,例如您的姓名。用户展开一个表单,而其他字段仍然在上方和下方可见。因此,回发的表单包含代表模型的字段子集。

虽然这对我们和我们的布局问题很有吸引力,但由于各种原因,严重的 MVC 开发人员应该回避它。我一直在阅读一些模式和最佳实践,这似乎与 viewmodel == view 的范式不相符。还是我弄错了?

无论如何,NerdDinner 规定使用 FormCollection och UpdateModel。所有空字段都被愉快地忽略了。从那时起,MVC 社区已经放弃了这种方法,以至于没有发现 MVC 2 中的错误。如果您的 formcollection 中没有完整的模型,UpdateModel 将无法工作。

获得最多赞誉的视图模型模式似乎是包含自定义视图模型实体的专用视图模型,并且是唯一可以与我的设计问题兼容的视图模型。它需要大量的映射,尽管使用AutoMapper和 Jimmy Bogard 的想法有所减轻,这可能值得,也可能不值得。他还提出了视图和视图模型之间的 1:1 关系。

为了与这些设计范例保持一致,我将为我不断扩展的每个字段集创建一个视图和关联视图。每个视图模型几乎相同,只是在只读字段上有所不同,视图还包含许多重复的标记。这对我来说似乎很荒谬。将来我可能希望能够显示同时打开的两个、更多或所有字段集。

我会仔细阅读我希望引发的讨论。提前谢谢了。

4

4 回答 4

3

我正在这样做(映射是在 modelBuilder 中使用ValueInjecter自动完成的):

我有一个示例 asp.net-mvc 应用程序,我在其中演示了在 mvc 中执行此操作的最佳实践,您可以在 valueinjecter 的下载中看到它

 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);
于 2010-06-11T06:52:16.743 回答
2

最近有一些关于验证模型问题的帖子,导致了 Brad Wilson 的这篇帖子“输入验证与 ASP.NET MVC 中的模型验证”。

最初的问题与 ASP.NET MVC 如何处理验证发布的模型有关,以及是否存在您不想编辑的模型元素并且没有在视图中提供字段,但您的控制器正在使用在整个模型中,有人可能会为您的控制器制作一个带有附加字段的 POST。

因此,使用特定于视图的模型使您能够确保只有您想要编辑的字段才能被编辑。

于 2010-01-26T23:12:44.420 回答
0

我有完全相同的问题,但我无法很好地制定它。

就我而言,会有大量的 ViewModel,因为不同的用户会根据一组角色看到不同的表单。我认为 ViewModel 和 View 之间的 1:1 关系非常模糊。如果我编写一个几乎只使用EditorForModel而不是更多的超级视图怎么办?现在我有一个,虽然高度退化,所有的视图,所以我也只有一个 ViewModel?

我的想法是编写一个EditorForModel不仅基于反射(即编译时已知的信息)而且基于(特定于域的)运行时规则的工作,例如由当前用户的角色、当前时间等管理。因此,还需要编写一个ModelBinder带有验证的自定义以及从 Model 到 ViewModel 的自定义映射。尽管如此,这使我无法编写愚蠢且容易出错的代码。

由于我的模型(或 DomainModel)包含很多逻辑,我根本不希望通过 ModelBinding 对其进行修改。此外,由于不可能知道编译时会出现哪些字段,因此不可能提供合适的 ViewModel。但是,“完整”,即最大 ViewModel 是已知的。从 ViewModel 到 Model 的映射再次涉及自定义代码,但只要可以形式化规则,那应该可以解决。

对不起,我的文字很混乱,但我自己现在很困惑,而且我得跑了。像CT一样,也无法发表评论。

于 2010-01-25T17:29:59.290 回答
0

看一下这个。这是使用 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 中的可扩展模型绑定器。

于 2010-04-08T20:36:23.587 回答