WCF: Interfaces, Generics und ServiceKnownType
Habe ich Folgendes:
[ServiceContract]
[ServiceKnownType(typeof(ActionParameters))]
[ServiceKnownType(typeof(SportProgram))]
[ServiceKnownType(typeof(ActionResult<SportProgram>))]
public interface ISportProgramBl
{
[OperationContract]
IActionResult<ISportProgram> Get(IActionParameters parameters);
}
Wenn ich das Cmdlet Get-Methode erhalte ich die folgende Fehlermeldung:
Es wurde ein Fehler beim serialisieren der parameter http://tempuri.org/:GetResult. Die InnerException-Nachricht war " der Typ 'PPS.Core.DomainModel.Unterstützung.Aktion.ActionResult`1[ [PPS.Core.DomainModel.SportProgram.ISportProgram, PPS.Core.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' mit Daten-Vertrag name 'ActionResultOfanyType: http://schemas.datacontract.org/2004/07/PPS.Core.DomainModel.Support.Action' ist nicht zu erwarten. Fügen Sie alle Arten nicht bekannt ist statisch in der Liste der bekannten Typen - Z. B. durch die Verwendung der KnownTypeAttribute-Attribut oder indem Sie Sie der Liste der bekannten Typen DataContractSerializer übergeben.'. Bitte sehen InnerException für mehr details.
Diesen Fehler kann ich sehen, dass Sie es beheben können, ActionResult, aber es nicht lösen können ISportProgram, obwohl ich ServiceKnownType(typeof(ActionResult < SportProgram >)) auf meine service-Schnittstelle...
Hinweis: dies ist die Referenz-stub, generiert wird, sieht wie folgt aus, so kann ich sehen, dass die bekannten Arten gebracht wird, über richtig:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="SportProgramStb.ISportProgramBl")]
public interface ISportProgramBl {
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ISportProgramBl/Get", ReplyAction="http://tempuri.org/ISportProgramBl/GetResponse")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(PPS.Core.DomainModel.SportProgram.SportProgram))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(PPS.Core.DomainModel.Support.Action.ActionParameters))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(PPS.Core.DomainModel.Support.Action.ActionResult<PPS.Core.DomainModel.SportProgram.SportProgram>))]
object Get(object parameters);
}
Warum ist das denn falsch?????? Hinweis die immer über den WCF-Dienst korrekt... aber es wirft die Ausnahme, wenn das Ergebnis zurückgegeben wird.
Schließlich ActionResult sieht wie folgt aus:
public interface IActionResult<T>
{
T Result { get; set; }
}
Cheers
Anthony
- Der Typ
ActionResult<ISportProgram>
dassSerializer
erwartet unterscheidet sich von der ArtActionResult<SportProgram>
inServiceKnownType
!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gut, ich denke, dies ist ein weiterer Fall von SOA vs. OOP "impedance mismatch". Die beiden Welt sind ziemlich getrennt.
In der WCF ist, alle übergeben wird, die vom client an den server übergeben serialisierten Nachrichten - keine Verweise verwendet werden.
Bedeutet dies: alles, was Sie wollen, zu serialisieren, die auf den client senden es über den server, und deserialisiert es und verwenden Sie es, Sie werden müssen konkrete -, die Sie nicht passieren können, um Schnittstellen, die Sie nicht verwenden "nicht-gelöst" Generika - Sie müssen spell it out. Im Grunde, alles, was übergeben wird vom client über das Netzwerk zu der server muss expressable in XML-schema.
Dies hat viele Auswirkungen:
Dies klingt vielleicht wie eine Menge von Einschränkungen - aber es ist da WCF ist mit allen message-basierte Kommunikation - es kann nicht umgehen mit refereces, Vererbung, generics etc. - Sie müssen spell it out.
So dass ich nicht wirklich eine Antwort für Sie per se - ich denke nur, Sie müssen Ihre Strategie zu überdenken und zu ändern, wie auf Ihrem client und der server tauschen Informationen über WCF.
Marc
PS: ich habe etwas mehr Forschung, und im Gegensatz zu meinem Verständnis, es scheint einen Weg zu serialisieren alles, was, basierend auf einer Schnittstelle und/oder eine abstrakte Basisklasse, die über den Draht, so lange wie Sie können sicher sein, dass es immer nur .NET, die an beiden enden des Drahtes (D. H. es ist nicht kompatibel mit z.B. Java).
Sehen Aaron Skonnard blog-post auf der NetDataContractSerializer und anderen blog-post und ein weiteres zeigt, wie Sie mithilfe der NetDataContractSerializer weitergeben kann, um Dinge wie
IPerson
als Parameter an die Methoden.Dies ist eines der Probleme, die ich lösen mit ServiceStack.NET - Meine Open-Source .NET-und MONO-Web-Services-Framework.
Service-Stack wurde stark beeinflusst durch die Martin Fowlers Data Transfer Object Pattern da es Ihnen erlaubt, verwenden Sie einfach DTO ' s zu definieren, die web-services - also die SOA ist Weg :).
Ich diese Einschränkung vermeiden, dass die inhärente in WCF durch die Erstellung meiner eigenen WSDL-s, die sich Verhalten, als würden Sie von Ihnen erwarten. Als Vorteil des Ersetzens der WCF komplexe Konfiguration /ServiceContract - Modell- Die SOAP-web-services funktioniert auch auf MONO - sehen Sie die live-demo.
Es ist eine alte Frage, und obwohl die akzeptierte Antwort ist völlig richtig, ich stumpled upon diese bei der Suche für ein ähnliches problem und dachte, ich könnte meine Erlebnisse teilen. Es ist oft ein Kopfschmerz, aber es ist möglich, dass Generika verwendet werden, kombiniert mit Schnittstellen mit WCF. Hier ist ein Beispiel eines anderen (ähnlichen) - Implementierung, die ich gemacht habe:
Der Schlüssel ist hier, die Kombination von
KnownType
undServiceKnownType
.So, in Ihrem Fall kann man etwas wie das hier tun:
Diese arbeiten, wenn Sie einen gemeinsamen Vertrag (Zugang zu den eigentlichen service-Schnittstelle) und verbrauchen den Vertrag mit
ChannelFactory<ISportProgramBl>
. Ich weiß nicht, ob es funktioniert mit einem service-Referenz.Jedoch scheint es einige Probleme mit der Umsetzung, wie Sie hier erwähnt:
WCF Mit einem interface und ein generisches Modell
Und andere ähnliche Frage gestellt und hier beantwortet:
Generische Rückgabetypen mit interface type params in WCF
Sind Sie wieder, die eine IList von T. Es vielleicht, dass das system Probleme hat, herauszufinden, was T ist.
Nicht sicher, ob es ok ist, um eine Schnittstelle eher als ein Typ.
Sind Sie spezifizieren Schnittstellen, die Objekte und nicht auf den konkreten Typen?
Edit:
Was ich damit sagen will, ist, dass sich alle konkreten Typen, die Sie übergeben, in der Generika (auch in sub-Objekt über Schnittstellen) übergeben wird in der Bekannten Typen-Liste. Wir hatten serialasation Fragen, wo all die Typen waren nicht bekannt.