In this chapter, you will learn more about different types of model classes in the MVC framework and how to use them.
Up until now, you have used the Video class as a model for the Index view. In simple solutions that might be fine, but in more complex solutions, you need to use entity models and view models. Sometimes you even make a more granular distinction between the models, using Data Transfer Objects (DTOs) with the view models.
An entity model is typically used to define a table in a database. A view model is used to transport data from the controller to the view, but sometimes the view model needs to contain objects, and that’s where the DTOs come into play. Some might argue that DTOs are view models, and in some scenarios they are.
You will create a new folder called Entities and move the Video class to that folder. The reason for moving the file is that the Video class later will be used to define a table in a SQL Server database. A class used to define a database table is referred to as an entity. You will also add a new folder named ViewModels, which will hold the view models created throughout the first part of the book.
Important to note is that the view model typically contains other data than the entity model, although some properties are the same. One example is when a video is being added in a Create view. The view model needs some properties from the entity model, but could also need other information that is not stored in the Video entity and must be fetched from another database table, or an enum.
A view model is never used to directly update the database. To update the database the data from the view model is added to an entity model, which then in turn updates the database table.
Let’s look at an example where an enum is used to display the genre a video belongs to. For simplicity, a video can only belong to one genre.
JQuery: You will use JQuery and JQuery Validation to perform client-side validation. This will make sure that the user input is conforming to the validation rules before the data is sent to the server action. Some validation rules are added by the framework; others you have added yourself to the entity and view model classes as attributes. Examples of validation rules are: password restrictions set by the framework (can be changed), and the Required, MaxLength, and DataType attributes.
First you need to add an Entities folder and a ViewModels folder to the folder structure.
namespace AspNetCore22Intro.Entities
public enum Genres
{
None,
Horror,
Animated,
Comedy,
Romance,
Action
}
public class Video
{
public int Id { get; set; }
public string Title { get; set; }
public int GenreId { get; set; }
}
new Video { Id = 3, GenreId = 2, Title = "Megamind" }
public class VideoViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Genre { get; set; }
}
Now that the view model has been created, you need to send it to the view as its model. This requires some changes to the HomeController class and the Index view. You need to fetch the video from the _videos collection using its id, and then convert the genre id to the name for the corresponding value in the Genres enum.
When the view model has been assigned values from the entity object and the enum name, it is sent to the view with the View method.
using AspNetCore22Intro.Models;
using AspNetCore22Intro.ViewModels;
using System;
using System
.Linq;
public ViewResult Index()
{
var model = _videos.GetAll().Select(video =>
new VideoViewModel
{
Id = video.Id,
Title = video.Title,
Genre = Enum.GetName(typeof(Genres), video.GenreId)
});
return View(model);
}
@model IEnumerable<AspNetCore22Intro.ViewModels.VideoViewModel>
<td>@video.Genre</td>
Now that you know how to use the VideoViewModel to send data to the Index view, it is time to add a new view to the Views folder.
The Details view will display a single video in the browser, based on the id sent to the Details action you will add next.
public IActionResult Details(int id)
{
}
Video Get(int id);
public Video Get(int id)
{
return _videos.FirstOrDefault(v => v.Id.Equals(id));
}
using System
.Linq;
var model = _videos.Get(id);
return new ObjectResult(model);
return View(
new VideoViewModel
{
Id = model.Id,
Title = model.Title,
Genre = Enum.GetName(typeof(Genres), model.GenreId)
}
);
@model AspNetCore22Intro.ViewModels.VideoViewModel
<div>Id: @Model.Id</div>
<div>Title: @Model.Title</div>
<div>Genre: @Model.Genre</div>
if (model == null)
return RedirectToAction("Index");
@Html.ActionLink("Home", "Index")
<td>@Html.ActionLink(video.Id.ToString(), "Details", new { id = video.Id })</td>
The complete markup for the Index view:
@model IEnumerable<AspNetCore22Intro.ViewModels.VideoViewModel>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Video</title>
</head>
<body>
<table>
@foreach (var video in Model)
{
<tr>
<td>@Html.ActionLink(video.Id.ToString(), "Details",
new { id = video.Id })</td>
<td>@video.Title</td>
<td>@video.Genre</td>
</tr>
}
</table>
</body>
</html>
The complete markup for the Details view:
@model AspNetCore22Intro.ViewModels.VideoViewModel
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Video</title>
</head>
<body>
<div>Id: @Model.Id</div>
<div>Title: @Model.Title</div>
<div>Genre: @Model.Genre</div>
@Html.ActionLink("Home", "Index")
</body>
</html>
The complete markup for the Details action:
public IActionResult Details(int id)
{
var model = _videos.Get(id);
if (model == null) return RedirectToAction("Index");
return View(new VideoViewModel
{
Id = model.Id,
Title = model.Title,
Genre = Enum.GetName(typeof(Genres), model.GenreId)
});
}
Join our mailing list to receive the latest news and updates from our team.
Don't worry, your information will not be shared.
50% Complete
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.