Quelle est votre méthode préférée pour envoyer des données complexes via un service Web ?

StackOverflow https://stackoverflow.com/questions/12982

  •  08-06-2019
  •  | 
  •  

Question

Nous sommes en 2008 et je suis toujours déchiré par celui-ci.Je développe donc une méthode Web qui nécessite qu'un type complexe lui soit transmis et renvoyé.Les deux options avec lesquelles je joue sont :

  1. Passer et revenir réel objets métier avec à la fois des données et des comportements.Lorsque wsdl.exe est exécuté, il créera automatiquement des classes proxy contenant uniquement la partie données, et celles-ci seront automatiquement converties vers et depuis mes objets métier réels côté serveur.Du côté client, ils ne pourront utiliser que le type de proxy stupide et devront les mapper à des objets métier réels comme bon leur semble.Un gros inconvénient ici est que si je "posséde" à la fois le côté serveur et le côté client et que je souhaite utiliser le même ensemble d'objets métier réels, je peux rencontrer certains maux de tête avec des conflits de noms, etc.(Puisque les objets réels et les proxys portent le même nom.)

  2. Oubliez d’essayer de transmettre de « vrais » objets métier.Au lieu de cela, créez simplement des objets DataTransfer simples que je mapperai manuellement à mes objets métier réels.De toute façon, ils sont toujours copiés vers de nouveaux objets proxy par wsdl.exe, mais au moins je ne me trompe pas en pensant que les services Web peuvent gérer de manière native des objets contenant une logique métier.

Au fait, est-ce que quelqu'un sait comment dire à wsdl.exe de pas faire une copie de l'objet ?Ne devrions-nous pas simplement lui dire : « Hé, utilise ce type existant ici.Ne le copiez pas!"

Quoi qu'il en soit, j'ai plutôt opté pour le numéro 2 pour l'instant, mais je suis curieux de savoir ce que vous en pensez tous.J'ai le sentiment qu'il y en a chemin de meilleures façons de procéder en général, et je ne suis peut-être même pas totalement précis sur tous mes points, alors faites-moi savoir quelles ont été vos expériences.

Mise à jour:Je viens de découvrir que VS 2008 a la possibilité de réutiliser les types existants lors de l'ajout d'une "référence de service", plutôt que de créer un tout nouveau type identique dans le fichier proxy.Doux.

Était-ce utile?

La solution

il existe également un argument en faveur de la séparation des niveaux : disposer d'un ensemble d'objets sérialisables qui sont transmis vers et depuis le service Web et d'un traducteur pour mapper et convertir entre cet ensemble et les objets métier (qui peuvent avoir des propriétés non adaptées à la transmission du service Web). fil)

C’est l’approche privilégiée par l’usine logicielle de services Web usine de services et signifie que vous pouvez modifier vos objets métier sans rompre l'interface/le contrat du service Web

Autres conseils

Je ferais un hybride.J'utiliserais un objet comme celui-ci

public class TransferObject
{
    public string Type { get; set; }
    public byte[] Data { get; set; }
}

alors j'ai un petit utilitaire sympa qui sérialise un objet puis le compresse.

public static class CompressedSerializer
{
    /// <summary>
    /// Decompresses the specified compressed data.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="compressedData">The compressed data.</param>
    /// <returns></returns>
    public static T Decompress<T>(byte[] compressedData) where T : class
    {
        T result = null;
        using (MemoryStream memory = new MemoryStream())
        {
            memory.Write(compressedData, 0, compressedData.Length);
            memory.Position = 0L;

            using (GZipStream zip= new GZipStream(memory, CompressionMode.Decompress, true))
            {
                zip.Flush();
                var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                result = formatter.Deserialize(zip) as T;
            }
        }

        return result;
    }

    /// <summary>
    /// Compresses the specified data.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="data">The data.</param>
    /// <returns></returns>
    public static byte[] Compress<T>(T data)
    {
        byte[] result = null;
        using (MemoryStream memory = new MemoryStream())
        {
            using (GZipStream zip= new GZipStream(memory, CompressionMode.Compress, true))
            {
                var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                formatter.Serialize(zip, data);
            }

            result = memory.ToArray();
        }

        return result;
    }
}

Ensuite, vous passeriez simplement l'objet de transfert qui aurait le nom du type.Donc tu pourrais faire quelque chose comme ça

[WebMethod]
public void ReceiveData(TransferObject data)
{
    Type originType = Type.GetType(data.Type);
    object item = CompressedSerializer.Decompress<object>(data.Data);
}

à l'heure actuelle, le sérialiseur compressé utilise des génériques pour le rendre fortement typé, mais vous pouvez créer facilement une méthode pour intégrer un objet Type à désérialiser en utilisant originType ci-dessus, tout dépend de votre implémentation.

j'espère que cela vous donne quelques idées.Oh, et pour répondre à votre autre question, wsdl.exe ne prend pas en charge la réutilisation des types, contrairement à WCF.

Darren a écrit:Je ferais un hybride.J'utiliserais un objet comme celui-ci...

Idée intéressante...passer une version sérialisée de l'objet au lieu de l'objet (wsdl-ed) lui-même.D'une certaine manière, j'aime son élégance, mais d'une autre manière, cela semble aller à l'encontre de l'objectif d'exposer votre service Web à des tiers ou partenaires potentiels ou autre.Comment sauraient-ils quoi transmettre ?Devraient-ils s’appuyer uniquement sur la documentation ?Il perd également un peu de l'aspect "client hétérogène", puisque la sérialisation est très spécifique au .Net.Je ne veux pas être critique, je me demande simplement si ce que vous proposez est également destiné à ce type de cas d'utilisation.Cependant, je ne vois rien de mal à l'utiliser dans un environnement fermé.

Je devrais me pencher sur WCF...Je l'ai évité, mais il est peut-être temps.

oh, bien sûr, je ne le fais que lorsque je suis le consommateur du service Web ou si vous avez une sorte de contrôleur à qui ils demandent un objet et que vous gérez ensuite la sérialisation et l'envoi plutôt que de consommer directement le service Web.Mais en réalité, s'ils consomment directement le service Web, ils n'auraient pas besoin ou n'auraient pas nécessairement l'assembly qui contiendrait le type en premier lieu, et devraient utiliser les objets générés par wsdl.

Et oui, ce que je propose est très spécifique à .NET car je n'aime pas utiliser autre chose.La seule autre fois où j'ai consommé des services Web en dehors de .net, c'était en javascript, mais maintenant je n'utilise que des réponses json au lieu des réponses de service Web XML :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top