¿Cuál es su método preferido para enviar datos complejos a través de un servicio web?

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

  •  08-06-2019
  •  | 
  •  

Pregunta

Estamos en 2008 y todavía estoy dividido sobre esto.Así que estoy desarrollando un método web que necesita que se le pase un tipo complejo y se le devuelva.Las dos opciones con las que estoy jugando son:

  1. Pasar y regresar actual objetos de negocio con datos y comportamiento.Cuando se ejecuta wsdl.exe, creará automáticamente clases de proxy que contienen solo la porción de datos, y éstas se convertirán automáticamente hacia y desde mis objetos comerciales reales en el lado del servidor.En el lado del cliente, solo podrán utilizar el tipo de proxy tonto y tendrán que asignarlos a algunos objetos comerciales reales como mejor les parezca.Un gran inconveniente aquí es que si "poseo" tanto el lado del servidor como el del cliente, y quiero usar el mismo conjunto de objetos comerciales reales, puedo tener ciertos dolores de cabeza con conflictos de nombres, etc.(Dado que los objetos reales y los proxy tienen el mismo nombre).

  2. Olvídese de intentar pasar objetos comerciales "reales".En su lugar, simplemente cree objetos DataTransfer simples que asignaré manualmente a mis objetos comerciales reales.De todos modos, wsdl.exe todavía los copia en nuevos objetos proxy, pero al menos no me estoy engañando pensando que los servicios web pueden manejar de forma nativa objetos con lógica de negocios.

Por cierto, ¿alguien sabe cómo decirle a wsdl.exe que no hacer una copia del objeto?¿No deberíamos poder simplemente decirle: "Oye, usa este tipo existente aquí".¡No lo copie!".

De todos modos, por ahora me he decidido por el número 2, pero tengo curiosidad por saber qué piensan todos ustedes.tengo la sensación de que hay forma mejores formas de hacer esto en general, y es posible que ni siquiera sea totalmente preciso en todos mis puntos, así que hágame saber cuáles han sido sus experiencias.

Actualizar:Acabo de descubrir que VS 2008 tiene una opción para reutilizar tipos existentes al agregar una "Referencia de servicio", en lugar de crear un tipo nuevo e idéntico en el archivo proxy.Dulce.

¿Fue útil?

Solución

También existe un argumento para separar los niveles: tener un conjunto de objetos serializables que se pasan hacia y desde el servicio web y un traductor para mapear y convertir entre ese conjunto y los objetos comerciales (que pueden tener propiedades no adecuadas para pasar por encima del cable)

Es el enfoque favorecido por la fábrica de software de servicios web. fábrica de servicio y significa que puede cambiar sus objetos comerciales sin romper la interfaz/contrato del servicio web

Otros consejos

Yo haría un híbrido.Yo usaría un objeto como este.

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

luego tengo una pequeña utilidad que serializa un objeto y luego lo comprime.

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;
    }
}

Luego simplemente pasaría el objeto de transferencia que tendría el nombre del tipo.Entonces podrías hacer algo como esto.

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

En este momento, el serializador comprimido usa genéricos para hacerlo fuertemente tipado, pero podría crear un método fácil para aceptar un objeto Type para deserializar usando originType arriba, todo depende de su implementación.

Espero que esto te dé algunas ideas.Ah, y para responder a su otra pregunta, wsdl.exe no admite la reutilización de tipos, aunque WCF sí.

Darren escribió:Yo haría un híbrido.Yo usaría un objeto como este...

Idea interesante...pasando una versión serializada del objeto en lugar del objeto (wsdl-ed) en sí.En cierto modo, me gusta su elegancia, pero en otro sentido, parece anular el propósito de exponer su servicio web a posibles terceros o socios o lo que sea.¿Cómo sabrían qué pasar?¿Tendrían que depender únicamente de la documentación?También pierde parte del aspecto de "cliente heterogéneo", ya que la serialización es muy específica de .Net.No quiero ser crítico, solo me pregunto si lo que propone también está destinado a este tipo de casos de uso.Sin embargo, no veo nada malo en usarlo en un entorno cerrado.

Debería investigar WCF...Lo he estado evitando, pero tal vez sea el momento.

Oh, seguro, solo hago esto cuando soy el consumidor del servicio web o si tienes algún tipo de controlador al que solicitan un objeto y luego manejas la serialización y el envío en lugar de que ellos consuman directamente el servicio web.Pero en realidad, si están consumiendo directamente el servicio web, entonces no necesitarían ni necesariamente tendrían el ensamblado que tendría el tipo en primer lugar, y deberían usar los objetos que genera wsdl.

Y sí, lo que propongo es muy específico de .NET porque no me gusta usar nada más.La única otra vez que consumí servicios web fuera de .net fue en javascript, pero ahora solo uso respuestas json en lugar de respuestas de servicios web xml :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top