Je veux utiliser le modèle de vue pour afficher insted du modèle de domaine. Et je souhaite personnaliser une propriété à afficher, comment dois-je procéder? Et est-ce une bonne pratique d'utiliser AutoMapper pour l'affichage?
Voici l'exemple de code:
public class BookController : BaseController
{
private IBookService bookService;
public BookController(IBookService bookService)
{
this.bookService = bookService;
}
public ActionResult Details(int id)
{
var book = bookService.GetBookById(id);
return View(Mapper.Map<BookView>(book));
}
}
public class Book
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class BookView
{
public int Id { get; set; }
public string Name { get; set; }
}
Si j'utilise une autre façon, je peux personnaliser n'importe quelle propriété, comme ci-dessous:
public ActionResult Details(int id)
{
var book = bookService.GetBookById(id);
return View(new BookView(book));
}
public class BookView
{
public BookView(Book book){
Name = book.Name +" Decorated";
}
public int Id { get; set; }
public string Name { get; set; }
}
Comment dois-je procéder? Et est-ce une bonne pratique d'utiliser AutoMapper pour l'affichage?
Mise à jour
Il semble qu'utiliser automapper dans le scénario ci-dessous soit plus approprié. Par exemple, mapper un modèle de vue sur un modèle de domaine comme ci-dessous. Des opinions?
[HttpPost]
public ActionResult Create(BookView bookView)
{
try
{
var book = Mapper.Map<Book>(bookView); //this is wrong
bookService.SaveOrUpdate(book);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Mise à jour 2
Pour un affichage personnalisé complexe via le modèle de vue, je ne veux pas utiliser l'automappeur pour mapper la logique d'affichage, en supposant que l'automappeur peut le mapper. Parce qu'il mélange différents objectifs. Par exemple:
Mapper.CreateMap<Book, BookView>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name + " this is for display purpose"));
Cependant, l'utilisation de la cartographie manuelle comme ci-dessous semble intuitive.
public BookView(Book book){
//mapping here
}
Mise à jour 3
Citation de Jimmy Bogard :
Je pense que l'utilisation d'AutoMapper parce que vous ne voulez pas utiliser l'opérateur "=" est un peu paresseux. Au lieu de cela, nous l'utilisons pour aplatir et remodeler, optimisant pour l'environnement du type de destination. Rappelez-vous, ma motivation initiale pour AutoMapper était:
Activer la protection de la couche de domaine contre d'autres couches en mappant sur les DTO
Merci @AndrewWhitaker pour le lien
Ceci est un bon cas d'utilisation pour AutoMapper (je l'ai utilisé de cette manière de manière intensive sur de nombreux projets avec succès). Généralement, vous faites pas voulez exposer les entités de domaine à votre vue (dans MVC, cela exposerait votre modèle directement à votre vue, ce qui est incorrect).
Vous n'avez pas besoin d'un mappage 1-1 entre l'entité de domaine et le modèle d'affichage. Vous pouvez les rendre complètement différents et personnaliser le mappage dans votre CreateMap<>
appel. Pour utiliser votre exemple:
Mapper.CreateMap<Book, BookView>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name + " Decorated"));
Dans le pire des cas, vous pouvez abandonner l'automappeur pour les cas complexes ou utiliser un résolveur de type personnalisé avec automappeur pour faire le travail.
En fait, c'est ainsi que Jimmy Bogard (l'auteur) recommande d'utiliser AutoMapper . Il mentionne spécifiquement le mappage des entités de domaine vers ASP.NET MVC ViewModels pour une utilisation avec des vues fortement typées.
Un autre avantage est que vous pouvez tester un à un vos profils de cartographie. De cette façon, si vous vous retrouvez avec une incompatibilité entre ViewModel et Model, vous obtiendrez un test unitaire qui échoue.
Mises à jour:
Je pense que la citation que vous avez ajoutée à votre question prend davantage en charge l'utilisation d'AutoMapper pour le mappage des modèles de domaine vers ViewModels:
Au lieu de cela, nous l'utilisons pour aplatir et remodeler, optimisant pour l'environnement du type de destination.
Donc, dans mon exemple, vous seriez certainement optimisé pour l'environnement du type de destination (dans ce cas, une vue).
Aussi par le lien que je référence ci-dessus, vous devriez pas utiliser automapper pour mapper à le domaine, seulement de. Dans cet esprit, vous devrez écrire une logique pour créer/mettre à jour des entités de domaine à partir de ce que vous recevez de la vue, quoi qu'il arrive. N'oubliez pas que les actions du contrôleur ne doivent pas prendre directement les entités de domaine (vous ne devez pas faire confiance aux données provenant directement de la vue - laissez le modèle déterminer si une entité de domaine serait valide ou non).