I modelli di dominio che utilizziamo con Entity Framework tipicamente presentano relazioni bidirezionali: da un Customer possiamo esplorare la lista dei suoi Order, e dal singolo Order possiamo accedere al Customer a cui appartiene:
public class Customer { public string Name { get; set; } public List<Order> Orders { get; set; } } public class Order { public int Number { get; set; } public Customer Customer { get; set; } }
Un oggetto di questo tipo non è direttamente utilizzabile in un JsonResult a causa della referenza circolare che lo contraddistingue, ossia che la relazione Customer -> Order -> Customer può essere percorsa all'infinito. Una action come la seguente, infatti, solleverà una InvalidOperationException:
public ActionResult JsonDemo() { var c = new Customer() { Name = "Marco" }; var o = new Order { Number = 1, Customer = c }; c.Orders.Add(o); return this.Json(c, JsonRequestBehavior.AllowGet); }

Quando abbiamo accesso diretto agli oggetti di dominio, per esempio perché stiamo utilizzando Entity Framework Code First, questo problema può essere facilmente risolto: ASP.NET MVC, infatti, internamente usa l'oggetto JavaScriptSerializer, che ignora tutte le proprietà marcate con l'attributo ScriptIgnoreAttribute:
public class Order { public int Number { get; set; } [ScriptIgnore] public Customer Customer { get; set; } }
Si tratta di una soluzione adatta però solo a casi particolarmente semplici, perché come detto è applicabile solo quando abbiamo effettivamente la possibilità di modificare il codice della classe di dominio. In generale, invece, utilizzare direttamente le nostre entity per questo scopo non è una best practice. Nel prossimo script presenteremo una soluzione di utilizzo più generale, anche se al costo di una maggiore quantità di codice.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Applicare un filtro per recuperare alcune issue di GitHub
Disabilitare automaticamente un workflow di GitHub
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
Sfruttare gli embedding e la ricerca vettoriale con Azure SQL Database
Modificare i metadati nell'head dell'HTML di una Blazor Web App
Popolare una classe a partire dal testo, con Semantic Kernel e ASP.NET Core Web API
Utilizzare il trigger SQL con le Azure Function
Supportare la sessione affinity di Azure App Service con Application Gateway
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Utilizzare una qualunque lista per i parametri di tipo params in C#
Simulare Azure Cosmos DB in locale con Docker