Próbowałem serializować klasę POCO, która została automatycznie wygenerowana z Entity Data Model .edmx i kiedy jej użyłem
JsonConvert.SerializeObject
Wystąpił następujący błąd:
Błąd Wykryto pętlę odwoływania się do typu System.data.entity.
Jak rozwiązać ten problem?
json
serialization
json.net
NevenHuynh
źródło
źródło
async
wywołania metody (aTask
) i zapomniałem poprzedzićawait
instrukcję.Odpowiedzi:
To było najlepsze rozwiązanie https://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7
Poprawka 1: Globalne ignorowanie odniesienia cyklicznego
(Wybrałem / wypróbowałem ten, podobnie jak wiele innych)
Serializator json.net ma opcję ignorowania odwołań cyklicznych. Umieść następujący kod w
WebApiConfig.cs
pliku:Prosta poprawka sprawi, że serializator zignoruje odwołanie, co spowoduje pętlę. Ma jednak ograniczenia:
Jeśli chcesz użyć tej poprawki w projekcie ASP.NET bez interfejsu API, możesz dodać powyższą linię do
Global.asax.cs
, ale najpierw dodaj:Jeśli chcesz użyć tego w projekcie .Net Core , możesz zmienić
Startup.cs
jako:Poprawka 2: Zachowanie globalnego odniesienia cyklicznego
Ta druga poprawka jest podobna do pierwszej. Po prostu zmień kod na:
Kształt danych zostanie zmieniony po zastosowaniu tego ustawienia.
Identyfikatory $ id i $ ref utrzymują wszystkie odwołania i wyrównują poziom wykresu obiektowego, ale kod klienta musi znać zmianę kształtu, aby zużywać dane, i dotyczy to również serializatora JSON.NET.
Poprawka 3: Zignoruj i zachowaj atrybuty odniesienia
Ta poprawka dekoruje atrybuty klasy modelu, aby kontrolować zachowanie serializacji na poziomie modelu lub właściwości. Aby zignorować właściwość:
JsonIgnore jest dla JSON.NET, a IgnoreDataMember jest dla XmlDCSerializer. Aby zachować odniesienie:
JsonObject(IsReference = true)]
dotyczy JSON.NET i[DataContract(IsReference = true)]
dotyczy XmlDCSerializer. Uwaga: po zastosowaniuDataContract
na zajęciach musisz dodaćDataMember
do właściwości, które chcesz serializować.Atrybuty mogą być stosowane zarówno w serializerze json, jak i xml i dają większą kontrolę nad klasą modelu.
źródło
[JsonIgnore]
powyższego atrybutu działało dla mnie.Użyj JsonSerializerSettings
ReferenceLoopHandling.Error
(domyślnie) spowoduje błąd, jeśli napotkamy pętlę odniesienia. Dlatego otrzymujesz wyjątek.ReferenceLoopHandling.Serialize
jest przydatny, jeśli obiekty są zagnieżdżone, ale nie w nieskończoność.ReferenceLoopHandling.Ignore
nie będzie serializować obiektu, jeśli jest on obiektem potomnym.Przykład:
W przypadku konieczności serializacji obiektu zagnieżdżonego w nieskończoność można użyć PreserveObjectReferences, aby uniknąć wyjątku StackOverflowException.
Przykład:
Wybierz, co ma sens dla serializowanego obiektu.
Odniesienie http://james.newtonking.com/json/help/
źródło
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
to działałoReferenceLoopHandling.Serialize
spowoduje, że serializator przejdzie w nieskończoną pętlę rekurencyjną i przepełni stos.Rozwiązaniem jest ignorowanie odniesień do pętli i nie serializowanie ich. To zachowanie jest określone w
JsonSerializerSettings
.Single
JsonConvert
z przeciążeniem:Ustawienie globalne z kodem
Application_Start()
w Global.asax.cs:Odniesienie: https://github.com/JamesNK/Newtonsoft.Json/issues/78
źródło
Najprostszym sposobem na to jest zainstalowanie Json.NET z nuget i dodanie
[JsonIgnore]
atrybutu do właściwości wirtualnej w klasie, na przykład:Chociaż w dzisiejszych czasach tworzę model z właściwościami, które chcę przekazać, dzięki czemu jest lżejszy, nie zawiera niechcianych kolekcji i nie tracę zmian po odbudowaniu wygenerowanych plików ...
źródło
W .NET Core 1.0 możesz ustawić to jako ustawienie globalne w pliku Startup.cs:
źródło
Jeśli używasz .NET Core 2.x, zaktualizuj sekcję ConfigureServices w pliku Startup.cs
https://docs.microsoft.com/en-us/ef/core/querying/related-data#related-data-and-serialization
Jeśli używasz .NET Core 3.x bez MVC, byłoby to:
Ta obsługa pętli referencyjnych jest prawie obowiązkowa, jeśli używasz Entity Framework i wzorca projektowego opartego na bazie danych.
źródło
services.AddMvc()
?Aby serializować nas w NEWTONSOFTJSON, gdy masz problem z pętlą, w moim przypadku nie potrzebowałem modyfikować global.asax ani apiconfig. Po prostu używam JsonSerializesSettings ignorując obsługę zapętlania.
źródło
Newtonsoft.Json.JsonConvert.SerializeObject(objToSerialize, new Newtonsoft.Json.JsonSerializerSettings() {ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore});
Możemy dodać te dwa wiersze do konstruktora klasy DbContext, aby wyłączyć pętlę odwoływania się do siebie, np
źródło
Możesz także zastosować atrybut do właściwości. Ten
[JsonProperty( ReferenceLoopHandling = ... )]
atrybut jest do tego odpowiedni.Na przykład:
Mam nadzieję, że to pomaga, Jaans
źródło
Aby zignorować odwołania do pętli i nie serializować ich globalnie w MVC 6, skorzystaj z następujących poleceń w pliku startup.cs:
źródło
Użyj tego w
WebApiConfig.cs
klasie:źródło
Dla mnie musiałem wybrać inną trasę. Zamiast próbować naprawić serializator JSON.Net musiałem pójść po Leniwym ładowaniu w moim tekście.
Właśnie dodałem to do mojego podstawowego repozytorium:
Obiekt „kontekstowy” jest parametrem konstruktora, którego używam w moim podstawowym repozytorium, ponieważ używam wstrzykiwania zależności. Zamiast tego możesz zmienić właściwość ProxyCreationEnabled w dowolnym miejscu, w którym utworzony zostanie tekst danych.
http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html
źródło
Miałem ten wyjątek, a moje działające rozwiązanie jest łatwe i proste,
Zignoruj właściwość Referenced, dodając do niej atrybut JsonIgnore:
Zresetuj właściwość podczas deserializacji:
using Newtonsoft.Json;
źródło
[JsonIgnore]
Zespół:
Działa to z ASP.NET Core; Wyzwanie związane z powyższym polega na tym, jak „ustawić ustawienie na ignorowanie”. W zależności od konfiguracji aplikacji może to być dość trudne. Oto, co zadziałało dla mnie.
Można to umieścić w swojej publicznej nieważnej sekcji ConfigureServices (usługi IServiceCollection).
źródło
Ludzie mówili już o dodaniu [JsonIgnore] do wirtualnej właściwości w klasie, na przykład:
Podzielę się również inną opcją, [JsonProperty (NullValueHandling = NullValueHandling.Ignore)], która pomija właściwość serializacji tylko wtedy, gdy jest null:
źródło
W przypadku .NET Core 3.0 zaktualizuj klasę Startup.cs, jak pokazano poniżej.
Zobacz: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-5/
źródło
Po prostu umieść
Configuration.ProxyCreationEnabled = false;
w pliku kontekstowym; to rozwiąże problem.źródło
Mój problem rozwiązany dzięki niestandardowej konfiguracji JsonSerializerSettings:
źródło
Upewnij się również, że używasz metody Oczekuj i asynchronizuj w swojej metodzie. Ten błąd można uzyskać, jeśli obiekt nie jest poprawnie serializowany.
źródło
Miałem do czynienia z tym samym problemem i próbowałem użyć JsonSetting, aby zignorować błąd samoreferencji, który działał, dopóki nie otrzymałem klasy, która sam się tak bardzo odwołuje, a mój proces dot-net opiera się na wartości zapisu Jsona.
Mój problem
Problem można zobaczyć w klasie użytkownika, która odnosi się do CompanyUser klasy która jest samodzielna.
Teraz wywołuję metodę GetAll, która zawiera wszystkie właściwości relacyjne.
Na tym etapie mój proces DotNetCore opiera się na wykonywaniu JsonResult, zapisywaniu wartości ... i nigdy nie nadchodzi. W moim Startup.cs już ustawiłem JsonOption. Z jakiegoś powodu EFCore zawiera zagnieżdżoną właściwość, której nie proszę Ef o podanie.
takie powinno być oczekiwane zachowanie
następnie
na tym etapie powinienem otrzymać tylko „Company.CompanyUsers.First (). User.DisplayName” i nie powinien dać mi Company.CompanyUsers.First (). User.CompanyUsers, który powoduje problem z samodzielnym odwoływaniem się; Technicznie nie powinno dać mi User.CompanyUsers, ponieważ CompanyUsers jest własnością nawigacyjną. Ale EfCore jest bardzo podekscytowany i daje mi User.CompanyUsers .
Postanowiłem więc napisać metodę rozszerzenia właściwości, która ma zostać wykluczona z obiektu (tak naprawdę to nie wyklucza, po prostu ustawia właściwość na null). Nie tylko zadziała również na właściwości tablicy. poniżej znajduje się kod Wyeksportuję również pakiet nuget dla innych użytkowników (nie jestem pewien, czy to komuś pomoże). Powód jest prosty, ponieważ jestem zbyt leniwy, aby pisać. Wybierz (n => new {n.p1, n.p2}); Po prostu nie chcę pisać instrukcji select, aby wykluczyć tylko 1 właściwość!
To nie jest najlepszy kod (na pewnym etapie zaktualizuję), ponieważ napisałem w pośpiechu i chociaż może to pomóc komuś, kto chce wykluczyć (ustawić null) również w obiekcie z tablicami.
powyżej klasy rozszerzenia daje możliwość ustawienia właściwości na null, aby uniknąć pętli odwołujących się nawet do tablic.
Konstruktor wyrażeń
Zastosowania:
Klasy modeli
Dummy Data
Skrzynie:
Przypadek 1: Wyklucz tylko właściwość bez tablicy
Przypadek 2: Wyklucz właściwość z 1 tablicą
Przypadek 3: Wyklucz właściwość z 2 zagnieżdżonymi tablicami
Przypadek 4: EF GetAll Query With Includes
Zauważyłeś, że metoda Explode () jest również metodą rozszerzenia tylko dla naszego konstruktora wyrażeń, aby uzyskać właściwość z właściwości tablicy. Ilekroć istnieje właściwość tablicowa, użyj .Explode (). YourPropertyToExclude lub .Explode (). Property1.MyArrayProperty.Explode (). MyStupidProperty . Powyższy kod pomaga mi uniknąć odwoływania się do siebie tak głęboko, jak chcę. Teraz mogę korzystać z GetAll i wykluczyć właściwość, której nie chcę!
Dziękujemy za przeczytanie tego dużego posta!
źródło
Za to, że nie zapętlałem, działało to dla mnie-
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Rozwiązałem to wszystko tutaj - serializacja dzieci Entity Framework za pomocą .AP Core 2 WebAPI https://gist.github.com/Kaidanov/f9ad0d79238494432f32b8407942c606
Z pewnością docenią wszelkie uwagi. może ktoś może go kiedyś użyć.
źródło
Kod C #:
źródło
Podobało mi się rozwiązanie, które robi to
Application_Start()
tak, jak w odpowiedzi tutajNajwyraźniej nie mogłem uzyskać dostępu do obiektów json w JavaScript przy użyciu konfiguracji w ramach mojej funkcji, jak w odpowiedzi DalSoft, ponieważ zwrócony obiekt miał „\ n \ r” na całym (klucz, val) obiekcie.
W każdym razie wszystko, co działa, jest świetne (ponieważ różne podejścia działają w różnych scenariuszach w zależności od zadanych komentarzy i pytań), chociaż lepiej byłoby zastosować standardowy sposób postępowania z dobrą dokumentacją potwierdzającą to podejście.
źródło