Nel precedente script abbiamo visto come l'utilizzo di una entità di Entity Framework possa portare a problemi nella serializzazione JSON a causa delle referenze circolari. L'esempio citato, però, è solo la punta dell'iceberg di una serie di problematiche che sorgono nel momento in cui esponiamo direttamente a utilizzatori esterni le entità di dominio.
Il modo corretto di procedere in queste casistiche, infatti, è quello di esporre il dato sotto forma di DTO (Data Transfer Object), ossia oggetti creati appositamente per essere condivisi verso l'esterno, magari con una strutturazione differente rispetto alle entità. I benefici sono molteplici:
- Se il dominio dovesse variare, i DTO assicurano che il messaggio scambiato con l'esterno rimanga invece il medesimo;
- tipicamente i modelli di dominio hanno una sovrastrutturazione rispetto a quanto è necessario comunicare all'esterno: per esempio, per un ordine può essere sufficiente una proprietà stringa con il nome del cliente, piuttosto che una reference verso una entità cliente;
- le entità di dominio possono avere dei dati che non vogliamo esporre all'esterno, quali identificativi, campi di servizio, informazioni riservate.
Consideriamo l'esempio di un ordine:
public class Order { public int Id { get; set; } public DateTime Date { get; set; } public Customer Customer { get; set; } ... }
Un data transfer object corrispondente potrebbe avere la seguente forma:
public class OrderDto { public DateTime Date { get; set; } public string Customer { get; set; } ... }
Gestire oggetti di questo tipo, però, può risultare molto tedioso, perché ci troviamo spesso a fare assegnazioni di proprietà tra l'una e l'altra tipologia di ordine. Proprio per evitare tutto questo codice boiler plate, possiamo utilizzare un tool, denominato Automapper, che è disponibile gratuitamente su NuGet.

Grazie ad Automapper, infatti, possiamo creare un mapping tra Order e OrderDto in modo che le assegnazioni vengano effettuate in maniera del tutto automatica. Allo startup dell'applicazione, non dobbiamo far altro che scrivere questo codice:
protected void Application_Start() { // ... Mapper.CreateMap<Order, OrderDto>() .ForMember(x => x.Customer, x => x.MapFrom(y => y.Customer.Name)); Mapper.AssertConfigurationIsValid(); }
La logica di funzionamento che regola la conversione è molto semplice: dove non specificato diversamente, tutte le proprietà dell'oggetto di destinazione (in questo caso OrderDto) vengono recuperate dalle proprietà omonime dell'oggetto origine (e quindi Order). Ovviamente questa regola non è sempre applicabile, e per questa ragione Automapper consente di specificare una serie di direttive. Per esempio, nel codice in alto, stiamo mappando la proprietà OrderDto.Customer, di tipo stringa, con la proprietà Name di Order.Customer.
La chiamata ad AssertConfigurationIsValid va poi effettuata a valle della configurazione, per verificare che tutte le impostazioni siano corrette.
Ciò che è importante, è che con i DTO abbiamo assoluto controllo di ciò che, per esempio, esponiamo all'esterno nella forma di un oggetto serializzato in formato JSON:
public ActionResult JsonDemo(int id) { var order = OrderRepository.Get(id); var model = Mapper.Map<OrderDto>(order); return this.Json(order, JsonRequestBehavior.AllowGet); }
Automapper è molto flessibile e presenta diverse opzioni di personalizzazione, per le quali rimandiamo alla guida ufficiale:
https://github.com/AutoMapper/AutoMapper/wiki
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Recuperare App Service cancellati su Azure
Filtering sulle colonne in una QuickGrid di Blazor
Creare una libreria CSS universale: Nav menu
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Migliorare la sicurezza dei prompt con Azure AI Studio
Utilizzare Copilot con Azure Cosmos DB
Testare l'invio dei messaggi con Event Hubs Data Explorer
Documentare i servizi REST con Swagger e OpenAPI con .NET 9
Path addizionali per gli asset in ASP.NET Core MVC
Utilizzare Azure Cosmos DB con i vettori
Sfruttare gli embedding e la ricerca vettoriale con Azure SQL Database
Sfruttare GPT-4o realtime su Azure Open AI per conversazioni vocali
I più letti di oggi
- .NET Conference Italia 2024 - Milano
- Develop and distribute Azure Functions using K8s and CI/CD
- Disponibile la versione finale di Hyper-V: la virtualizzazione per Windows Server 2008
- Speciale Mastering Entity Framework
- Velocity arriva alla CTP3
- Silverlight Summer: un'estate speciale piena di Style per i controlli Silverlight!
- Disponibile la versione beta di Silverlight 4.0
- Mono 0.13: ora anche web services
- .NET Alerts Software Development Kit