The community is working on translating this tutorial into Persian, but it seems that no one has started the translation process for this article yet. If you can help us, then please click "More info".
ViewModels
We have already worked with Models multiple times in this tutorial, but if you look around in other material about ASP.NET MVC or just the MVC pattern in general, you may notice that something called a "View-Model" is often mentioned. But what's the difference between a Model and a ViewModel? Actually, whenever you pass a Model to a View, it's considered a ViewModel because it's used by the View. In other words, there doesn't have to be a difference - you can use your Models as ViewModels interchangeably.
There are, however, a lot of situations where you may want to create a specific ViewModel for a specific View. This can be to extend or simplify an existing Model, or because you want to represent something in a View that's not already covered by one of your models.
ViewModels are often placed in their own directory in your project, called "ViewModels". Again, this is just a convention and since ViewModels are just regular .NET classes, you are free to place them where ever you want to, but it often makes sense to follow these conventions. Some people also prefer to postfix the name of the class with the word ViewModel, e.g. "AddressViewModel" or "EditUserViewModel".
When to use a ViewModel?
Here are a couple of situations where you could benefit from a ViewModel:
To represent something in a View that's not already contained by an existing Model: When you pass a Model to a View, you are free to pass e.g. a String or another simple type, but if you want to pass multiple values, it might make more sense to create a simple ViewModel to hold the data, like this one:
public class AddressViewModel
{
public string StreetName { get; set; }
public string ZipCode { get; set; }
}
To access the data of multiple Models from the same View: This is relevant in a lot of situations, e.g. when you want to create a FORM where you can edit the data of multiple Models at the same time. You could then create a ViewModel like this:
public class EditItemsViewModel
{
public Model1Type Model1 { get; set; }
public Model2Type Model2 { get; set; }
}
To simplify an existing Model: Imagine that you have a huge class with information about a user. Perhaps even sensitive information like passwords. When you want to expose this information to a View, it can be beneficiary to only expose the parts of it you actually need. For instance, you may have a small widget showing that the user is logged in, which username they have and for how long they have been logged in. So instead of passing your entire User Model, you can pass in a much leaner ViewModel, designed specifically for this purpose:
public class SimpleUserInfoViewModel
{
public string Username { get; set; }
public TimeSpan LoginDuration { get; set; }
}
To extend an existing Model with data only relevant to the View: On the other hand, sometimes your Model contains less information than what you need in your View. An example of this could be that you want some convenience properties or methods which are only relevant to the View and not your Model in general, like in this example where we extend a user Model (called WebUser) with a LoginDuration property, calculated from the LastLogin DateTime property already found on the WebUser class:
public class WebUser
{
public DateTime LastLogin { get; set; }
}
From there on there are two ways of doing things: You can either extend this class (inherit from it) or add a property for the WebUser instance on the ViewModel. Like this:
public class UserInfoViewModel
{
public WebUser User { get; set; }
public TimeSpan LoginDuration
{
get
{
return DateTime.Now - this.User.LastLogin;
}
}
}
Or like this:
public class ExtendedUserInfoViewModel : WebUser
{
public TimeSpan LoginDuration
{
get
{
return DateTime.Now - this.LastLogin;
}
}
}
Summary
A ViewModel is basically just a Model passed to a View, but as outlined in this article, there are many ways of doing this - you can either use an existing Model, as it is, or create a new one, specific to the View in question.