通过选择MVC来开发我们的新网站,我发现自己正处于围绕着我的“最佳实践”中实时开发。两周前,NerdDinner是我的向导,但随着MVC 2的发展,即使它看起来已经过时了。这是一次激动人心的经历,我很荣幸能够每天与智能程序员保持密切联系。
现在我偶然发现了一个似乎无法直接回答的问题 - 无论如何都要从所有博客中得到答案 - 我想从社区中获得一些见解。这是关于编辑(阅读:编辑动作)。大量的材料,教程和博客,涉及创建和查看模型。因此,尽管这个问题可能没有提出问题,但我希望能够进行一些讨论,这有助于我决定我将采取的发展道路。
我的模型代表具有多个字段的用户,例如姓名,地址和电子邮件。实际上,所有名称都在字段上,每个名称都有名字,姓氏和中间名。 “详细信息”视图显示所有这些字段,但您一次只能更改一组字段,例如,您的名称。用户展开表单,而其他字段在上方和下方仍然可见。因此,回发的表单包含表示模型的字段的子集。
虽然这对我们和我们的布局问题很有吸引力,但由于各种原因,它会被严肃的MVC开发人员所避开。我一直在阅读一些模式和最佳实践,看起来这与viewmodel == view的范例无关。或者我弄错了?
无论如何,NerdDinner指示使用FormCollection och UpdateModel。所有空字段都被高兴地忽略了。从那以后,MVC社区已经放弃了这种方法,以至于没有发现MVC 2中的bug。如果没有表单集中的完整模型,UpdateModel将无法运行。
获得最多赞誉的view model pattern似乎是包含自定义视图模型实体的专用视图模型,并且是我的设计问题唯一可以与之兼容的模型。它需要进行繁琐的绘图,尽管使用AutoMapper和吉米·博加德的ideas可以减轻这种情况,这可能是也可能是不值得的。他还提出了视图和视图模型之间的1:1关系。
为了与这些设计范例保持一致,我将为每个扩展字段集创建一个视图和相关视图。视图模型将各自几乎相同,仅在只读字段中不同,视图也包含多次重复标记。这对我来说似乎很荒谬。将来我可能希望能够同时显示两个,更多或所有字段集。
我会非常认真地阅读我希望引发的讨论。非常感谢提前。
答案 0 :(得分:3)
我这样做(映射是使用ValueInjecter在modelBuilder中自动完成的):
我有一个示例asp.net-mvc应用程序,其中我演示了在mvc中执行此操作的最佳做法,您可以在download of the 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);
答案 1 :(得分:2)
最近有一些关于验证模型的帖子,导致Brad Wilson“Input Validation vs. Model Validation in ASP.NET MVC”的这篇文章。
最初的问题与ASP.NET MVC如何处理验证已发布的模型有关,以及您的模型中是否存在您不想编辑但未在视图中提供字段的元素,而是您的控制器正在使用整个模型,有人可能会使用其他字段为您的控制器制作一个POST。
因此,使用View特定模型可以确保只能编辑您想要编辑的字段。
答案 2 :(得分:0)
我有完全相同的问题,但我不能很好地制定它。
在我的情况下,会有大量的ViewModel,因为不同的用户会根据一组角色看到不同的表单。我认为ViewModel和View之间的1:1关系非常模糊。如果我写一个非常简单地使用EditorForModel
而不是更多的超级视图怎么办?现在我有一个,虽然高度退化,但对于一切,我也只有一个ViewModel?
我的想法是写一个EditorForModel
,它不仅基于反射(即编译时已知的信息),而且基于(特定于域的)运行时规则,例如由当前用户的角色控制因此,还需要编写带有验证的自定义ModelBinder
以及从Model到ViewModel的自定义映射。尽管如此,这使我无法编写愚蠢的错误代码。
由于我的Model(或DomainModel)包含很多逻辑,我不希望它通过ModelBinding进行修改。此外,由于无法知道编译时将出现哪些字段,因此无法提供适当的ViewModel。然而,'full',即最大ViewModel是已知的。从ViewModel到模型的映射再次涉及自定义代码,但只要规则可以正式化,那就应该有效。
抱歉,我的文字非常令人困惑,但我现在很困惑,加上我要跑。像C.T.一样,也无法评论。
答案 3 :(得分: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中的Extensible Model Binder。