|
| 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 sCRC est chaine sur 8
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 
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 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  |
| |
| |
| | | |
|
| | |
| |
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  |
| |
| |
| | | |
|
| | |
| |
Registered member 94 messages |
|
| Posted on March, 31 2021 - 12:43 AM |
Merci pour tous*** tes conseils  |
| |
| |
| | | |
|
| | | | |
| | |
|