9
votes

Comment puis-je exclure certaines propriétés publiques d'être sérialisées dans un JSONRESULT?

J'ai une vue personnaliséeModel qui est sérialisée à l'aide d'un JSONRESULT. Le point de vue a des propriétés qui doivent être publiques, tout en même temps, ces propriétés ne doivent pas être visibles dans la sortie JSON résultante.

J'ai déjà essayé d'utiliser l'attribut [non-séralisé], mais cela ne semble avoir aucun effet.

Y a-t-il un moyen simple de faire cela? Ou devrais-je devoir coder mon propre type de résultat (auquel cas je ne me dérangerai probablement pas)?


1 commentaires

La majeure partie de la réponse utilise l'attribut ou le greau. Je veux juste simplement exclure certaines des propriétés publiques lors de la sérialisation. Je cherche Json.net comme suggéré par @charlino mais n'a pas trouvé la voie. C'est le cas: j'ai Error Propriété qui ne sera définie que lorsque l'erreur se produit. Le côté client vérifie ce premier choix à afficher un message autrement affichera le reste de la propriété de modèle. Lorsqu'il n'y a pas d'erreur, il rendra {..., "erreur": null} !


6 Réponses :


0
votes

Pas exactement la réponse que vous recherchez, mais vous pouvez tricher json () code> à l'aide du code suivant et des classes anonymes:

MyModel model = ...;
return Json(new MyModel {model.Prop1, model.Prop2});


5 commentaires

Je sais que je peux utiliser des types anonymes à la place. Mais cela fait tester une unité le résultat beaucoup plus difficile. Cela signifie que je devais devoir analyser le résultat sérialisé ou utiliser la réflexion.


Le test de l'unité JSONRESULTS est difficile à commencer. Comment allait-tu cela auparavant? Il ne semble pas que vous puissiez récupérer le modèle sous-jacent qui a conduit le JSONRESULT.


Ce n'est pas un problème du tout. La propriété JSONRESULT.DATA contient l'objet qui doit être sérialisé. Puisque j'utilise une vue personnaliséeModel au lieu d'un type d'objet anonyme, je peux simplement saisir cet objet et tester ses propriétés.


Eh bien, bien que douloureux, vous pouvez toujours créer une nouvelle version de votre classe et simplement copier ces propriétés que vous souhaitez. J'ai édité mon message avec cette approche.


@Adrian: Merci, je ne savais pas que les données ont été renvoyées à l'objet sérialisé.



0
votes

Vous pouvez créer une classe wrapper qui expose uniquement les propriétés que vous souhaitez dans le JSONRESULT. Dans l'exemple ci-dessous, la vache a 2 propriétés - "jambe" et "moo". Supposons que vous souhaitiez seulement exposer la "jambe" comme une propriété. Ensuite,

Dim CW comme Cowwrapper = Nouveau CowWrapper (C) P>

retourne une classe d'emballage qui n'expose que "la jambe". Ceci est également utile pour des choses telles que DataGridView si vous souhaitez uniquement afficher un sous-ensemble des propriétés. P>

Vache de classe publique P>

Jambe de propriété en lecture publique () sous forme de chaîne p> xxx pré>

Propriété d'extrémité P>

Propriété réadonnaire publique MOO () en tant que chaîne p> xxx pré>

propriété finale p>

Classe d'extrémité p>

Cowwrapper de classe publique P>

   get

      return m_cow.Leg()

   end get


4 commentaires

Cela fonctionne, mais au prix de devoir copier assez de propriétés, ce n'est donc pas vraiment ce que je cherchais.


À quel coût? La programmation? Il devrait être simple d'écrire un utilitaire simple pour construire ces classes compte tenu du fichier de classe comme entrée ou d'écrire une classe pouvant construire des propriétés de manière dynamique à l'aide d'introspection. Durée? Le coût d'une référence supplémentaire est négligeable.


Je n'ai pas réalisé que vous voulez dire construire de tels types au moment de l'exécution par réflexion. Cela couvrirait bien sûr tous mes types de visiteurs personnalisés sans codage supplémentaire. Une approche valide mais elle est trop compliquée par rapport à l'utilisation d'un outil prêt à l'emploi (nommément JSON.NET)


Super! (Qu'il y a un outil prêt à l'emploi). J'aurais dû écrire "Cela devrait être possible" non "Cela devrait être simple" .. Comme je ne sais pas beaucoup l'introspection moi-même. J'ai utilisé les classes de wrapper (codé dur, sans utiliser l'introspection) lors du remplissage d'un DataGridView avec une classe LINQ vers SQL. Souvent, je ne veux pas afficher tous les champs de la table, de sorte que l'emballage s'occupe de cela.



1
votes

Étendez le JavascriptConverter < / Code> classe pour ne pas inclure les propriétés avec le non-sérialiszeatribute . Ensuite, vous pouvez créer un ActionResult qui utilise votre JavaScriptConverter pour sérialiser l'objet.

Ceci crée une classe solide et testable sans avoir à (re) générer des classes d'emballage ou en utilisant des objets anonymes.


1 commentaires

C'est l'approche qui me vint également à l'esprit. Cela fonctionne certainement, mais comme il s'agit seulement d'économiser quelques octets de chaque demande JSON, j'espérais qu'il y a quelque chose de plus simple. Bonne approche, mais simplement trop de travail par rapport aux avantages dans mon cas.



2
votes

Jetez un coup d'œil à JSON.net de James Newton-King. Ça va faire ce que vous recherchez.


1 commentaires

Parfait! Comme il s'avère, James a également écrit un type JSONRESULT correspondant: james.newtonking.com/archive/2008/10/16/...



27
votes

Vous pouvez mettre un attribut [scriptingignore] sur les membres qui ne devraient pas être sérialisés. Voir ScriptIntIntRibute Classe dans MSDN pour un exemple.


2 commentaires

Pour d'autres personnes, l'espace de noms complet de l'attribut est [System.web.script.Sériorialisation.scriptignore]


On dirait que scriptonignore lorsque vous utilisez l'utilisation du JSON MVC Retour habituel () --- ALORS JSONIGNORE Si vous utilisez json.net



2
votes

Créez simplement une interface pour revenir au lieu d'une classe.

{
    'MyPublicProperty': ''
}


2 commentaires

Merci pour votre réponse. Ce n'est pas une mauvaise méthode, mais il existe également un moyen plus automatisé de garantir que vos classes latérales client soient toujours synchronisées avec le côté serveur: utilisez TypeScript pour le code côté client et génèrent de manière programmable vos images de vue côté client à partir d'objets côté serveur. pendant la compilation. Voir type.litesolutions.net Pour plus de détails.


Cette approche fonctionnerait-elle avec une liste étant sérialisée? Je ne peux pas le faire travailler ...