5

Serializzazione JSON (API Web ASP.Net) non riuscita a causa del loop autoreferenziale (è un problema comune, Motivo: un'entità viene richiesta carichi pigri entità figlio e ogni bambino ha un riferimento all'entità padre).Ottenere JSON serializzazione Entity Framework Riferimento auto Errore di loop anche dopo ProxyCreation false quando si utilizza esplicita Include

lavoro in giro ho trovato, ma non mi aiuta:

  1. Use [JsonIgnore] for navigation properties to be ignored: questa soluzione funziona, ma non si applica nel mio caso. Ad esempio: per ottenere informazioni sul cliente insieme ai suoi ordini, aggiungerei rapidamente [JsonIgnore] alla proprietà del cliente nella classe dell'ordine, ma quando voglio ottenere informazioni sull'ordine insieme ai dettagli del cliente, poiché c'è [JsonIgnore] nella proprietà del cliente , non includerà i dettagli del cliente.
  2. Change JSON.Net Serializer Settings to Preserve References: Impossibile conservare perché non ho bisogno di dati di riferimento circolare.
  3. Disable Proxy Creation at the Data Context and use explicit loading(this should ideally solve the problem): Disabilitare la creazione di proxy ferma caricamento pigro e restituisce i dati senza errori, ma quando ho includere esplicitamente entità figlio, ho di nuovo l'errore di ottenere il circuito autoreferenziale inaspettato! L'errore è al livello di riferimento precedente all'entità padre.

Eventuali esperienze lungo le stesse linee/suggerimenti?

+0

Si prega di inviare qualche codice del tuo modello –

risposta

3

Ho provato tutte le soluzioni proposte, ma non ha funzionato. Finito con Override DefaultContractResolver del JSON.Net serializzatore a questo:

public class FilterContractResolver : DefaultContractResolver 
{ 
    Dictionary<Type, List<string>> _propertiesToIgnore; 

    public FilterContractResolver(Dictionary<Type, List<string>> propertiesToIgnore) 
    { 
     _propertiesToIgnore = propertiesToIgnore; 
    } 

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     var property = base.CreateProperty(member, memberSerialization); 
     List<string> toIgnore; 
     property.Ignored |= ((_propertiesToIgnore.TryGetValue(member.DeclaringType, out toIgnore) || _propertiesToIgnore.TryGetValue(member.DeclaringType.BaseType, out toIgnore)) && toIgnore.Contains(property.PropertyName)); 
     return property; 
    } 
} 

poi creato una classe statica che restituisce un dizionario di Proprietà per essere ignorato basato sul controller:

public static class CriteriaDefination 
{ 
    private static Dictionary<string, Dictionary<Type, List<string>>> ToIgnore = new Dictionary<string, Dictionary<Type, List<string>>> 
    { 
     { 
      "tblCustomer", new Dictionary<Type, List<string>>{ 
       { 
        typeof(tblCustomer), new List<string>{ 
         //include all 
        } 
       }, 
       { 
        typeof(tblOrder), new List<string>{ 
         "tblCustomer"//ignore back reference to tblCustomer 
        } 
       } 
      } 
     }, 
     { 
      "tblOrder", new Dictionary<Type, List<string>>{ 
       { 
        typeof(tblCustomer), new List<string>{ 
         "tblOrders"//ignore back reference to tblOrders 
        } 
       }, 
       { 
        typeof(tblOrder), new List<string>{ 
         //include all 
        } 
       } 
      } 
     } 
    }; 
    public static Dictionary<Type, List<string>> IgnoreList(string key) 
    { 
     return ToIgnore[key]; 
    } 
} 

E dentro ogni controller cambia il JSON Formatter qualcosa come:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new FilterContractResolver(CriteriaDefination.IgnoreList("tblCustomer")); 
2

Questo è quello che ho finito per sistemarmi, speriamo che aiuti qualcun altro.

dicono i corsi EF sono strutturati in questo modo:

public partial class MyEF 
{ 
    public virtual ICollection<MyOtherEF> MyOtherEFs {get; set;} 
} 
public partial class MyOtherEF 
{ 
    public virtual MyEF MyEF {get; set;} 
} 

Per mantenere forma serializzazione accadendo in JSON.NET, è possibile estendere la classe e aggiungere un metodo con il nome "ShouldSerialize" + nome della proprietà in questo modo :

public partial class MyEF 
{ 
    public bool ShouldSerializeMyOtherEFs() { return false; } 
} 

Se si voleva ottenere un po 'più di fantasia, si potrebbe aggiungere la logica nel metodo in modo che fosse serializzare in alcuni casi. Ciò consente di mantenere la logica di serializzazione fuori dalla creazione del codice EF Model First, purché questo codice si trovi in ​​un diverso file di codice fisico.