Domanda

È il 2008 e sono ancora combattuto su questo.Quindi sto sviluppando un metodo web che necessita del passaggio di un tipo complesso e della restituzione da esso.Le due opzioni con cui sto giocando sono:

  1. Passa e ritorna effettivo oggetti business con dati e comportamenti.Quando viene eseguito wsdl.exe, creerà automaticamente classi proxy che contengono solo la porzione di dati e queste verranno automaticamente convertite da e verso i miei oggetti business reali sul lato server.Dal lato client, potranno utilizzare solo il tipo di proxy stupido e dovranno mapparli in alcuni oggetti di business reali come ritengono opportuno.Un grosso svantaggio qui è che se "possiedo" sia il lato server che quello client e desidero utilizzare lo stesso set di oggetti business reali, posso incorrere in alcuni grattacapi con conflitti di nomi, ecc.(Poiché gli oggetti reali e i proxy hanno lo stesso nome.)

  2. Dimentica di provare a passare oggetti business "reali".Invece, crea semplicemente semplici oggetti DataTransfer che mapperò manualmente avanti e indietro sui miei oggetti aziendali reali.Vengono comunque copiati su nuovi oggetti proxy da wsdl.exe, ma almeno non mi sto ingannando pensando che i servizi Web possano gestire in modo nativo oggetti con logica aziendale al loro interno.

A proposito, qualcuno sa come dire a wsdl.exe non fare una copia dell'oggetto?Non dovremmo essere in grado di dirgli semplicemente: "Ehi, usa questo tipo esistente proprio qui.Non copiarlo!"

Ad ogni modo, per ora ho optato per il numero 2, ma sono curioso di sapere cosa ne pensate.Ho la sensazione che ci siano modo modi migliori per farlo in generale, e potrei anche non essere del tutto preciso su tutti i miei punti, quindi per favore fatemi sapere quali sono state le vostre esperienze.

Aggiornamento:Ho appena scoperto che VS 2008 ha un'opzione per riutilizzare i tipi esistenti quando si aggiunge un "Riferimento al servizio", anziché creare un nuovo tipo identico nel file proxy.Dolce.

È stato utile?

Soluzione

c'è anche un argomento per separare i livelli: avere un insieme di oggetti serializzabili che vengono passati da e verso il servizio web e un traduttore per mappare e convertire tra quell'insieme e gli oggetti business (che potrebbero avere proprietà non adatte al passaggio oltre i livelli) filo)

È l'approccio favorito dalla fabbrica di software per servizi web fabbrica di servizi e significa che puoi modificare i tuoi oggetti aziendali senza infrangere l'interfaccia/il contratto del servizio web

Altri suggerimenti

Farei un ibrido.Utilizzerei un oggetto come questo

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

poi ho una piccola e carina utility che serializza un oggetto e poi 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;
    }
}

Quindi passeresti semplicemente l'oggetto di trasferimento che avrebbe il nome del tipo.Quindi potresti fare qualcosa del genere

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

in questo momento il serializzatore compresso utilizza i generici per renderlo fortemente tipizzato, ma potresti creare facilmente un metodo per includere un oggetto Type da deserializzare utilizzando originType sopra, tutto dipende dalla tua implementazione.

spero che questo ti dia qualche idea.Oh, e per rispondere alla tua altra domanda, wsdl.exe non supporta il riutilizzo dei tipi, WCF lo fa però.

Darren ha scritto:Farei un ibrido.Io utilizzerei un oggetto del genere...

Idea interessante...passando una versione serializzata dell'oggetto invece dell'oggetto stesso (wsdl-ed).In un certo senso, mi piace la sua eleganza, ma in un altro modo sembra vanificare lo scopo di esporre il tuo servizio web a potenziali terze parti o partner o altro.Come potrebbero sapere cosa passare?Dovrebbero fare affidamento esclusivamente sulla documentazione?Perde anche parte dell'aspetto "client eterogeneo", poiché la serializzazione è molto specifica per .Net.Non intendo essere critico, mi chiedo solo se ciò che proponi sia pensato anche per questi tipi di casi d'uso.Non vedo però nulla di sbagliato nell'usarlo in un ambiente chiuso.

Dovrei dare un'occhiata al WCF...Lo sto evitando, ma forse è il momento.

oh, certo, lo faccio solo quando sono il consumatore del servizio web o se hai una sorta di controller a cui richiedono un oggetto e quindi gestisci la serializzazione e l'invio anziché consumare direttamente il servizio web.Ma in realtà, se consumano direttamente il servizio web, non avrebbero bisogno o non avrebbero necessariamente l'assembly che conterrebbe il tipo in primo luogo e dovrebbero utilizzare gli oggetti generati da wsdl.

E sì, quello che ho proposto è molto specifico per .NET perché non mi piace usare nient'altro.L'unica altra volta che ho utilizzato servizi web al di fuori di .net era in Javascript, ma ora utilizzo solo le risposte json invece delle risposte dei servizi web xml :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top