我也有同样的不适。我唯一的解决方法是执行以下操作:
- 创建一个绑定器来绑定和验证视图模型
- 创建一个活页夹以从数据库中获取实体(或仅在控制器中执行此操作)
- 在超类中调用继承的 Save 方法。此方法采用视图模型和将要更新的实体,并执行您在步骤中列出的所有工作。
动作方法如下所示:
public ActionResult Whatever(TViewModel viewModel, TEntity entity)
{
return Save(viewModel, entity);
}
基本控制器具有通用定义,如下所示:
public abstract BaseController<TEntity, TViewModel>
where TEntity : Entity
where TViewModel : ViewModel
构造函数有两个依赖项,一个用于实体存储库,另一个用于模型映射器,如下所示:
protected BaseController(IRepository<TEntity> repository, IMapper<TEntity, TViewModel> mapper)
有了这个,您就可以编写一个受保护的 Save 方法,该方法可以从子类中的控制器操作中调用,如下所示:
protected ActionResult Save(TViewModel viewModel, TEntity entity)
{
if (!ModelState.IsValid)
return View(viewModel);
_mapper.Map(viewModel, entity);
if (!entity.IsValid)
{
// add errors to model state
return View(viewModel);
}
try
{
_repository.Save(entity);
// either redirect with static url or add virtual method for defining redirect in subclass.
}
catch (Exception)
{
// do something here with the exception
return View(viewModel);
}
}
就可测试性而言,您可以测试传入有效/无效视图模型和实体的保存方法。您可以分别测试模型映射器的实现、视图模型的有效状态和实体的有效状态。
通过使基本控制器通用,您可以为域中的每个实体/视图模型组合重复此模式,如果您要创建许多控制器来做同样的事情。
我很想听听其他人对此的看法。好问题。