我对查看模型还比较陌生,在使用它们时遇到了一些问题。在这种情况下,我想知道最佳做法是什么......
我将 View 所需的所有信息放入 View 模型中。这是一个示例 - 请原谅任何错误,这是我脑海中的代码。
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);
}
如果屏幕只允许编辑一个或两个字段,当 View 模型返回时它会丢失相当多的数据(这是应该的)。
[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.
}
}
我的临时解决方案是从头开始重新创建 View 模型,从域模型中重新填充它,将表单数据重新应用到它,然后照常进行。但这使得 View 模型参数有些毫无意义。
[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,我仍然可以使用助手。如果我把我需要显示的内容添加到 View 包(或 View 数据)中,像这样...
ViewBag.Project= project;
然后我可以执行以下操作...
@Html.LabelFor(model => ((Project)ViewData["Project"]).Name)
@Html.DisplayFor(model => ((Project)ViewData["Project"]).Name)
有点 hack,在某些情况下它需要用 System.ComponentModel.DisplayNameAttribute
修饰域模型,但我已经这样做了。
我很想调用...
@Html.LabelFor(model => ViewBag.Project.Name)
但是动态会导致表达式出现问题。
最佳答案
经过反复试验(又名编写代码,然后讨厌它)学习后,我目前首选的方法是:
我仅使用 View 模型来绑定(bind)输入字段。所以在你的情况下,如果你的 View 只编辑两个字段,那么你的 View 模型将只有两个属性。对于填充 View 所需的数据(下拉列表、标签等),我使用动态 ViewBag。
我认为显示 View (即填充 View 需要显示的任何内容)和捕获发布的表单值(绑定(bind)、验证等)是两个独立的问题。而且我发现将填充 View 所需的数据与从 View 回发的数据混合在一起会变得困惑,并且经常会准确地创建您的情况。我不喜欢传递部分填充的对象。
不过,我不确定这对 Automapper(用于将域对象映射到动态 ViewBag)如何发挥作用,因为我还没有使用过它。我相信它有一个可能有效的 DynamicMap 方法?将发布的强类型 ViewModel 自动映射到域对象上应该没有任何问题。
关于c# - 在 ASP.NET MVC 3 中使用 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5306655/