2009-06-21 6 views
1

Ich versuche, ein Datenkontraktobjekt, das ich auf dem Server erhalten habe, zu nehmen, einige Manipulationen daran vorzunehmen und dann eine upcasted-Version davon zurückzugeben, aber es scheint nicht zu funktionieren. Ich kann es mit den Attributen KnownType oder ServiceKnownType zum Laufen bringen, aber ich möchte nicht alle Daten runden. Unten ist ein Beispiel:WCF DataContract Upcasting

[DataContract] 
public class MyBaseObject 
{ 
    [DataMember] 
    public int Id { get; set; } 
} 

[DataContract] 
public class MyDerivedObject : MyBaseObject 
{ 
    [DataMember] 
    public string Name { get; set; } 
} 


[ServiceContract(Namespace = "http://My.Web.Service")] 
public interface IServiceProvider 
{ 
    [OperationContract] 
    List<MyBaseObject> SaveMyObjects(List<MyDerivedObject> myDerivedObjects); 
} 

public class ServiceProvider : IServiceProvider 
{ 
    public List<MyBaseObject> SaveMyObjects(List<MyDerivedObject> myDerivedObjects) 
    { 
     ... do some work ... 

     myDerivedObjects[0].Id = 123; 
     myDerivedObjects[1].Id = 456; 
     myDerivedObjects[2].Id = 789; 

     ... do some work ... 

     return myDerivedObjects.Cast<MyBaseObject>().ToList(); 
    } 
} 

jemand irgendwelche Ideen, wie diese zu erhalten, ohne neue Objekte neu erstellen zu müssen, arbeiten oder die Knowntype Attribute verwenden?

Antwort

0

Ich denke, dass Ihr Problem ist, dass Sie versuchen, eine generische Liste zu senden.

Es funktioniert, wenn Sie die Liste in einem Objekt kapseln. Das ist ein Objekt mit einer einzigen öffentlichen Eigenschaft erstellen, die die generische Liste ist.

Sie müssen auch sicherstellen, dass alle Klassen, die nicht direkt im Vertrag verwendet werden, als serialisierbar gekennzeichnet sind.

+0

Die IList sendet gut. Es ist, wenn ich versuche, das Objekt zu verbessern, das nicht funktioniert. Ich möchte nicht alle Daten hin- und herdrehen. –

+0

Sie könnten versuchen, benutzerdefinierten Zuordnungscode oder Schnittstellen zu verwenden. –

0

Wenn Sie die abgeleiteten Objekte zurückgeben möchten, wird es immer eine Rundreise geben, da der Client und der Dienst getrennt sind. Damit der Client seine eigene Liste von MyBaseObjects aktualisieren kann, muss er die Liste der MyDerivedObjects deserialisieren, die vom Server stammen.

Die Verwendung von KnownType und/oder ServiceKnownType wird benötigt, da dies zur Hinzufügung dieser Typinformationen in WSDL führt, die wiederum vom Client zum Deserialisieren der Nachrichten auf den richtigen Typ verwendet wird.

Für den Anfang, ein nützliches Werkzeug zum Testen des Szenarios Sie beschrieben haben: http://www.wcfstorm.com

+0

Ordentliches Dienstprogramm! :) Ich muss es versuchen. In Bezug auf die Upcasting, wenn ich das Basisobjekt instanziieren und die Werte festlegen, kann ich es gut senden, jedoch möchte ich die zusätzliche Arbeit vermeiden und das abgeleitete Objekt einfach upcast. Aus der Sicht ist das nicht möglich. –

0

Sie könnten eine DataContractSurrogate (IDataContractSurrogate) versuchen, Erstellen und Basistyp für den Anruf zu GetDataContractType zurück. Ich bin mir nicht sicher, ob es so verwendet werden sollte, damit Sie immer noch besser mit "der zusätzlichen Arbeit" umgehen können, aber vielleicht verstehe ich den Umfang dieser zusätzlichen Arbeit nicht.

0

Eines der Probleme mit WCF (und .net Remoting) ist, dass es versucht, "Message Passing" wie Methodenaufrufe aussehen.

Diese fallen, wenn Sie versuchen, zu viele "oop" -Designs zu verwenden.

Die Tatsache, dass die Nachrichten von .net Klassen vertreten sind, tut nicht wie .net Klasse alle ihre Verhalten machen.

Siehe this und this, um mehr über das Problem der Abstraktion Undichte.

So müssen Sie beginnen, über Nachricht nicht übergeben Objekt beim Entwurf Ihrer WCF-Schnittstellen zu denken, oder Sie werden viele Probleme wie diese treffen.