When using model binding in an ASP.NET MVC application we make sure that our user interface elements matches with the domain object. But sometimes this is not possible as user interface contains elements which does not make any sense on the domain objects. In this article we will demonstrate how to implement ViewModels which closely reflects the elements on the interface.
The scenario for this article is very simple. We will implement a user registration screen which involves the username, password and confirm password fields.
When Not Using ViewModel?
Let's see how we can accomplish this task without using ViewModel approach. Our view is implemented below as shown:
Nothing complicated right! Now, instead of passing individual parameters to the controller action we can leverage the power of model binders to populate our domain object. If you are not familiar with model binders then check out this article. The implementation of the controller "Register" action is shown below:
The "Home.Index" evaluates to "Index". This is generated by using T4 templates and has been covered in the following article.
Using T4 Template to Generate Strongly Typed View Names
Inside the controller's action you will need to validate that if the ReEnterPassword is same as Password field. Unfortunately, there is no way to access the ReEnterPassword field since the User object does not have that field. One way to solve this problem is to add a new field called "ReEnterPassword" to the User object. But this will not makes any sense on the domain side of the application. The User object does not care about the ReEnterPassword field and by doing so we are making things complicated.
A better way to solve this problem is to introduce a UserViewModel which reflects the fields on the user interface. In the next section we are going to tackle the same scenario using ViewModel approach.
The UserViewModel will reflect the activities that will happen on the view. I think a better name would have been RegistrationViewModel but let's stick with UserViewModel for this article. Here is the implementation of the UserViewModel:
As, you can see in the above code the UserViewModel reflects the user interface. Each element that will be passed from the user interface is mapped in the ViewModel. Now, we can update the Register action to see the changes.
The ValidateSignUp method is responsible for making sure that the ReEnterPassword and the Password fields are same.
What About Mapping ViewModel to the Domain Objects?
Eventually, you will need to map the ViewModel to the actual domain objects. You can perform this manually for small ViewModels or you can use AutoMapper to perform complicated mapping.
In this article we learned how we can use ViewModel to reflect the interaction on the user interface instead of complicating our domain objects. The next article will discuss how to use AutoMapper to map between the ViewModel and the domain objects.