What is a ViewModel in ASP.NET MVC?

13

I'm used to the MVC approach to frameworks like CakePHP and Laravel. Now that I'm delving into ASP.NET MVC, I'd like to understand what this ViewModel is for.

What is the purpose of ViewModels?

    
asked by anonymous 07.06.2018 / 18:31

2 answers

10

I'll make an analogy that I find it very easy to understand what a viewmodel is.

Think of a database, but only as a metaphorical relationship, not having to have a relationship between them. The model of your MVC application is the database table. viewmodel is the equivalent of what we know about view in the database . Simple, right?

In CakePHP and Laravel's concept is this? If it is, in ASP.NET MVC or Core (which I advise most) is the same thing.

Including AP already had a preview of using SQL views in MVC where the approach was a bit different.

Of course, there are concrete differences between concepts, but that's basically it.

As the name says, modelview is a template for the view.

What is the normal MVC M model?

It determines what data will be available to you in the database you are working on. Note that I did not speak of database, base can be any way.

The model can be used directly in view without any problem.

I imagine you understand well that view is where you have the actual presentation of the data.

But in anything that comes out of CRUD very simple, and even in some cases like this, the model can not be used directly in a simple way. He would have to juggle to work. In some cases it could not even work.

The solution is to create an "alternate" template that will be used in the view. In other words, viewmodel is a model that only meets the specific need of one or more views. We can say that it is equal to pure model , but it does not bind directly to the database.

In the viewmodel you create a structure with the data you will use in view , which can be just the subset of fields in the model, you can have fields created on demand that will be easily used in view (remembering that views should have no processing other than to control its own construction). But it can also make data available from other adopted model objects. Generally, MVC does not have mechanism to pass different objects to view directly, you need to create a new template with what you need.

Remembering viewmodels are usually created in the controller, even indirectly.

It's almost duplicate of View Model should have related classes .

More information about MVVM where its use has been inspected, but there more fully.

You have a legal example on answer in the SO . A viewmodel :

public class CountyViewModel {
    [HiddenInput]
    public int? CountyId { get; set; }

    [DisplayName("County Name")] [StringLength(25)]
    public string CountyName { get; set; }

    [DisplayName("County URL")] [StringLength(255)]
    public string URL { get; set; }
}

public class ListAllCountiesViewModel {
    public string CountyName { get; set; }
    public IEnumerable<County> ListAllCounty { get; set; }
}

public class PropertyViewModel {
    public ListAllCountiesViewModel _listAllCountyViewModel { get; set; }
    public CountyViewModel _countyViewModel { get; set; }
}
    
07.06.2018 / 18:57
10

In C # everything needs a type. Well, even today it is possible to work more dynamically, but it is not the point. Types are defined by classes.

In ASP.NET MVC it is customary to type views as well. That is, you define that a view will receive an object and that this object must be of a certain type that, as already said, is defined by a class.

Starting from this point, I'll try to explain using an example, to make it easier to visualize.

Imagine that you have a template (a type, a class) that represents a database table named person.

public class Pessoa { }

Now imagine that this person can have a name and one or more cars, so the class Pessoa will have two properties

public class Pessoa 
{
    public string Nome { get; set; }
    public List<Carro> Carros { get; set; }
}

And the car class is defined as follows

public class Carro
{
    public string Modelo { get; set; }
}

Well, now imagine that you have the following task: create a view that shows the name of all the people registered and the model of all your cars separated by commas.

You can simply create a view using the type Pessoa and treat the car models in Razor itself.

@model List<Pessoa>

@foreach(var pessoa in Model)
{
    <p>@(pessoa.Nome) - @(string.Join(", ", pessoa.Carros.Select(c => c.Modelo)))</p>
}

Great, it's done, but it would be a little smarter of you if you just sent view a type that contains two strings . Then go into that view model .

public class PessoaCarrosViewModel
{
    public string NomePessoa { get; set; }
    public string ModelosCarros { get; set; }
}

Following this idea, the view code would be

@model List<PessoaCarrosViewModel>

@foreach(var pv in Model)
{
    <p>@(pv.NomePessoa) - @(pv.ModelosCarros)</p>
}

Obviously somewhere in the code there's going to have to be a way to map a set of data (for example, models) to a view model .

Of course, my example is extraordinarily simple, and it probably would not even really be necessary to use a view model , but its idea is this, you have a type that contains merged information other types to display in view .

    
07.06.2018 / 18:49