WCF: Schnittstellen, Generics und ServiceKnownType

8

Ich habe folgendes:

%Vor%

Wenn ich die Methode Get ausführen, erhalte ich den folgenden Fehler:

  

Beim Versuch, den Parameter Ссылка zu serialisieren, ist ein Fehler aufgetreten. Die InnerException-Nachricht war 'Type' PPS.Core.DomainModel.Support.Action.ActionResult'1 [[PPS.Core.DomainModel.SportProgram.ISportProgram, PPS.Core.DomainModel, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]] 'mit dem Datenvertragsnamen' ActionResultOfanyType: Ссылка wird nicht erwartet . Fügen Sie statische Typen, die der Liste der bekannten Typen nicht bekannt sind, hinzu, z. B. indem Sie das KnownTypeAttribute-Attribut verwenden oder diese der Liste bekannter Typen hinzufügen, die an DataContractSerializer übergeben werden. Weitere Informationen finden Sie unter InnerException.

Von diesem Fehler kann ich sehen, dass es ActionResult auflösen kann, aber ISportProgram kann nicht aufgelöst werden, obwohl ich ServiceKnownType (typeof (ActionResult & lt; SportProgram & gt;)) auf meiner Service-Schnittstelle habe. .

Beachten Sie, dass der Referenzstub, der generiert wird, so aussieht. So kann ich sehen, dass die bekannten Typen korrekt dargestellt werden:

%Vor%

Warum geht das schief ??? Beachten Sie, dass es den WCF-Dienst korrekt durchläuft ... aber es löst die Ausnahme aus, wenn das Ergebnis zurückgegeben wird.

Zuletzt ActionResult sieht so aus:

%Vor%

Prost Anthony

    
vdh_ant 03.09.2009, 23:28
quelle

5 Antworten

15

Nun, ich denke, das ist ein weiterer Fall der SOA vs. OOP "Impedance Mismatch". Die zwei Welten sind ziemlich getrennt.

In WCF wird alles, was vom Client an den Server übergeben wird, als serialisierte Nachrichten übergeben - es werden keine Referenzen verwendet.

Das bedeutet: Alles, was Sie auf dem Client serialisieren, an den Server senden, deserialisieren und verwenden wollen, muss konkret sein - Sie können keine Schnittstellen weitergeben, die Sie nicht verwenden können "nicht aufgelöste" Generika - Sie müssen es buchstabieren. Grundsätzlich muss alles, was vom Client über die Verbindung zum Server übertragen wird, im XML-Schema ausgedrückt werden können.

Dies hat viele Auswirkungen:

  • keine Schnittstellen - Sie können keine Schnittstellen weitergeben - Sie müssen mit konkreten Typen arbeiten
  • keine "automatische" Vererbung - Sie können nicht einfach eine Basisklasse definieren und darauf basierende abgeleitete Klassen weitergeben - diese müssen ebenfalls spezifiziert werden (dafür steht das ServiceKnownType-Attribut)
  • keine automatischen Generika - wieder müssen Sie stattdessen konkrete Typen verwenden

Das klingt nach vielen Einschränkungen - aber weil WCF die gesamte nachrichtenbasierte Kommunikation verwendet - es kann nicht mit Referenzen, Vererbung, Generika usw. umgehen - müssen Sie es buchstabieren.

Ich habe also wirklich keine Antwort für Sie per se - ich denke nur, dass Sie Ihre Strategie überdenken müssen und die Art ändern müssen, wie Ihr Client und Server Informationen über WCF austauschen.

Marc

PS: Ich habe mehr geforscht, und entgegen all meinem Verständnis scheint es eine Möglichkeit zu geben, alles, was auf einer Schnittstelle und / oder einer abstrakten Basisklasse basiert, zu serialisieren, solange du sicher sein kannst, dass es ist immer nur .NET an jedem Ende der Leitung (dh es ist nicht kompatibel mit zB Java).

Siehe Aaron Skonnard Blogpost auf dem NetDataContractSerializer und ein anderer Blogeintrag und noch ein , das zeigt, wie man den NetDataContractSerializer benutzt, um Dinge wie IPerson als Parameter an deine Methoden zu übergeben.

    
marc_s 04.09.2009, 05:16
quelle
2

Dies ist eines der Probleme, die ich mit ServiceStack.NET - Mein Open Source .NET und MONO Web Services Framework löse.

Service Stack wurde stark von Martin Fowlers Data Transfer Objektmuster beeinflusst, da es Ihnen erlaubt, einfach DTOs zu verwenden, um Ihre zu definieren Web Services - also der SOA Weg:).

Ich vermeide diese Einschränkung, die WCF innewohnt, indem ich meine eigenen WSDLs erzeuge, die sich so verhalten, wie Sie es erwarten. Als ein Vorteil, WCFs komplexe Konfiguration / ServiceContracts Modell zu ersetzen - Die SOAP-Webservices funktionieren auch auf MONO - siehe live Demo .

    
mythz 02.03.2011 16:20
quelle
1

Es ist eine alte Frage, und obwohl die akzeptierte Antwort völlig richtig ist, stolperte ich bei der Suche nach einem ähnlichen Problem und dachte, ich könnte meine Erfahrungen teilen. Es ist oft Kopfschmerzen, aber es ist möglich, Generika in Verbindung mit Schnittstellen mit WCF zu verwenden. Hier ist ein Arbeitsbeispiel einer anderen (ähnlichen) Implementierung, die ich gemacht habe:

%Vor%

Der Schlüssel hier ist die Kombination von KnownType und ServiceKnownType .

In Ihrem Fall können Sie also so etwas tun:

%Vor%

Dies funktioniert, wenn Sie einen gemeinsamen Vertrag haben (Zugriff auf die eigentliche Service-Schnittstelle) und den Vertrag mit ChannelFactory<ISportProgramBl> konsumieren. Ich weiß nicht, ob es mit einer Service-Referenz funktioniert.

Es scheint jedoch einige Probleme mit der Implementierung zu geben, wie hier erwähnt:

WCF Mit einer Schnittstelle und einem generischen Modell

Und eine andere ähnliche Frage, die hier gestellt und beantwortet wurde:

Generische Rückgabetypen mit Schnittstellentypparametern in WCF

    
smoksnes 12.02.2016 07:50
quelle
0

Sie geben eine IList von T zurück. Möglicherweise hat das System Probleme herauszufinden, was T ist.

Ich bin mir nicht sicher, ob es in Ordnung ist, eine Schnittstelle anstelle eines Typs zurückzugeben.

    
Shiraz Bhaiji 03.09.2009 06:55
quelle
0

Spezifizieren Sie Schnittstellen in den Objekten und nicht in konkreten Typen?

%Vor%

Bearbeiten:

Was ich sage ist, dass all die konkreten Typen, die Sie in den Generika (einschließlich Unterobjekt über Schnittstellen) übergeben, in der Liste der bekannten Typen übergeben werden. Wir hatten Serialisierungsprobleme, bei denen nicht alle Typen bekannt waren.

    
Preet Sangha 03.09.2009 06:45
quelle