Frage

Wir schreiben das Jahr 2008 und ich bin immer noch hin- und hergerissen.Deshalb entwickle ich eine Webmethode, die einen komplexen Typ benötigt, der übergeben und von ihr zurückgegeben wird.Die beiden Optionen, mit denen ich spiele, sind:

  1. Pass und zurück tatsächlich Geschäftsobjekte mit Daten und Verhalten.Wenn wsdl.exe ausgeführt wird, werden automatisch Proxy-Klassen erstellt, die nur den Datenanteil enthalten, und diese werden auf der Serverseite automatisch in und aus meinen echten Geschäftsobjekten konvertiert.Auf der Client-Seite können sie nur den dummen Proxy-Typ verwenden und müssen ihn nach eigenem Ermessen einigen echten Geschäftsobjekten zuordnen.Ein großer Nachteil hierbei ist, dass ich, wenn ich sowohl die Server- als auch die Clientseite „besitze“ und denselben Satz realer Geschäftsobjekte verwenden möchte, auf gewisse Probleme mit Namenskonflikten usw. stoßen kann.(Da die realen Objekte und die Proxys den gleichen Namen haben.)

  2. Vergessen Sie den Versuch, „echte“ Geschäftsobjekte zu übergeben.Erstellen Sie stattdessen einfach einfache DataTransfer-Objekte, die ich manuell hin und her meinen echten Geschäftsobjekten zuordne.Sie werden immer noch von wsdl.exe in neue Proxy-Objekte kopiert, aber zumindest mache ich mir nicht vor, zu glauben, dass Webdienste Objekte mit Geschäftslogik nativ verarbeiten können.

Übrigens – Weiß jemand, wie man wsdl.exe dazu auffordert? nicht eine Kopie des Objekts erstellen?Sollten wir nicht einfach sagen können: „Hey, verwenden Sie diesen vorhandenen Typ hier.“Kopieren Sie es nicht!"

Wie auch immer, ich habe mich vorerst irgendwie für Nummer 2 entschieden, aber ich bin gespannt, was ihr alle denkt.Ich habe das Gefühl, dass es welche gibt Weg Im Allgemeinen gibt es bessere Möglichkeiten, dies zu tun, und ich bin möglicherweise nicht einmal in allen meinen Punkten ganz korrekt. Teilen Sie mir daher bitte mit, welche Erfahrungen Sie gemacht haben.

Aktualisieren:Ich habe gerade herausgefunden, dass VS 2008 eine Option zur Wiederverwendung vorhandener Typen beim Hinzufügen einer „Dienstreferenz“ bietet, anstatt einen völlig neuen identischen Typ in der Proxy-Datei zu erstellen.Süß.

War es hilfreich?

Lösung

Es gibt auch ein Argument für die Trennung der Ebenen: Sie verfügen über einen Satz serialisierbarer Objekte, die an den und vom Webdienst übergeben werden, und einen Übersetzer, der diesen Satz den Geschäftsobjekten zuordnet und zwischen ihnen konvertiert (die möglicherweise Eigenschaften haben, die nicht für die Übergabe geeignet sind). Draht)

Dies ist der von der Webservice-Softwarefabrik bevorzugte Ansatz Service-Fabrik und bedeutet, dass Sie Ihre Geschäftsobjekte ändern können, ohne die Webservice-Schnittstelle/den Webservice-Vertrag zu beschädigen

Andere Tipps

Ich würde einen Hybrid machen.Ich würde ein Objekt wie dieses verwenden

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

Dann habe ich ein nettes kleines Dienstprogramm, das ein Objekt serialisiert und dann komprimiert.

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

Dann würden Sie einfach das Übertragungsobjekt übergeben, das den Typnamen hätte.Sie könnten also so etwas tun

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

Im Moment verwendet der komprimierte Serialisierer Generika, um eine starke Typisierung zu gewährleisten. Sie können jedoch mithilfe von originType oben problemlos eine Methode erstellen, um ein Type-Objekt zum Deserialisieren aufzunehmen. Dies hängt alles von Ihrer Implementierung ab.

Ich hoffe, das gibt Ihnen einige Ideen.Oh, und um Ihre andere Frage zu beantworten: wsdl.exe unterstützt die Wiederverwendung von Typen nicht, WCF jedoch.

Darren schrieb:Ich würde einen Hybrid machen.Ich würde ein Objekt wie dieses verwenden ...

Interessante Idee...Übergabe einer serialisierten Version des Objekts anstelle des (wsdl-ed) Objekts selbst.In gewisser Weise gefällt mir seine Eleganz, aber andererseits scheint es den Zweck zunichte zu machen, Ihren Webdienst potenziellen Dritten oder Partnern oder was auch immer zugänglich zu machen.Woher sollten sie wissen, was sie passieren müssen?Müssten sie sich ausschließlich auf die Dokumentation verlassen?Es geht auch etwas von dem Aspekt des „heterogenen Clients“ verloren, da die Serialisierung sehr .Net-spezifisch ist.Ich möchte nicht kritisch sein, ich frage mich nur, ob das, was Sie vorschlagen, auch für diese Art von Anwendungsfällen gedacht ist.Ich sehe jedoch nichts Falsches daran, es in einer geschlossenen Umgebung zu verwenden.

Ich sollte mir WCF ansehen ...Ich habe es vermieden, aber vielleicht ist es an der Zeit.

Oh, klar, ich mache das nur, wenn ich der Verbraucher des Webservices bin oder wenn Sie eine Art Controller haben, von dem sie ein Objekt anfordern, und Sie dann die Serialisierung und das Senden übernehmen, anstatt den Webservice direkt zu konsumieren.Wenn sie den Webservice jedoch direkt nutzen, benötigen sie nicht unbedingt die Assembly, die den Typ enthalten würde, und sollten die von wsdl generierten Objekte verwenden.

Und ja, was ich darlege, ist sehr .NET-spezifisch, weil ich nichts anderes verwenden möchte.Das einzige andere Mal, dass ich Webservices außerhalb von .net konsumierte, war in Javascript, aber jetzt verwende ich nur noch JSON-Antworten anstelle von XML-Webservice-Antworten :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top