Gestire referenze circolari in un JsonResult di ASP.NET MVC

di Marco De Sanctis, in ASP.NET MVC,

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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi