2011-11-02 20 views
11

Posiadam obiekt encji encji, który chcę przekształcić do postaci szeregowej jako obiekt json. Rozejrzałem się i dowiedziałem się, że json.net (http://james.newtonking.com/projects/json-net.aspx) powinien móc serializować obiekty z odwołaniami cyklicznymi "po wyjęciu z pudełka". Tak więc próbowałem używaćjson.net; serializacja obiektu struktury encji (błąd odwołania cyklicznego)

Ale nadal otrzymuję ten sam błąd. Problem może być, że muszę użyć ReferenceLoopHandling.Ignore i ContractResolver, ale nie jestem pewien, jak z nich korzystać. Każda pomoc jest doceniana! Dzięki

+0

możliwe duplikat [Serializować jednostki ramowej przedmiotów do JSON] (http://stackoverflow.com/questions/657939/serialize-entity-framework-objects-into- json) –

+2

@CraigStuntz nie, ponieważ nie chcę mapować właściwości maunally na nowy obiekt. I pytam, jak to zrobić za pomocą JSON.NET – Johan

+0

Proponowane rozwiązanie będzie działać dla JSON.NET.Jeśli wolisz radzić sobie z odwołaniami cyklicznymi niż z instrukcją przypisania, cóż, to zależy od ciebie. Ale JSON.NET nie oznacza, że ​​inne rozwiązanie nie zadziała. –

Odpowiedz

2

Moim rozwiązaniem było po prostu usunięcie referencji nadrzędnej na moje elementy podrzędne.

Tak więc w moim modelu wybrałem relację i zmieniono odwołanie nadrzędne na Odwołanie wewnętrzne, a nie publiczne.

Może nie być idealnym rozwiązaniem dla wszystkich, ale dla mnie działa.

14

Aby obejść ten problem, przekonwertowałem moje jednostki na oparty na POCO kod pierwszy. Aby to zrobić, kliknij prawym przyciskiem myszy w oknie edmx i wybierz:

Dodaj element generujący kod> zakładka Code> EF POCO Entity Generator.

Należy pamiętać, że może być konieczne zainstalowanie go za pomocą nuget, jeśli go nie widzisz.

W czasie działania EF dodaje klasy proxy do tych obiektów do celów śledzenia, ale mają one tendencję do zepsucia procesu serializacji. Aby temu zapobiec możemy po prostu ustawić ProxyCreationEnabled false następująco:

var context = new YourEntities(); 
context.Configuration.ProxyCreationEnabled = false; 

var results = context.YourEntity.Take(100).ToList(); 

Następnie można bezpiecznie wrócić Json.NET danych odcinkach przez pominięcie odniesienia domyślnego zapętlenie następująco:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new JsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    }); 
+4

+1 dla 'ReferenceLoopHandling.Ignore' - zapisał mój dzień! – nrodic

1

Spróbuj tego: po pierwsze upewniając poco lub model ma DataContract, DataMemeber i usunąć wirtualny klawisz word..then ..

public string Get() 
    { 
     var list = _languageRepository.GetMany(l => l.LanguageTrans.FirstOrDefault().CultureCode == "en").ToList(); 

     string json = JsonConvert.SerializeObject(list, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); 

     return json; 
    } 
+0

W ten sposób można zachować powiązane jednostki ... – Bryant

9

Innym rozwiązaniem będzie dodanie [JsonIgnore] Attribut e do twoich właściwości nawigacyjnych.

Na przykład:

using System; 
using System.ComponentModel.DataAnnotations.Schema; 

[Serializable] 
public class Entity 
{ 
    public int EntityID { get; set; } 
    public string EntityName { get; set; } 

    [JsonIgnore] 
    public virtual Parent Parent { get; set; } 
    [JsonIgnore] 
    public virtual List<Child> Children { get; set; } 
} 
+0

To jest właściwa odpowiedź, jednostki powinny się nawzajem odwoływać. Ale musisz zignorować własność obiektu nadrzędnego w potomstwie. – Darren

+1

Ale co jeśli chcę zobaczyć relację z punktu widzenia elementów podrzędnych? –

6

użyłem następujące rozwiązanie sklonować moje podmioty, żadnych sztuczek, gdzie wymagane dane dotyczące atrybutów podmiotów i moim stole odniesień kołowych został zachowany. Miałem nawet istoty wskazujące na siebie bez żadnych problemów. Wymagana biblioteka do serializacji to Json.Net (biblioteka Newtonsoft.Json).

private static T CloneObject<T>(T obj) 
    { 
     if (obj == null) 
      return obj; 
     string ser = JsonConvert.SerializeObject(obj, Formatting.Indented, 
      new JsonSerializerSettings() { 
           NullValueHandling = NullValueHandling.Ignore, 
           MissingMemberHandling = MissingMemberHandling.Ignore, 
           ReferenceLoopHandling = ReferenceLoopHandling.Ignore}); 
     return (T) JsonConvert.DeserializeObject(ser, obj.GetType()); 
    } 

Przykład użycia:

protected object CopyObj(Object obj) 
    { 
     return CloneObject(obj); 
    } 
    var cust1 = this.cts.Customers().Where(cc => cc.Id == 3).Include(cc => cc.Addresses).FirstOrDefault(); 
    var cust2 = CopyObj(cust1) as Customers; 
    //Cust2 now includes copies of the customer record and its addresses 
Powiązane problemy