Podczas serializacji obiektu typu "SubSonic" wykryto Okrężną referencję.Schemat.DatabaseColumn".

Próbuję wykonać prosty zwrot JSON, ale mam problemy, które mam poniżej.

public JsonResult GetEventData()
{
    var data = Event.Find(x => x.ID != 0);
    return Json(data);
}

Dostaję HTTP 500 z wyjątkiem pokazanym w tytule tego pytania. Próbowałem też

var data = Event.All().ToList()
To dało ten sam problem.

Czy to błąd czy moja implementacja?

Author: Glauco Vinicius, 2009-07-20

14 answers

Wydaje się, że w Twojej hierarchii obiektów znajdują się odniesienia okrągłe, które nie są obsługiwane przez serializer JSON. Potrzebujesz wszystkich kolumn? Możesz wybrać tylko te właściwości, których potrzebujesz w widoku:

return Json(new 
{  
    PropertyINeed1 = data.PropertyINeed1,
    PropertyINeed2 = data.PropertyINeed2
});

To sprawi, że Twój obiekt JSON będzie lżejszy i łatwiejszy do zrozumienia. Jeśli masz wiele właściwości, AutoMapper może być użyty do automatycznego mapowania między obiektami DTO i obiektami View.

 178
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-20 12:52:01

Miałem ten sam problem i rozwiązałem przez using Newtonsoft.Json;

var list = JsonConvert.SerializeObject(model,
    Formatting.None,
    new JsonSerializerSettings() {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});

return Content(list, "application/json");
 109
Author: ddfnfal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-23 15:09:23

Dzieje się tak, ponieważ złożone obiekty powodują, że wynikowy obiekt json zawodzi. I nie udaje się, ponieważ gdy obiekt jest mapowany, mapuje dzieci, co mapuje ich rodziców, czyniąc okrężne odniesienie do wystąpienia. JSON zajmie nieskończony czas, aby go serializować, więc zapobiega problemowi z wyjątkiem.

Mapowanie struktury encji również powoduje to samo zachowanie, a rozwiązaniem jest odrzucenie wszystkich niechcianych właściwości.

/ Align = "left" / odpowiedź, cały kod będzie:
public JsonResult getJson()
{
    DataContext db = new DataContext ();

    return this.Json(
           new {
                Result = (from obj in db.Things select new {Id = obj.Id, Name = obj.Name})
               }
           , JsonRequestBehavior.AllowGet
           );
}

Może to być również następujące, jeśli nie chcesz, aby obiekty wewnątrz Result właściwości:

public JsonResult getJson()
{
    DataContext db = new DataContext ();

    return this.Json(
           (from obj in db.Things select new {Id = obj.Id, Name = obj.Name})
           , JsonRequestBehavior.AllowGet
           );
}
 57
Author: ClayKaboom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 13:53:59

Podsumowując, istnieją 4 rozwiązania tego problemu:

Rozwiązanie 1: Wyłącz ProxyCreation dla DBContext i przywróć go na końcu.

    private DBEntities db = new DBEntities();//dbcontext

    public ActionResult Index()
    {
        bool proxyCreation = db.Configuration.ProxyCreationEnabled;
        try
        {
            //set ProxyCreation to false
            db.Configuration.ProxyCreationEnabled = false;

            var data = db.Products.ToList();

            return Json(data, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
        finally
        {
            //restore ProxyCreation to its original state
            db.Configuration.ProxyCreationEnabled = proxyCreation;
        }
    }

Rozwiązanie 2: Używanie JsonConvert przez ustawienie ReferenceLoopHandling do ignorowania w Ustawieniach serializera.

    //using using Newtonsoft.Json;

    private DBEntities db = new DBEntities();//dbcontext

    public ActionResult Index()
    {
        try
        {
            var data = db.Products.ToList();

            JsonSerializerSettings jss = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
            var result = JsonConvert.SerializeObject(data, Formatting.Indented, jss);

            return Json(result, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
    }

następujące dwa rozwiązania są takie same, ale korzystanie z modelu jest lepsze, ponieważ jest mocny typ.

Rozwiązanie 3: zwraca Model zawierający wymagane właściwości tylko.

    private DBEntities db = new DBEntities();//dbcontext

    public class ProductModel
    {
        public int Product_ID { get; set;}

        public string Product_Name { get; set;}

        public double Product_Price { get; set;}
    }

    public ActionResult Index()
    {
        try
        {
            var data = db.Products.Select(p => new ProductModel
                                                {
                                                    Product_ID = p.Product_ID,
                                                    Product_Name = p.Product_Name,
                                                    Product_Price = p.Product_Price
                                                }).ToList();

            return Json(data, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
    }

Rozwiązanie 4: zwraca nowy dynamiczny obiekt zawierający tylko potrzebne właściwości.

    private DBEntities db = new DBEntities();//dbcontext

    public ActionResult Index()
    {
        try
        {
            var data = db.Products.Select(p => new
                                                {
                                                    Product_ID = p.Product_ID,
                                                    Product_Name = p.Product_Name,
                                                    Product_Price = p.Product_Price
                                                }).ToList();

            return Json(data, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
    }
 16
Author: Amro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-13 07:21:08

JSON, podobnie jak xml i inne formaty, jest formatem serializacji opartym na drzewie. Nie będzie cię kochać, jeśli masz okrągłe odniesienia w swoich obiektach, jak "drzewo" byłoby:

root B => child A => parent B => child A => parent B => ...

Często można wyłączyć nawigację wzdłuż określonej ścieżki; na przykład za pomocą XmlSerializer można oznaczyć właściwość nadrzędną jako XmlIgnore. Nie wiem, czy jest to możliwe z omawianym serializerem json, ani czy DatabaseColumn ma odpowiednie znaczniki (bardzo mało prawdopodobne, ponieważ musiałoby się odwoływać każdy API serializacji)

 7
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-20 12:53:23

Its z powodu nowego szablonu DbContext T4, który jest używany do generowania entity Entity Ramework. Aby móc wykonać śledzenie zmian, szablony te wykorzystują wzór Proxy, owijając nimi swoje ładne POCOs. Powoduje to problemy podczas serializacji przy użyciu JavaScriptSerializer.

Zatem 2 rozwiązania to:

  1. albo po prostu serializujesz i zwracasz potrzebne właściwości na kliencie
  2. Możesz wyłączyć automatyczne generowanie proxy poprzez ustawienie go na konfiguracji kontekstu

    Kontekst.Konfiguracja.ProxyCreationEnabled = false;

Bardzo dobrze wyjaśnione w poniższym artykule.

Http://juristr.com/blog/2011/08/javascriptserializer-circular-reference/

 4
Author: nilesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-30 17:15:24

Korzystanie Z Newtonsoft.Json: w Twojej globalnej.metoda ASAX Application_Start dodaj tę linię:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
 4
Author: kravits88,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-23 00:27:38

Dodaj [JsonIgnore] do właściwości wirtualnych w modelu.

 4
Author: MorenajeRD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-04 08:59:12

Unikaj bezpośredniej konwersji obiektu table. Jeśli relacje są ustawione między innymi tabelami, może to spowodować błąd. Można raczej utworzyć klasę modelu, przypisać wartości do obiektu klasy, a następnie serializować go.

 4
Author: Unais.N.I,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 03:58:00

Dostarczone odpowiedzi są dobre, ale myślę, że można je poprawić dodając "architektoniczną" perspektywę.

Dochodzenie

MVC's Controller.Json funkcja wykonuje zadanie, ale jest bardzo słaba w dostarczaniu istotnego błędu w tym przypadku. Używając Newtonsoft.Json.JsonConvert.SerializeObject, Błąd określa dokładnie, jaka jest właściwość wyzwalająca Okrężną referencję. Jest to szczególnie przydatne podczas serializacji bardziej złożonych hierarchii obiektów.

Właściwa Architektura

One nigdy nie należy próbować serializacji modeli danych (np. modeli EF), ponieważ właściwości nawigacyjne ORM są drogą do zatracenia, jeśli chodzi o serializację. Przepływ danych powinien być następujący:

Database -> data models -> service models -> JSON string 

Modele usług można uzyskać z modeli danych za pomocą auto maperów (np. Automapper). Chociaż nie gwarantuje to braku odniesień okrągłych, należy to odpowiednio zaprojektować: modele usług powinny zawierać dokładnie to, czego wymaga konsument usług (tj. właściwości).

W w rzadkich przypadkach, gdy klient żąda hierarchii obejmującej ten sam typ obiektu na różnych poziomach, usługa może utworzyć strukturę liniową z relacją rodzic- > potomek (używając tylko identyfikatorów, nie referencji).

Nowoczesne aplikacje zazwyczaj unikają ładowania złożonych struktur danych na raz, a modele usług powinny być cienkie. Np.:

  1. dostęp do danych nagłówka tylko dla zdarzeń (identyfikator, nazwa, data itp.) jest załadowany - > service model (JSON) zawierający tylko nagłówek dane
  2. Lista zarządzanych uczestników-dostęp do wyskakującego okienka i leniwe Ładowanie listy - > modelu usługi (JSON) zawierającego tylko listę uczestników]}
 3
Author: Alexei - check Codidact,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-06 07:32:14

Używam FIXA, ponieważ używam Knockoutu w widokach MVC5.

On action

return Json(ModelHelper.GetJsonModel<Core_User>(viewModel));

Funkcja

   public static TEntity GetJsonModel<TEntity>(TEntity Entity) where TEntity : class
    {
        TEntity Entity_ = Activator.CreateInstance(typeof(TEntity)) as TEntity;
        foreach (var item in Entity.GetType().GetProperties())
        {
            if (item.PropertyType.ToString().IndexOf("Generic.ICollection") == -1 && item.PropertyType.ToString().IndexOf("SaymenCore.DAL.") == -1)
                item.SetValue(Entity_, Entity.GetPropValue(item.Name));
        }
        return Entity_;  
    }
 1
Author: A.Kosecik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-14 12:00:41

Można zauważyć właściwości, które powodują odniesienia kołowe. Wtedy możesz zrobić coś takiego:

private Object DeCircular(Object object)
{
   // Set properties that cause the circular reference to null

   return object
}
 0
Author: Bassel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-21 06:07:27
//first: Create a class as your view model

public class EventViewModel 
{
 public int Id{get;set}
 public string Property1{get;set;}
 public string Property2{get;set;}
}
//then from your method
[HttpGet]
public async Task<ActionResult> GetEvent()
{
 var events = await db.Event.Find(x => x.ID != 0);
 List<EventViewModel> model = events.Select(event => new EventViewModel(){
 Id = event.Id,
 Property1 = event.Property1,
 Property1 = event.Property2
}).ToList();
 return Json(new{ data = model }, JsonRequestBehavior.AllowGet);
}
 -1
Author: Ynnoboy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-24 07:24:31

Łatwiejszą alternatywą rozwiązania tego problemu jest zwrócenie ciągu znaków i sformatowanie go do JSON za pomocą JavaScriptSerializer.

public string GetEntityInJson()
{
   JavaScriptSerializer j = new JavaScriptSerializer();
   var entityList = dataContext.Entitites.Select(x => new { ID = x.ID, AnotherAttribute = x.AnotherAttribute });
   return j.Serialize(entityList );
}

Ważne jest, aby część "Wybierz", która wybiera właściwości, które chcesz w widoku. Niektóre obiekty mają odniesienie do rodzica. Jeśli nie wybierzesz atrybutów, może pojawić się okrągłe odniesienie, jeśli po prostu weźmiesz tabele jako całość.

Nie rób tego:

public string GetEntityInJson()
{
   JavaScriptSerializer j = new JavaScriptSerializer();
   var entityList = dataContext.Entitites.toList();
   return j.Serialize(entityList );
}

Zrób to zamiast tego, jeśli nie chcesz całego stołu:

public string GetEntityInJson()
{
   JavaScriptSerializer j = new JavaScriptSerializer();
   var entityList = dataContext.Entitites.Select(x => new { ID = x.ID, AnotherAttribute = x.AnotherAttribute });
   return j.Serialize(entityList );
}

To pomaga renderować widok z mniejszą ilością danych, tylko z potrzebnymi atrybutami i sprawia, że Twoja sieć działa szybciej.

 -1
Author: Sterling Diaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-29 22:55:01