c# – 在视图模型中使用存储库可以吗?
假设我有复杂的视图模型,有很多数据,如国家/地区,产品,类别等的列表,我每次创建ViewModel时都需要从数据库中获取数据.
我想要解决的主要问题是,当我处理POST操作时,一些TestModel发布的值不正确,导致ModelState.IsValid为false,那么我必须返回与当前发布的模型相同的视图.这迫使我再次获得我的类别列表,因为我在GET操作中这样做.这在控制器中增加了很多重复的代码,我想删除它.目前我正在做以下事情: 我的模型和视图模型: 模型,实体存储在数据库中: public class Category { public int Id { get; set; } public string Name { get; set; } public IEnumerable<Category> SubCategories { get; set; } } 查看型号: public class CategoryModel { public int Id { get; set; } public string Name { get; set; } } public class TestModel { [Required] [MaxLength(5)] public string Text { get; set; } public int SelectedCategory { get; set; } public IEnumerable<CategoryModel> Categories { get; set; } public SelectList CategoriesList { get { var items = Categories == null || !Categories.Any() ? Enumerable.Empty<SelectListItem>() : Categories.Select(c => new SelectListItem { Value = c.Id.ToString(),Text = c.Name }); return new SelectList(items,"Value","Text"); } } } 我的控制器: public class HomeController : Controller { private readonly Repository _repository = ObjectFactory.GetRepositoryInstance(); public ActionResult Index() { var model = new TestModel { Categories = _repository.Categories.Select(c => new CategoryModel { Id = c.Id,Name = c.Name }) }; return View(model); } [HttpPost] public ActionResult Index(TestModel model) { if (ModelState.IsValid) { return RedirectToAction("Succes"); } model.Categories = _repository.Categories.Select(c => new CategoryModel { Id = c.Id,Name = c.Name }); return View(model); } public ActionResult Succes() { return View(); } } 我想删除重复的类别抓取和映射,基本上这个代码: .Categories = _repository.Categories.Select(c => new CategoryModel { Id = c.Id,Name = c.Name }) 来自控制器.另外我想删除ModelState的有效性检查,只有当ModelState.IsValid保持控制器代码AS CLEAN AS POSSIBLE时,我想执行该操作.到目前为止,我有以下解决方案来删除ModelState有效性检查: 创建自定义ValidateModelAttribute public class ValidateModelAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var viewData = filterContext.Controller.ViewData; if(viewData.ModelState.IsValid) return; viewData.Model = filterContext.ActionParameters["model"]; filterContext.Result = new ViewResult { ViewData = viewData,}; } } 现在模型在动作执行之前被验证.在验证错误的情况下,我们使用与最近发布的相同模型相同的视图.因此,控制器POST操作如下所示: [HttpPost] [ValidateModelAttribute] public ActionResult Index(TestModel model) { // Do some important stuff with posted data return RedirectToAction("Success"); } 这是很好的,但现在我的TestModel的Categories属性是空的,因为我必须从数据库中获取类别,并相应地映射它们.那么可以修改我的视图模型看起来像这样: public class TestModel { private readonly Repository _repository = ObjectFactory.GetRepositoryInstance(); ... public int SelectedCategory { get; set; } public IEnumerable<CategoryModel> Categories { get { return _repository.Categories.Select(c => new CategoryModel { Id = c.Id,Name = c.Name }); } } ... } 这将使我们拥有非常干净的控制器,但不会导致某种性能或架构问题?观看模式不会违背单一责任原则吗? ViewModels应该负责获取所需的数据吗? 解决方法
没关系视图模型应主要由服务/查询甚至控制器填充的DTO.以前的版本没有问题,你的控制器只是几行代码.
但是您的存储库并不是一个存储库,它是一个ORM.一个适当的存储库(这里只是一些查询对象)将直接返回视图模型的类别列表. 关于你的自动验证属性,不要重新发明轮子,别人(在这种情况下我)做了before. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |