ViewModel is used to encapsulate the multiple entities into single entity. It is basically a combination of data models into single object and rendering by the view.
Sometimes it is required to show the multiple entities data on view which is coming from different data model classes. So, it includes all the data into single one and makes it flexible to show on View in ASP.NET. So, basically it is separation of concerns, it means you include different entities for particular purpose and make main focus on the code.
There are many reasons to use ViewModel:
- We can create master detail records for the view.
- Create real data with paging information in same group.
- Dashboards which includes different source of data.
- Aggregate the data for reporting.
- Optimized for rendering on the view.
When to use ViewModel
As per requirement, you need to pass more than one entity to strongly typed view which is best practice then you need to use ViewModel. It is a separate class as an entity. It makes formation and interaction between model and view more easy and simple.
So, if you already have created model entity and want to add some additional information to show on view then it is best practice to use ViewModel.
Domain Models
Post.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
-
- namespace DotnetTutorial.Data.Entities
- {
- public class Post
- {
- [Key]
- public int PostId { get; set; }
-
- [MaxLength(500)]
- [Column(TypeName = "varchar")]
- public string PostTitle { get; set; }
-
- [MaxLength(1000)]
- [Column(TypeName = "text")]
- public string ShortPostContent { get; set; }
-
- [Column(TypeName="text")]
- public string FullPostContent { get; set; }
-
- [MaxLength(255)]
- public string MetaKeywords { get; set; }
-
- [MaxLength(500)]
- public string MetaDescription { get; set; }
- public DateTime PostAddedDate { get; set; }
- public DateTime PostUpdatedDate { get; set; }
- public bool IsCommented { get; set; }
- public bool IsShared { get; set; }
- public bool IsPrivate { get; set; }
- public int NumberOfViews { get; set; }
- public int EntityType { get; set; }
-
-
- public virtual int CategoryId { get; set; }
-
- [ForeignKey("CategoryId")]
- public virtual Category Categories { get; set; }
-
- public int NumberOfLikes { get; set; }
-
- public int NumberOfComments { get; set; }
- }
- }
Category.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
-
- namespace DotnetTutorial.Data.Entities
- {
- public class Category
- {
- [Key]
- [Required(ErrorMessage="Category is required")]
- public int CategoryId { get; set; }
-
- [MaxLength(25)]
- public string CategoryName { get; set; }
-
- [MaxLength(25)]
- public string CategorySlug { get; set; }
-
- [MaxLength(1000)]
- public string CategoryImage { get; set; }
-
- public List<Post> Posts { get; set; }
- }
- }
Now I am going to create a ViewModel which will contain the list of properties which will show on View.
PostViewModel.cs ArticleController.cs See the following code where we are using ViewModel to show the data on View.
- public ActionResult Index(int? page)
- {
- AddNewVisitorEntry("Home");
- var pgNumber = page ?? 1;
- var pageSize = _settingRepository.PostPerPages;
- var allPostList = _postRepository.GetPostForHomePage(pgNumber, pageSize);
- var totalPage = PostExtensions.GetPageCount(_postRepository.GetPostCount(), pageSize);
- IEnumerable<PostViewModel> model = null;
- var postEntities = allPostList.Select(x => new PostViewModel()
- {
- PostId = x.PostId,
- PostTitle = x.PostTitle,
- ShortPostContent = x.ShortPostContent,
- FullPostContent = x.FullPostContent,
- MetaKeywords = x.MetaKeywords,
- MetaDescription = x.MetaDescription,
- PostAddedDate = x.PostAddedDate,
- PostUpdatedDate = x.PostUpdatedDate,
- TimeAgo = x.PostAddedDate.TimeAgo().ToString(),
- IsCommented = x.IsCommented,
- IsShared = x.IsShared,
- IsPrivate = x.IsPrivate,
- NumberOfViews = x.NumberOfViews,
- EntityType = x.EntityType,
- PostUrl = x.PostUrl,
- ThumbImagePath = x.ThumbImagePath,
- ImagePath = x.ImagePath,
- CategoryId = x.CategoryId,
- postCategory = x.Categories,
- PostTags = _tagRepository.GetTagListByPostId(x.PostId),
- userDetails = _userRepository.GetUserDetailsByUserId(x.UserId),
- NumberOfLikes = x.NumberOfLikes,
- NumberOfComments = x.NumberOfComments
- });
- model = postEntities;
- ViewBag.TotalPages = Convert.ToInt32(totalPage);
- ViewBag.CurrentPage = pgNumber;
- ViewBag.PageSize = pageSize;
- return View("Index",model);
- }
View - @model DotnetTutorial.Data.ViewModel.PostViewModel
- @{
- var userId = 0;
- if (LoggedUserDetails != null)
- {
- userId = LoggedUserDetails.UserId;
- }
- var url = Url.RouteUrl("IndividualArticlesPost", new { categoryslug = Model.postCategory.CategorySlug, url = Model.PostUrl });
- var shareUrl = "http://www.dotnet-tutorial.com" + url;
- var uniquid = "post123" + Model.PostId;
- var showReadMore = string.Empty;
- var content = string.Empty;
- if (Model.postPageStatus > 0)
- {
- content = Model.ShortPostContent;
- showReadMore = "Yes";
- }
- else
- {
- content = Model.FullPostContent;
- }
- var firstName = Model.userDetails.FirstName;
- var lastName = Model.userDetails.LastName;
- var fullName = firstName + " " + lastName;
- }
- <style>
- #mypost {
- border: 1px solid #d5d3d3;
- padding:0 6px 10px 6px;
- }
- </style>
- <div id="mypost">
- <div>
- <h3>
- <span itemprop="name"> @Html.RouteLink(Model.PostTitle, "IndividualArticlesPost", new { categoryslug = Model.postCategory.CategorySlug, url = Model.PostUrl }, new { @class = "title", @style = "color:#069; font-weight:bold;" })</span>
- </h3>
- <div>
- <b>By : </b> <a class="PostAuthor" href="http://dotnet-tutorial.com/mukeshkumar" itemprop="url">
- <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">@fullName</span></span>
- </a>
- <b> Posted On </b><time itemprop="datePublished">@Model.TimeAgo</time>
- </div>
-
- <input type="hidden" id="hdnPostId" value="@Model.PostId" />
- </div>
- <span itemprop="articleBody">
- <div>
- @Html.Raw(content)
- </div>
- </span>
- <div>
- @if (showReadMore == "Yes")
- {
- var postUrl = "http://www.dotnet-tutorial.com" + url;
- var posttitle = Model.PostTitle;
- <div class="pull-right">
- <a href="@url" class="btn btn-primary" type="button" style="float:right">Read more</a>
- </div>
- <br />
- }
- </div>
- <br />
- </div>
Hope this article will help you to understand the use of ViewModel using above example and how to implement it with ASP.NET MVC project. Thanks for reading this article, hope you enjoyed it.