Aller au contenu principal

ViewModel et mapping Model ViewModel

Un ViewModel sélectionne les champs d'un ou de plusieurs modèles pour exposer une forme adaptée aux écrans, aux API ou aux grilles. Les ViewModels sont généralement placés dans le projet Shared et préfixés par Vm.

Création d'un ViewModel​

Créez une classe dédiée contenant uniquement les champs à exposer à l'écran, à l'API ou à la grille. Le ViewModel peut regrouper des propriétés issues d'un ou de plusieurs modèles EF Core.

Mapping​

Le framework serveur Lagoon n'expose pas d'API générique de mapping Model ↔ ViewModel. Les conversions sont du code applicatif : créez des méthodes d'extension ou projetez directement les entités EF Core dans vos requêtes.

L'exemple suivant montre un mapping applicatif simple.

VmPizzaMapping.cs
public static class VmPizzaMapping
{
public static VmPizza GetNewVmPizza(this Order order)
{
// Crée un ViewModel à partir du modèle EF Core.
VmPizza vmPizza = new();
vmPizza.MapFromModel(order);
return vmPizza;
}

public static Order GetNewOrder(this VmPizza vmPizza)
{
// Crée un modèle EF Core à partir du ViewModel.
Order order = new();
vmPizza.MapToModel(order);
return order;
}

public static void MapFromModel(this VmPizza vmPizza, Order order = null)
{
// Copie ici les propriétés du modèle vers le ViewModel.
}

public static void MapToModel(this VmPizza vmPizza, Order order = null)
{
// Copie ici les propriétés du ViewModel vers le modèle.
}
}

Exemple de ViewModel partagé​

Les ViewModels de Lagoon suivent les conventions générales des DTOs : nom préfixé par Vm, propriétés publiques et documentation XML pour les membres publics.

VmCountryFirm.cs
public class VmCountryFirm
{
public Guid Id { get; set; }

public string FirmName { get; set; }
}

Utilisation côté serveur​

Un contrôleur peut projeter directement les entités EF Core vers un ViewModel. Lorsque le résultat est destiné à une grille distante, retournez une requête IQueryable<T> et appliquez [Queryable].

FirmsController.cs
[Authorize]
[Route("api/[controller]")]
public class FirmsController : LgControllerBase
{
private readonly ApplicationDbContext _db;

public FirmsController(ApplicationDbContext db)
{
_db = db;
}

[Queryable]
[HttpGet("GetFirmsByCountry")]
public IQueryable<VmCountryFirm> Get(QueryArg<int?> data)
{
// Projette l'entité EF Core vers le ViewModel exposé au client.
return _db.Firms.Where(c => c.CountryId == data.Value).Select(x => new VmCountryFirm
{
Id = x.Id,
FirmName = x.Name,
});
}
}

Bonnes pratiques​

SujetRecommandation
EmplacementViewModels dans Shared, conversions dans du code applicatif côté serveur ou modèle.
NomPréfixer les ViewModels par Vm.
SérialisationUtiliser les attributs de sérialisation attendus par le projet si le ViewModel transite entre client et serveur.
MappingCentraliser les conversions Model ↔ ViewModel dans du code applicatif explicite.
RequêtesProjeter en IQueryable<T> lorsque [Queryable] doit appliquer filtres, tris et pagination.

Voir aussi​