asp.net-mvc – 遵循视图模型模式的最佳实践
我现在有几次学习ASP.NET MVC了.我遵循在互联网或书籍中找到的一些指导原则,我希望确保我遵循关于视图模型模式的开发中的良好实践.以下是博客实施的简单示例.能否请你确认我是在正确的方式.假设我想在视图上显示帖子标题描述,并在此帖子上显示评论.所以我有一个视图有2个部分视图.
在我的控制器中: public ActionResult DetailPost(int postID) { // retrieve infos Post postModel = repository.Posts.FirstOrDefault(p => p.PostID == postID); IEnumerable<Comments> commentsModel = postModel.Comments; // prepare view model DetailPostViewModel detailPostViewModel = new DetailPostViewModel { Post = postModel,Comments = commentsModel,}; return View(detailPostViewModel); } 所以在这里,我将看到一个由两件事组成的视图模型: >帖子信息 视图模型将传递给视图以跟随视图模型模式. 在我的详细视图中: @model WebUI.ViewModels.DetailPostViewModel @{ ViewBag.Title = "Detail"; } <h2>Detail</h2> @Html.Partial("_DetailPost",Model.Post) @Html.Partial("_Comments",Model.Comments) 所以在这里,我使用了我的DetailPostViewModel.对于我的部分观点,我传递了必要的信息,即实体!?我不知道这是正确的方式,还是我必须在这里通过视图模型呢? 在我的_DetailPost视图中: @model Domain.Entities.Post @Html.DisplayForModel() ... 所以在我的部分视图中,我使用en实体作为模型.是好还是坏? 在我的_Comments视图中: @model IEnumerable<Domain.Entities.Comment> @foreach (var item in Model) { @Html.DisplayFor(Model => item.Title) @Html.DisplayFor(Model => item.Username) } 所以在我的部分视图中,我使用en实体作为模型.是好还是坏? 感谢您的建议/意见. 编辑 我尝试在Automapper的帮助下实现我的视图模型模式,但是我遇到了一些问题,如下所述.我理解将一个对象映射到另一个对象的原理.在基本情况下,它运作良好.现在,让我们看一个更复杂的情况:我有一个由一些属性(id,title,…)组成的帖子,每个帖子可以附加一些注释(对象),每个注释只能附加一个用户(对象) .我希望得到一个包含我所有帖子的视图模型,并获取所有评论,并为每个评论获得用户附加. 以下是域实体: public class Post { public int PostID { get; set; } public string Title { get; set; } ... public virtual ICollection<Comment> Comments { get; set; } } public class Comment { public int CommentID { get; set; } public string CommentText { get; set; } ... public virtual <User> User { get; set; } } public class User { public int UserID { get; set; } public string Username { get; set; } ... } 以下是视图模型: public class PostVM { public int PostID { get; set; } public string Title { get; set; } ... public virtual ICollection<CommentVM> CommentsVM { get; set; } } public class CommentVM { public int CommentID { get; set; } public string CommentText { get; set; } ... public virtual <UserVM> UserVM { get; set; } } public class UserVM { public int UserID { get; set; } public string Username { get; set; } ... } 这是我的控制器: // I would like to list all posts in the DB. public ViewResult Index() { PostVM viewModel = new PostVM { ... } return View(viewModel); } 如何将我的(实体)帖子对象列表映射到我的视图模型对象和所有子对象(注释,用户)? 谢谢! 解决方法
你很接近,但对我来说这不是视图模型的正确用法.你有以下几点:
public class DetailPostViewModel { public Post Post { get; set; } public IEnumerable<Comment> Comments { get; set; } } 这是某种混合伪视图模型.真实视图模型不应该引用任何域模型. 一个更正确的例子如下: public class DetailPostViewModel { public PostViewModel Post { get; set; } public IEnumerable<CommentViewModel> Comments { get; set; } } 其中PostViewModel和CommentViewModel当然是其各自域实体的相应视图模型. 而不是部分我会使用显示模板: @model WebUI.ViewModels.DetailPostViewModel @{ ViewBag.Title = "Detail"; } <h2>Detail</h2> @Html.DisplayFor(x => x.Post) @Html.DisplayFor(x => x.Comments) 然后你将拥有相应的显示模板(?/ Views / Shared / DisplayTemplates / PostViewModel.cshtml): @model WebUI.ViewModels.PostViewModel ... some properties of a post 和(?/ Views / Shared / DisplayTemplates / CommentViewModel.cshtml): @model WebUI.ViewModels.CommentViewModel @Html.DisplayFor(x => x.Title) @Html.DisplayFor(x => x.Username) 显然,由于Comments是枚举,因此将自动为集合的每个元素呈现显示模板.这样您就不需要在视图中编写任何循环. 就控制器逻辑而言,我个人喜欢使用AutoMapper来映射域实体和视图模型. 所以它可能看起来像这样: public ActionResult DetailPost(int postID) { // retrieve infos var postModel = repository.Posts.FirstOrDefault(p => p.PostID == postID); var viewModel = new DetailPostViewModel { Post = Mapper.Map<Post,PostViewModel>(postModel),Comments = Mapper.Map<IEnumerable<Comment>,IEnumerable<CommentViewModel>>(postModel.Comments) }; return View(viewModel); } 甚至更好: public class PostViewModel { ... some properties of a Post public IEnumerable<CommentViewModel> Comments { get; set; } } 然后: public ActionResult DetailPost(int postID) { // retrieve infos var postModel = repository.Posts.FirstOrDefault(p => p.PostID == postID); var viewModel = Mapper.Map<Post,PostViewModel>(postModel); return View(viewModel); } 然后你的视图将强烈输入PostViewModel: @model WebUI.ViewModels.PostViewModel @{ ViewBag.Title = "Detail"; } <h2>Detail</h2> ... some properties of a post @Html.DisplayFor(x => x.Comments) 根据评论部分的要求,域模型和视图模型之间的映射如下所示: Mapper.CreateMap<User,UserVM>(); Mapper .CreateMap<Comment,CommentVM>() .ForMember( dest => dest.UserVM,opt => opt.MapFrom(src => src.User) ); Mapper .CreateMap<Post,PostVM>() .ForMember( dest => dest.CommentsVM,opt => opt.MapFrom(src => src.Comments) ); 备注:如果在视图模型中以相同的方式命名属性,则不需要两个ForMemeber调用:User和Comments. AutoMapper依赖于标准命名约定,您也可以编写自己的自定义约定策略,以避免单独映射每个成员.然后,您需要的是在定义视图模型时保持一致并遵循惯例. 然后在控制器中: IEnumerable<Post> posts = ... IEnumerable<PostVm> postVms = Mapper.Map<IEnumerable<Post>,IEnumerable<PostVM>>(posts); return View(postVms); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 多个客户端应该有一个项目副本,还是每个客户端都
- .net – Cache.Add绝对到期 – 是否基于UTC?
- asp.net-mvc-4 – MVC4:什么实体代表表webpages_Membershi
- 如何使用ASP.NET在纯HTML页面上执行表单验证?
- asp.net – Transfer-Encoding:Chunked cause 404系统找不
- asp.net – 性能监视器显示活动的4294967293个会话
- asp.net-mvc – 我真的需要一个ORM吗?
- asp.net – 在什么情况下HttpContext.Current.Session可以为
- asp.net-mvc – 在Webgrid中将布尔值显示为复选框
- 在asp.net MVC中创建面包屑路径
- asp.net – 是否有任何使用自动生成的视觉工作室
- asp.net – 如何在WebForms中的form.onSubmit期间
- asp.net – 如果禁用ViewState会发生什么
- asp.net-mvc – MVC中的错误处理
- asp.net – SESSION VARIABLES的替代品是什么?
- asp.net-mvc – 用于表行的Asp.Net MVC WebGrid帮
- ASP.NET拒绝访问该路径
- ASP.NET Verses Winforms
- asp.net-mvc-3 – 同一页面中的两个ValidationSu
- 一个支持 CodeFirst/DbFirst/ModelFirst 的数据库