web-dev-qa-db-fra.com

Json Une référence circulaire a été détectée lors de la sérialisation d'un objet de type

Donnez aux classes:

public class Parent
{
    public int id {get; set;}
    public int name {get; set;}

    public virtual ICollection<Child> children {get; set;}
}

[Table("Child")]
public partial class Child
{
    [Key]
    public int id {get; set;}
    public string name { get; set; }

    [NotMapped]
    public string nickName { get; set; }
}

Et le code du contrôleur:

List<Parent> parents = parentRepository.Get();
return Json(parents); 

Il fonctionne sur LOCALHOST, mais il ne fonctionne pas sur le serveur en direct:

ERREUR: Json Une référence circulaire a été détectée lors de la sérialisation d'un objet de type

J'ai fait une recherche et trouvé le [ScriptIgnore] attribut, j'ai donc changé le modèle en

using System.Web.Script.Serialization;

public class Parent
{
    public int id {get; set;}
    public int name {get; set;}

    [ScriptIgnore]
    public virtual ICollection<Child> children {get; set;}
}

Mais la même erreur se produit sur le serveur en direct (win2008).

Comment puis-je éviter cette erreur et sérialiser les données parent avec succès?

23
Expert wanna be

Essayez le code suivant:

return Json(
    parents.Select(x => new {
        id = x.id,
        name = x.name,
        children = x.children.Select(y => new {
            // Assigment of child fields
        })
    })); 

... ou si vous n'avez besoin que des propriétés parent:

return Json(
    parents.Select(x => new {
        id = x.id,
        name = x.name
    })); 

Ce n'est pas vraiment la solution au problème, mais c'est une solution de contournement courante lors de la sérialisation des DTO ...

47
RMalke

J'ai eu un problème similaire et, de même, je n'ai pas pu résoudre le problème sous-jacent. Je suppose que le serveur utilise une DLL différente de localhost pour la conversion en json via json.encode.

J'ai posté la question et ma résolution ici ne référence circulaire a été détectée lors de la sérialisation avec Json.Encode

J'ai résolu avec mvchelper.

2
David

Vous pouvez utiliser ce code et ne pas utiliser la fonction Sélectionner une extension pour filtrer votre colonne.

var list = JsonConvert.SerializeObject(Yourmodel,
    Formatting.None,
    new JsonSerializerSettings() {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});
return list;
2
Mohsen Rahimi

J'utilise le correctif, car l'utilisation de Knockout dans les vues MVC5.

En action

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

une fonction

   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
A.Kosecik