PC SOFT

PROFESSIONAL NEWSGROUPS
WINDEVWEBDEV and WINDEV Mobile

Home → WINDEV 2025 → Désérialiser un Tableau de Variants
Désérialiser un Tableau de Variants
Started by DREAM-TECH (BE), Mar., 24 2021 7:17 PM - 8 replies
Registered member
94 messages
Posted on March, 24 2021 - 7:17 PM
Bonjour,

Je sérialise un tableau de variables de type Variant que je place dans un JSON et lorsque j'essaye de désérialiser j'ai l'erreur suivante : L'élément JSON n'est pas un tableau.

Mon code pour sérialiser :

vDevice is Variant
arrResult is array of Variant
FOR EACH Device WITH FKUser = 1
vDevice.sName = Device.sName
vDevice.sModel = Device.sModel
Add(arrResult,vDevice)
END

bufResult is Buffer
Serialize(arrResult, bufResult, psdJSON)
RESULT bufResult


Mon code pour désérialiser :

myResponse is httpResponse = RESTSend(myRequest)

arrResult is array of Variant
Deserialize(arrResult,myResponse..Content,psdJSON)

FOR EACH vElement IN arrResult
Trace(UTF8ToString(vElement.sName+" "+vElement.sModel)
END


Ceci est le contenu de ma variable myResponse..Content (à l'aide de l'outil en ligne http://json2table.com/ il arrive à interpréter le contenu de ma variable myResponse..Content sans problème) :







J'ai trouvé une autre solution en manipulant directement une variable de type JSON pour créer mes records mais je suis curieux de comprendre pourquoi ça ne fonctionne pas comme ça ?

J'ai besoin de vos lumières :)

Merci.
Registered member
4,334 messages
Posted on March, 25 2021 - 7:00 AM
Bonjour,
Pourquoi passer par un tableau de variants et pas un tableau de classes ?
Cela évitera déjà une boucle qui peut être très gourmande en mémoire.
Dans un deuxième temps il est fort possible que le contenu reçu soit tronqué ou "parasité". L'ajout d'un CRC dans les transmission de données n'est jamais superflu.

--
Il y a peut être plus simple, mais, ça tourne
Registered member
94 messages
Posted on March, 27 2021 - 4:21 PM
Bonjour,

Merci @Voroltinquo :)

Je t'avoue pas très envie de passer par une classe, j'ai structuré mes classes uniquement pour ma couche domaine,

En plus, j'ai l'impression que ça va donner le même résultat à partir du moment où je mets dans un JSON un tableau de structures/variants/objets.

J'ai testé avec un tableau de structures et de variants, c'est le même problème, je testerai également avec avec un tableau d'objets.

Merci.
Registered member
4,334 messages
Posted on March, 28 2021 - 10:34 AM
Sérialisation :
tabDonnéesDevice est tableau de MDevice //MDevice : classe mappée issue de la table ou de la requête à sérialiser
sCRC est chaine sur 8 // CRC du buffer résultant de la sérialisation

FichierVersTableau(tabDonnéesProduit,Device)

Sérialise(tabDonnéesDevice,gbufResSérial,psdJSON)
sCRC=EntierVersHexa(sCalculeCrc16(gbufResSérial))

RENVOYER gbufResSérial+sCRC


Désérialisation :
Procedure LireDonnées (httpMaRequête est hrrpRequête)

httpMonResultat est un httpRéponse
bufDonnéesUtiles est Buffer
nTailleBuf est entier

httpMonResultat=HTTPEnvoie(httpMaRequête)

TANTQUE PAS VerifCRC(httpMonResultat.Contenu)
httpMonResultat=HTTPEnvoie(httpMaRequête)
FIN
nTailleBuf=Taille(httpMonResultat.Contenu)
bufDonnéesUtiles=httpMonResultat.Contenu
bufDonnéesUtiles=bufDonnéesUtiles[À nTailleBuf-8]
Désérialise(gtabDonnéesReçues,bufDonnéesUtiles,psdJSON)


Procedure VerifCRC(bufAVerifier est Buffer)
sCRC est une chaine sur 8
sCRCReçu est une chaine sur 8
nTailleBuff est un entier

nTailleBuff=Taille(bufAVerifier)
sCRCReçu=bufAVerifier[nTailleBuff-7 À ]
bufAVerifier=bufAVerifier[À nTailleBuff-8]
sCRC=EntierVersHexa(sCalculeCrc16(bufAVerifier))

SI sCRC=sCRCReçu ALORS
RENVOYER Vrai
SINON
RENVOYER Faux
FIN


Ces codes fonctionnent

--
Il y a peut être plus simple, mais, ça tourne
Registered member
94 messages
Posted on March, 30 2021 - 2:06 AM
Hello,

Merci @Voroltinquo :)

Finalement j'ai reçu la réponse du support de PC Soft, la désérialisation de JSON ne permet pas l’utilisation de variable de type variant (c'était justement mon point de curiosité).

Par contre, j'ai cru avoir le même problème avec les structures mais ce n'est pas le cas, j'ai vérifié mon code et maintenant ça fonctionne (je n'ai sais pas si entre temps j'ai rajouté quelque chose qui a fait que ça fonctionne ou tout simplement parce que j'ai mis les updates de la version 26, bref :merci:

myResponse is httpResponse = RESTSend(myRequest)

strDevice is structure
sName is string
sModel is string
END

arrResult is array of strDevice
Deserialize(arrResult,myResponse..Content,psdJSON)

FOR EACH stDevice IN arrResult
Trace(stDevice.sName+" "+stDevice.sName)
END


J'aurai bien voulu utiliser des variants pour des transferts de données (genre un petit tableau de 2-3 infos) sans pour autant créer une structure/classe (typée) coté client et coté serveur (l'avantage justement du type variant), mais c'est rien, ce n'est pas bloquant.

Par contre, il y a un point très intéressant dans ton exemple @Voroltinquo, c'est le fait que tu rajoute un contrôle CRC16 pour vérifier si tu as reçu l'entièreté de données (j'utilise le même contrôle mais pour autre chose) et justement je voulais comprendre un peu plus comment fonctionne RESTSend et HttpResponse. En Java je faisais comme toi un control de données (checksum) grâce à une boucle et surtout pour chaque nouvelle connexion je déclenche un nouveau thread (pour chaque client un thread) et une boucle dans chaque thread jusqu'à la fin de réception de données de ce client.

Mais en Windev je n'ai pas encore expérimenté plusieurs connexions simultanées (via des webservices REST et donc RESTSend et httpResponse) et je n'ai pas vu des threads dans les exemples lorsqu'on utilise httpResponse = RESTSend et pourtant ça me semble indispensable ? je me trompe ?

Exemple concret :

Avec mon webservice j'utilise un certificat et des signatures :

sSignature is string = WebserviceReadHTTPHeader("SignatureWS")

Comment le webservice va déterminer qu'il s'agit de la signature du client X et pas celle du client Y ?

Idem pour les paramètres : Si je reçois plusieurs appels à la même API mais avec des paramètres différents (en fonction de l'appel) :

sParameter = WebserviceParameter("sClient")

Plusieurs clients font appel à la même API (point d'entrée) simultanément comment le webservice gère ça ?

Je voulais créer un autre topic pour ce point mais je profite de ton expérience @Voroltinquo (avec 2125 messages :o hhhh).

En gros, dois-je gérer les réponses REST dans des threads comme avec les autres langages ?

Ou, la magie de Windev fait qu'il y a quelque chose d'automatique derrière ?

Merci d'avance :merci:
Registered member
4,334 messages
Posted on March, 30 2021 - 6:21 AM
Dans ce cas, tu ne fais qu'interroger la base (méthode GET.) Tout se passe comme une requête C/S, le serveur s'occupe de tout. Par contre avec une méthode POST ou PUT, comme en C/S, il peut être utile de bloquer les tables sujettes à modification le temps que le boulot se fasse.
En ce qui concerne la signature du client, tu dois mettre en place un système similaire au login.
Si la paire Client-Signature existe, la requête peut être exécutée.

--
Il y a peut être plus simple, mais, ça tourne
Registered member
4,334 messages
Posted on March, 30 2021 - 6:24 AM
En ce qui concerne l'utilisation des classes, rien ne t'empêche d'utiliser un composant qui recense le classes utilisées.

--
Il y a peut être plus simple, mais, ça tourne
Registered member
94 messages
Posted on March, 31 2021 - 12:40 AM
Hello,

Un grand merci @Voroltinquo pour toutes tes conseils :merci:
Registered member
94 messages
Posted on March, 31 2021 - 12:43 AM
Merci pour tous*** tes conseils :merci: