J'ai expérimenté la création d'un site Web qui exploite MVC avec JSON pour ma couche de présentation et le cadre d'entité pour le modèle de données / base de données. Mon problème entre en jeu avec la sérialisation de mes objets Model en JSON.
J'utilise la méthode code first pour créer ma base de données. Lors de la première méthode de code, une relation un à plusieurs (parent / enfant) nécessite que l'enfant ait une référence au parent. (Exemple de code mon être une faute de frappe, mais vous obtenez l'image)
class parent
{
public List<child> Children{get;set;}
public int Id{get;set;}
}
class child
{
public int ParentId{get;set;}
[ForeignKey("ParentId")]
public parent MyParent{get;set;}
public string name{get;set;}
}
Lors du retour d'un objet "parent" via un JsonResult, une erreur de référence circulaire est levée car "enfant" a une propriété de classe parent.
J'ai essayé l'attribut ScriptIgnore mais je perds la possibilité de regarder les objets enfants. J'aurai besoin d'afficher des informations dans une vue enfant parent à un moment donné.
J'ai essayé de créer des classes de base pour les parents et les enfants qui n'ont pas de référence circulaire. Malheureusement, lorsque j'essaie d'envoyer les basesParent et baseChild, celles-ci sont lues par l'analyseur JSON comme leurs classes dérivées (je suis presque sûr que ce concept m'échappe).
Base.baseParent basep = (Base.baseParent)parent;
return Json(basep, JsonRequestBehavior.AllowGet);
La seule solution que j'ai trouvée est de créer des modèles "View". Je crée des versions simples des modèles de base de données qui n'incluent pas la référence à la classe parente. Ces modèles de vue ont chacun une méthode pour renvoyer la version de la base de données et un constructeur qui prend le modèle de base de données comme paramètre (viewmodel.name = databasemodel.name). Cette méthode semble forcée bien qu'elle fonctionne.
REMARQUE: je poste ici parce que je pense que cette discussion mérite d'être discutée. Je pourrais tirer parti d'un modèle de conception différent pour surmonter ce problème ou cela pourrait être aussi simple que d'utiliser un attribut différent sur mon modèle. Dans ma recherche, je n'ai pas vu de bonne méthode pour surmonter ce problème.
Mon objectif final serait d'avoir une belle application MVC qui exploite fortement JSON pour communiquer avec le serveur et afficher les données. Tout en maintenant un modèle cohérent à travers les couches (ou du mieux que je peux trouver).
la source
Une alternative plus simple à la tentative de sérialisation des objets serait de désactiver la sérialisation des objets parent / enfant. Au lieu de cela, vous pouvez effectuer un appel distinct pour récupérer les objets parent / enfant associés au fur et à mesure de vos besoins. Ce n'est peut-être pas idéal pour votre application, mais c'est une option.
Pour ce faire, vous pouvez configurer un DataContractSerializer et définir la propriété DataContractSerializer.PreserveObjectReferences sur «false» dans le constructeur de votre classe de modèle de données. Cela spécifie que les références d'objet ne doivent pas être conservées lors de la sérialisation des réponses HTTP.
Exemples:
Format Json:
Format XML:
Cela signifie que si vous récupérez un élément dont les objets enfants sont référencés, les objets enfants ne seront pas sérialisés.
Voir aussi la classe DataContractsSerializer .
la source
Sérialiseur JSON qui traite des références circulaires
Voici un exemple de Jackson personnalisé
JSONSerializer
qui traite des références circulaires en sérialisant la première occurrence et en stockant un *reference
à la première occurrence sur toutes les occurrences suivantes.Gérer les références circulaires lors de la sérialisation d'objets avec Jackson
Extrait partiel pertinent de l'article ci-dessus:
la source
L'envoi du strict minimum de données est la seule bonne réponse. Lorsque vous envoyez des données à partir de la base de données, il n'est généralement pas judicieux d'envoyer chaque colonne avec toutes les associations. Les consommateurs ne devraient pas avoir à gérer les associations et les structures de bases de données, c'est-à-dire les bases de données. Non seulement cela permettra d'économiser de la bande passante, mais il est également beaucoup plus facile à entretenir, à lire et à consommer. Recherchez les données, puis modélisez-les pour ce dont vous avez réellement besoin pour envoyer l'eq. le strict minimum.
la source
.Include(x => x.TableName )
ne pas renvoyer de relations (de la table principale à la table dépendante), ou renvoyer uniquement une ligne de données, CORRIGER ICI:/programming/43127957/include-not-working-in-net-core-returns-one-parent
En outre, dans Startup.cs assurez-vous que vous avez ceci en haut:
la source