当您遇到这样的场景时,是时候开始考虑使用 ViewModels 和 EditModels,它们是专门用于显示 View 所需的确切属性的模型。
这样做的一种策略:
- 在您的项目中创建新文件夹:ViewModels 和 EditModels。
- 对于每个详细信息视图,添加一个 ViewModel 类,对于每个编辑/创建视图,添加一个 EditModel 类。
- 在您的控制器中,当页面第一次被请求时,从您的实体映射到您的 ViewModel/EditModel。在回发时,执行验证并将 EditModel 映射回实体。
几点注意事项:
- 这确实增加了一些工作,但它确实是利用 MVC 的强类型视图功能的唯一可靠方法。
- 为了最大程度地减少从实体到 ViewModel 的乏味,您可以使用AutoMapper之类的工具在具有相同名称的属性之间自动映射(并为剩余的映射设置规则)。
- 从 EditModel 回到实体可能需要一些手动工作。AutoMapper 可以处理一些场景,但它可能不是该类型映射的理想工具(它更适合从实体到 ViewModel)。我听说有人使用命令模式和规则引擎来执行映射回实体,但到目前为止,这些技术的真正详细的解释或教程让我回避了。
ViewModel 示例(来自 NerdDinner 教程)
public class DinnerFormViewModel {
// Properties
public Dinner Dinner { get; private set; }
public SelectList Countries { get; private set; }
// Constructor
public DinnerFormViewModel(Dinner dinner) {
Dinner = dinner;
Countries = new SelectList(PhoneValidator.AllCountries, dinner.Country);
}
}
// controller actions
[Authorize]
public ActionResult Edit(int id) {
Dinner dinner = dinnerRepository.GetDinner(id);
return View(new DinnerFormViewModel(dinner));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection) {
Dinner dinner = dinnerRepository.GetDinner(id);
try {
UpdateModel(dinner);
dinnerRepository.Save();
return RedirectToAction("Details", new { id=dinner.DinnerID });
}
catch {
ModelState.AddModelErrors(dinner.GetRuleViolations());
return View(new DinnerFormViewModel(dinner));
}
}
资料来源: http: //nerddinnerbook.s3.amazonaws.com/Part6.htm