Thursday, February 12, 2015

Model and View model in MVC 5

Model

Model usually represent the business domain entities. These entities are used to interact with the database and in a simple system, they usually have one to one relationship with database tables.

Battle of Business Logic

This is something that I see most people get wrong in their interviews. When I ask them where to put the business logic, I usually get the answer as Controller. The best practices say that all business logic should be in Model. However, I will not lie, I do some times put business logic in controller itself if it is something small. I don't want to do it the hard way for smaller code, especially if I know that this won't be needed again or if its a test project. However, if its a substantial code I would recommend putting it in Model only.
The major advantage of keeping the business logic in Model is less duplicated code. I won't be writing the same thing again and again in Views or Controller. Secondly, it helps us in isolating the code for testing. Finally, it also helps in making the view and controller easier to read and understand.

ViewModel

ViewModels are classes that are used for interaction with Views. Views which use such viewModels are called strongly typed views. Let's take an example of Student class.

Suppose the Model looks like:
public class Student
{

      int Student Id { get; set; }
      string FirstName { get; set; }
      string LastName { get; set; }

}


In Add.cshtml we can use this
public class StudentViewModel
{

     [Required] 
     string FirstName;

     [Required] 
     string LastName; 

}


Ideally, ViewModel should only have the fields that are required by the specific View. This not only helps to keep the code clean and easy to understand but also prevents attacks like OverPosting which I will explain in a later post.

ViewModels are also useful in the scenario where a single view needs to show data from multiple models. For example, Student Details page might have Student detail as well as Department Detail.
public class StudentDetailViewModel
{
     [Required] 
     string FirstName;

     [Required] 
     string LastName;

     [Required] 
     string DepartmentName; 
}

So when we are filling the ViewModel, we can map the properties which we need to read explicitly from Student and Department model and have complete control on the system. The fields which are supposed to be hidden should be excluded (or encrypted atleast) from the viewModel so that user cannot get access to them by any chance.

Conclusion

Understanding Model and ViewModel is crucial to have a clean code base esp in an MVC application. Separating them not only helps us to make our code easy to understand but also makes it less prone to bugs.

2 comments:

  1. Good post describing the difference between Model and ViewModel.

    But, who nowadays has business logic in Model classes? Business logic normally goes in the business logic layer commonly know as the Manager classes, which in turn uses the data access layer.

    Can you give an example of the kind of business logic you would have in a Model?

    ReplyDelete
  2. Hi Chaitanya,
    Thanks for the appreciation.
    For the example that you have asked for, let me give you a quick example:
    Suppose, you have a special Student who is Admin and whose Email should not be allowed to edit. You don't want to keep that information in your View or Controller. You will perhaps have an IsEmailEditable property in your Model which can control the Edit button on Email property in the View.

    Regarding the business logic layer and Manager classes that you have mentioned, you are perfectly right that you can have a separate layer for that. However, that is going to be used for larger enterprise level applications. You are separating out that layer which makes sense if you have tons of complex business logic. Such a layer would fill in the data according to the business rules in the Model.
    I will be talking more about enterprise level architecture in future posts. This article is rather for beginner level, not advanced level :)

    ReplyDelete