I'm starting to develop a Blazor Server Side application and my idea is to use :
My folders structure will look like this :
Features
Feature 1
XXXView.razor : the view
XXXView.razor.cs : the partial class
XXXView.razor.queries.cs : contains the queries (ex : GetCustomer) used by the view
XXXView.razor.commands.cs : contains the commands (ex : SaveCustomer) used by the view
Feature 2
My question is the following : in this kind of architecture, is there a good reason to use a ViewModel (as in asp .net MVC projects) instead of using the entity directly in the view ?
The code below is an example of what I would do without using ViewModel.
public partial class UserEditView : EditableComponentBase
{
[Parameter]
public long? Id { get; set; }
[Required]
public string Name { get; set; }
protected override async Task OnInitializedAsync()
{
if (this.Id.HasValue)
{
UserEntity user = await Mediator.Send(new GetUserQuery(this.Id.Value));
this.Name = user.Name;
this.Title = $"Change info of {user.Name}";
}
else
{
this.Title = "New user";
}
await base.OnInitializedAsync();
}
protected override async Task Save()
{
UserEntity user = this.Id.HasValue ? await Mediator.Send(new GetUserEditViewQuery(this.Id.Value)) : new UserEntity();
user.Nom = this.Name;
await Mediator.Send(new SaveUserCommand(user));
Close();
}
}
with GetUserEditViewQuery returning an entity with all information needed fetched or in lazy loading.
The code below is an example of what I would do if I use ViewModel.
public partial class UserEditView : EditableComponentBase
{
[Parameter]
public long? Id { get; set; }
public UserViewModel User { get; set; } = new UserViewModel();
protected override async Task OnInitializedAsync()
{
if (this.Id.HasValue)
{
this.User = await Mediator.Send(new GetUserEditViewQuery(this.Id.Value));
this.Title = $"Change info of {this.User.Name}";
}
else
{
this.Title = "New user";
}
await base.OnInitializedAsync();
}
protected override async Task Save()
{
await Mediator.Send(new SaveUserCommand(user));
Close();
}
}
with GetUserEditViewQuery returning a ViewModel containing all information needed.
As you can see, the differences if I didnt use the ViewModel is that the view :
- define the fields that will be displayed itself (without using a ViewModel)
- get the data using a query which return here an entity (but which could return something else if needed) then use it to set the variables
- convert the variables to an entity (or another object if needed) and call a command to save the information
=> this seems really similar to how I would develop a desktop application
I would be interested by the pros and cons of each approach.
UPDATE
@Henk Holterman : I change the GetUserQuery of the example 2 by GetUserEditViewQuery
@Ben Sampica : First, thanks for your answer.
If I understand you correctly,
In a use case "Change user information", the ViewModel (UserEditViewModel) will contain all information needed to edit the user.
In a use case "View user information", the ViewModel (UserViewViewModel : not really nice but ...) will contain all information needed to view the user (which can differ from the change page).
=> the queries are different and so return different ViewModel.
I understood and it makes sense.
But is there only one ViewModel by page or can I use more than one?
Indeed, in some cases, pages contains list with a button which permits the user to add an element in this list.
For me, adding an element in the list will call a new query which add the element in the database then the list is refreshed.
In lot of examples, I see people create a property in the ViewModel of the page (say UserEditViewModel) and populate it in the main query (say GetUserEditViewQuery) which is not really possible here.
If I had to do it, I would certainly do something like this :
this.List = await Mediator.Send(new GetListForUserEditViewQuery());
this.User = await Mediator.Send(new GetUserEditViewQuery());
Would it be correct ?
question from:
https://stackoverflow.com/questions/65833599/is-there-a-reason-to-use-viewmodel-in-blazor-server-side