65 votes

Comment ne pas sérialiser la propriété __type des objets JSON

Chaque objet que je renvoie d'une WebMethod d'un ScriptService est enveloppé dans un objet JSON avec les données dans une propriété nommée d. C'est bon. Mais je ne veux pas que la propriété additionnelle __type soit renvoyée au client, car je fais un traitement manuel avec jQuery.

Est-ce possible?

40voto

J'ai constaté que si je fais en sorte que le constructeur par défaut de ma classe que mon webmethod retourne autre chose que public, il ne sérialisera pas la portion __type:ClassName.

Vous voudrez peut-être déclarer votre constructeur par défaut protected internal ClassName() { }

25voto

Stephen Kennedy Points 1458

La solution de John n'a pas fonctionné pour moi car le type que je retourne est dans une DLL séparée. J'ai un contrôle total sur cette DLL mais je ne peux pas construire mon type de retour si le constructeur est interne.

Je me suis demandé si le type de retour étant un type public dans une bibliothèque pourrait même être la cause - j'ai beaucoup fait d'Ajax et je n'ai jamais vu ça auparavant.

Tests rapides:

  • J'ai temporairement déplacé la déclaration du type de retour dans App_Code. J'obtiens toujours __type sérialisé.

  • Même chose et appliqué le constructeur protégé interne selon JM. Cela a fonctionné (donc il obtient un vote).

Étrangement, je n'obtiens pas __type avec un type de retour générique:

[WebMethod]
public static WebMethodReturn> GetAccountCredits()

Cependant, la solution pour moi a été de laisser mon type de retour dans la DLL mais de changer le type de retour de WebMethod en object, c'est-à-dire

[WebMethod]
public static object ApplyCredits(int addonid, int[] vehicleIds) 

au lieu de

[WebMethod]
public static WebMethodReturn ApplyCredits(int addonid, int[] vehicleIds)

16voto

Jonathan Sayce Points 1942

J'ai essayé certaines de ces suggestions avec un service .NET 4 WCF, et elles ne semblent pas fonctionner - la réponse JSON inclut toujours __type.

La façon la plus simple que j'ai trouvée pour supprimer le type-hinting est de changer le comportement du point de terminaison de enableWebScript à webHttp.

Le comportement par défaut enableWebScript est nécessaire si vous utilisez un client ASP.NET AJAX, mais si vous manipulez le JSON avec JavaScript ou jQuery, alors le comportement webHttp est probablement un meilleur choix.

12voto

Brett Veenstra Points 10238

Si vous utilisez ServiceStack.Text JSON Serializer vous avez juste besoin de :

JsConfig.ExcludeTypeInfo = true;

Cette fonctionnalité a été automatiquement ajoutée dans v2.28, mais le code ci-dessus exclut cela de la sérialisation. Vous pouvez également changer ce comportement en Type avec :

JsConfig.ExcludeTypeInfo = true;

4voto

ClearCloud8 Points 1237

Je pense avoir identifié la cause racine de l'apparition mystérieuse de "__type" !

Voici un exemple où vous pouvez recréer le problème.

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class Test : System.Web.Services.WebService
{
    public class Cat
    {
        public String HairType { get; set; }
        public int MeowVolume { get; set; }
        public String Name { get; set; }
    }

    [WebMethod]
    public String MyMethodA(Cat cat)
    {
        return "return value does not matter";
    }

    [WebMethod]
    public Cat MyMethodB(String someParam)
    {
        return new Cat() { HairType = "Court", MeowVolume = 13, Name = "Felix the Cat" };
    }
}

Voici la partie clé !

Simplement parce que MyMethodA() existe dans ce même fichier .asmx et prend la classe Cat en paramètre.... le __type sera ajouté au JSON retourné lors de l'appel de l'autre méthode : MyMethodB().

Même s'ils sont des méthodes différentes !!

Ma théorie est la suivante :

  1. Lorsque vous écrivez des services web de cette manière, le code de Microsoft connecte automatiquement le comportement de sérialisation/désérialisation JSON pour vous car vous avez utilisé les attributs corrects, comme [WebMethod] et [ScriptService].
  2. Lorsque ce code magique automatique de Microsoft s'exécute, il trouve une méthode qui prend la classe Cat en paramètre.
  3. Il se dit... oh... ok.... bon puisque je vais recevoir un objet Cat depuis JSON.... donc... si je retourne un jour un objet Cat en JSON depuis n'importe quelle méthode de la classe de service web actuelle... je lui donnerai une propriété __type pour qu'il soit facile à identifier plus tard lors de la désérialisation en C#.
  4. Nyah-hahahaha...

Remarque Importante à Retenir

Vous pouvez éviter que la propriété __type n'apparaisse dans votre JSON généré en évitant de prendre la classe en question (Cat dans mon cas) en tant que paramètre pour l'un de vos WebMethods dans votre service web. Ainsi, dans le code ci-dessus, essayez simplement de modifier MyMethodA() pour supprimer le paramètre Cat. Cela évite la génération de la propriété __type.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X