Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C#] Meilleur approche pour l'envoi de requête web

    20 août 2019 à 1:04:05

    Bonjour, je suis actuellement assez embêté car cela fait plusieurs jours que je tente de résoudre un problème. Tout d'abord voilà le contexte :

    J'ai un serveur web ( php ) capable de recevoir des requêtes POST et de les traiter.

    J'aimerais savoir quel est selon vous, programmeurs expérimentés, la meilleur approche pour envoyer des requêtes depuis un programme C# vers mon serveur web.

    Chaque requête est constitué de 2 éléments :

        * query = le nom de la requête par exemple 'user:login' pour se connecter

        * properties = toutes les propriétés/données de la requêtes. Pour un user:login on retrouvera par exemple un username et un password.

    Côté C# je pense que le mieux est de stocker toutes ces données dans un Dictionary<string, object> qui sous JSON ressemblerait à ça par exemple : 

    {
      "query": "user:login",
      "properties": {
        "username": "nitorax",
        "password": "secret :)"
      }
    }

    On remarque que properties s'apparente également à un Dictionary et c'est très important de le remarquer car certaines requêtes pourraient nécessiter des Dictionaries imbriqués les un dans les autres.

    Pour en revenir à la meilleur approche pour envoyer ces données, selon moi :

       * Je devrais d'abord encoder avec Base64 chaque données une par une en parcourant chaque éléments contenu dans les Dictionaries.

       * Ensuite je sérialise le tout avec JSON

        * Enfin j'encode à nouveau le tout avec Base64

       * Et on fini par envoyer en requête POST au serveur web qui lui s'occupe de faire les opérations inverse

        * (Bien sûr on rajoutera un cryptage par la suite pour sécuriser les données sensibles comme les mots de passes)

    Selon moi c'est la meilleur approche pour éviter tout problème avec les données et m'assurer qu'aucune donnée soit corrompue.

    Si vous êtes d'accord avec cette approche, pourriez vous m'indiquer comment encoder en Base64 un dictionary<string, object> pouvant contenir en valeur à la fois des List<object>, des string, des bool, d'autres Dictionary<string, object> et des int. ( je sais les int et bool n'ont pas besoin d'être encodés mais c'est pour insister sur le fait que le Dictionary peut contenir de tout ).

    Voici un des bouts de codes que j'ai essayé mais qui malheureusement pour la centième fois ne marche toujours pas ...

     Base64Utils.cs (Mon soucis se trouve ici)

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ToolBox.utils
    {
        public class Base64Utils
        {
    
            //PERMET DE TRANSFORMER UN OBJECT EN DICTIONARY VOULU
            private static IEnumerable<DictionaryEntry> CastDict(IDictionary dictionary)
            {
                foreach (DictionaryEntry entry in dictionary)
                {
                    yield return entry;
                }
            }
    
            //ENCODE N'IMPORTE QUEL OBJECT EN CHERCHANT SON TYPE
            public static T Base64Encode<T>(T unknow_entry)
            {
                
                if(typeof(T) == typeof(string)) //DE TYPE STRING DONC ON ENCODE DIRECTEMENT
                {
                    Console.WriteLine("I'm a string");
                    string know_entry = unknow_entry.ToString();
                    if (know_entry.Length % 4 == 2)
                    {
                        know_entry += "==";
                    }
                    else if (know_entry.Length % 4 == 3)
                    {
                        know_entry += "=";
                    }
                    //Console.WriteLine(str);
                    if (!String.IsNullOrEmpty(know_entry))
                        return (T)(object) Convert.ToBase64String(Encoding.UTF8.GetBytes(know_entry));
                    return default(T);
    
                }else if(typeof(T).IsGenericType && (typeof(T).GenericTypeArguments.Length == 1)) //DE TYPE ARRAY ( car 1 seul type généric )
                {
                    Console.WriteLine("I'm a list beach !");
                    List<object> know_entry = new List<object>();
    
                    foreach (var tempo in (IList) unknow_entry)
                    {
                        
                        know_entry.Add(Base64Encode(tempo));  //ON RAPPELLE LA METHODE D'ENCODAGE SUR CHAQUES ELEMENTS DU TABLEAU
                    }
    
                    IList list = know_entry;
                    know_entry = list.Cast<object>().ToList();
    
                    return (T) (object) know_entry;
                }
                else if (typeof(T).IsGenericType && (typeof(T).GenericTypeArguments.Length == 2))
                {
                    Console.WriteLine("I'm a dictionary sir :)");
                    IDictionary dictionary = (IDictionary) unknow_entry;
                    Dictionary<string, object> know_entry = CastDict(dictionary).ToDictionary(entry => (string)entry.Key, entry => (entry.Value));
    
                    foreach (var tempo in know_entry)
                    {
    
                        know_entry[tempo.Key] = (Base64Encode(tempo.Value));   //ON RAPPELLE LA METHODE D'ENCODAGE SUR CHAQUES ELEMENTS DU DICTIONARY
                    }
    
                    return (T)(object)know_entry;
                }
                else   //LA ON A QUELQUECHOSE INCONNU DONC ON SAIT PAS QUOI FAIRE ALORS ON FAIT RIEN ... MALHEUREUSEMENT CERTAINS TYPE LIST OU DICTIONARY ARRIVENT ICI CE QUI POSE UN GROS PROBLEME ...
                {
                    Console.WriteLine("I'm a ... idk : " + typeof(T));
                    return default(T);
                }
            }
    
    
            public static T Base64Decode<T>(T unknow_entry)
            {
                if (typeof(T) == typeof(string))
                {
                    string know_entry = unknow_entry.ToString();
                    if (know_entry.Length % 4 == 2)
                    {
                        know_entry += "==";
                    }
                    else if (know_entry.Length % 4 == 3)
                    {
                        know_entry += "=";
                    }
                    //Console.WriteLine(str);
                    if (!String.IsNullOrEmpty(know_entry))
                        return (T)(object) Encoding.UTF8.GetString(Convert.FromBase64String(know_entry));
                    return default(T);
                }
                else if (typeof(T) == typeof(IList<>))
                {
                    List<object> know_entry = new List<object>();
                    foreach (var tempo in (IList)unknow_entry)
                    {
    
                        know_entry.Add(Base64Decode(tempo));
                    }
    
                    IList list = know_entry;
                    know_entry = list.Cast<object>().ToList();
    
                    return (T)(object)know_entry;
                }
                else if (typeof(T) == typeof(IDictionary<,>))
                {
                    IDictionary dictionary = (IDictionary)unknow_entry;
                    Dictionary<string, object> know_entry = CastDict(dictionary).ToDictionary(entry => (string)entry.Key, entry => (entry.Value));
    
                    foreach (var tempo in know_entry)
                    {
    
                        know_entry[tempo.Key] = (Base64Decode(tempo.Value));
                    }
    
                    return (T)(object)know_entry;
                }
                else
                {
                    return default(T);
                }
            }
    
        }
    }
    

    JSonUtils.cs

    namespace ToolBox.utils
    {
        class JsonUtils
        {
            public static bool IsDebug { get; set; } = false;
    
    
            public static String ToJson<T>(T t)
            {
                return JsonConvert.SerializeObject(t, Formatting.Indented);
            }
    
            public static JSON_TYPE TryGetFromJson(string json, out List<object> list, out Dictionary<string, object> dictionary)
            {
                list = null;
                dictionary = null;
    
                if (json.StartsWith("["))
                {
                    list = (JsonConvert.DeserializeObject<List<object>>(json));
                    return JSON_TYPE.ARRAY;
                }
                else if (json.StartsWith("{"))
                {
                   dictionary = (JsonConvert.DeserializeObject<Dictionary<string, object>>(json));
                    return JSON_TYPE.OBJECT;
                }
                else
                {
                    return JSON_TYPE.NULL;
                }
            }
    
            public enum JSON_TYPE { ARRAY, OBJECT, NULL }
    
        }
    
    }

    Query.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ToolBox.utils
    {
        internal class Query
        {
    
            public string query;
            public Dictionary<string, object> properties;
            public string uuid;
            public string feedback_code;
            public string feedback_message;
            public Dictionary<string, object> feedback_properties;
    
            //CONSTRUCTEURS
            public Query(string query)
            {
                this.query = query;
            }
            public Query(string query, Dictionary<string, object> properties) : this(query)
            {
                this.properties = properties;
            }
            public Query(string query, Dictionary<string, object> properties, string uuid) : this(query, properties)
            {
                this.uuid = uuid;
            }
            public Query(string uuid, string feedback_code, string feedback_message) : this(uuid)
            {
                this.feedback_code = feedback_code;
                this.feedback_message = feedback_message;
            }
            public Query(string uuid, string feedback_code, string feedback_message, Dictionary<string, object> feedback_properties) : this(uuid, feedback_code, feedback_message)
            {
                this.feedback_properties = feedback_properties;
            }
            public Query(string query, Dictionary<string, object> properties, string uuid, string feedback_code, string feedback_message, Dictionary<string, object> feedback_properties) : this(query, properties, uuid)
            {
                this.feedback_code = feedback_code;
                this.feedback_message = feedback_message;
                this.feedback_properties = feedback_properties;
            }
    
            
            //GESTION PROPERTIES
            public bool TryGetProperty(string key, out object value)
            {
                return properties.TryGetValue(key, out value);
            }
    
            public void SetProperty(string key, object value)
            {
                properties[key] = value;
            }
    
            public bool DeleteProperty(string key)
            {
                return properties.Remove(key);
            }
    
            public void ClearProperties()
            {
                properties.Clear();
            }
    
            //MISE EN PAQUET DE TOUTES LES REQUÊTES
            public static string PackageQueriesToSend(List<Query> queries) // CETTE METHODE TRANSFORME CHAQUE OBJET QUERY DE LA LISTE EN DICTIONARY, PUIS ENCODE LE TOUT PUIS SERIALISE ( PUIS SERA RAJOUTER LA METHODE POUR ENCODER LE JSON STRING LORSQUE L'ENCODAGE ELEMENT PAR ELEMENT SERA FONCTIONNEL )
            {
                List<object> q_builder = new List<object>();
                foreach(var query in queries)
                {
                    q_builder.Add(new Dictionary<string, object>
                    {
                        ["q"] = query.query,
                        ["u"] = query.uuid, // UUID EST INUTILE POUR LE MOMENT NE PAS S'EN PREOCCUPER
                        ["p"] = query.properties
                    });
                    
                }
                return JsonUtils.ToJson(Base64Utils.Base64Encode(q_builder));
            }
    
        }
    }
    


    Voilà, je vous laisse le soin si vous le désirez de copier le code et le compiler pour le tester ou bien de tenter de résoudre directement mon problème si vous voyez d'où il vient. 

    J'aimerais trouver une façon propre d'encoder en BASE64 et qui puisse fonctionner malheureusement pour moi mes recherches n'ont pas portées leurs fruits puisque je me retrouve avec un code vraiment sale qui en plus ne fonctionne pas ...

    Je vous suis reconnaissant de tenter de résoudre mon problème, toute petite aide aussi insignifiante soit elle m'aidera beaucoup.





    • Partager sur Facebook
    • Partager sur Twitter
      30 août 2019 à 13:57:54

      >Si vous êtes d'accord avec cette approche

      Non.

      Plutôt que de réinventer une roue carrée, utilisez des outils qui existent pas palette entière et qui ont été conçu par des personnes bien plus expérimentées que nous.

      Des Framework de requêtes Web, c'est pas ça qui manque : REST, WebMethod SOAP, etc...

      Choisissez en un compatible avec votre infrastructure Serveur. La partie client/NET, vous trouverez toujours les outils pour vous en servir facilement et pas réinventer une roue carrée.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

      [C#] Meilleur approche pour l'envoi de requête web

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown