【发布时间】:2011-07-15 11:12:28
【问题描述】:
我对查看模型比较陌生,并且在使用它们时遇到了一些问题。这是我想知道最佳做法的一种情况......
我将视图所需的所有信息放入视图模型中。这是一个例子——请原谅任何错误,这是我头脑中的代码。
public ActionResult Edit(int id)
{
var project = ProjectService.GetProject(id);
if (project == null)
// Something about not found, possibly a redirect to 404.
var model = new ProjectEdit();
model.MapFrom(project); // Extension method using AutoMapper.
return View(model);
}
如果屏幕只允许编辑一个或两个字段,当视图模型返回时,它会丢失相当多的数据(应该如此)。
[HttpPost]
public ActionResult Edit(int id, ProjectEdit model)
{
var project = ProjectService.GetProject(id);
if (project == null)
// Something about not found, possibly a redirect to 404.
try
{
if (!ModelState.IsValid)
return View(model) // Won't work, view model is incomplete.
model.MapTo(project); // Extension method using AutoMapper.
ProjectService.UpdateProject(project);
// Add a message for the user to temp data.
return RedirectToAction("details", new { project.Id });
}
catch (Exception exception)
{
// Add a message for the user to temp data.
return View(model) // Won't work, view model is incomplete.
}
}
我的临时解决方案是从头开始重新创建视图模型,从域模型重新填充它,将表单数据重新应用到它,然后照常进行。但这使得视图模型参数有些毫无意义。
[HttpPost]
public ActionResult Edit(int id, ProjectEdit model)
{
var project = ProjectService.GetProject(id);
if (project == null)
// Something about not found, possibly a redirect to 404.
// Recreate the view model from scratch.
model = new ProjectEdit();
model.MapFrom(project); // Extension method using AutoMapper.
try
{
TryUpdateModel(model); // Reapply the form data.
if (!ModelState.IsValid)
return View(model) // View model is complete this time.
model.MapTo(project); // Extension method using AutoMapper.
ProjectService.UpdateProject(project);
// Add a message for the user to temp data.
return RedirectToAction("details", new { project.Id });
}
catch (Exception exception)
{
// Add a message for the user to temp data.
return View(model) // View model is complete this time.
}
}
有没有更优雅的方式?
编辑
两个答案都是正确的,所以如果可以的话,我会奖励他们两个。不过,我向 MJ 点头,因为经过反复试验,我发现他的解决方案是最精简的。
我仍然可以使用助手,Jimmy。如果我将需要显示的内容添加到视图包(或视图数据)中,就像这样......
ViewBag.Project= project;
然后我可以执行以下操作...
@Html.LabelFor(model => ((Project)ViewData["Project"]).Name)
@Html.DisplayFor(model => ((Project)ViewData["Project"]).Name)
有点小技巧,在某些情况下它需要用System.ComponentModel.DisplayNameAttribute 装饰域模型,但我已经这样做了。
我很想打电话...
@Html.LabelFor(model => ViewBag.Project.Name)
但动态会导致表达式出现问题。
【问题讨论】:
-
你可以在这里查看:prodinner.codeplex.com 了解 asp.net mvc 中的最佳实践(包括视图模型)
标签: c# asp.net-mvc-3 viewmodel automapper