Um zu vermeiden, Ihr Service-Code, die bekannten Typen in web.config des Dienst gestellt abzuschrecken:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="SomeNs.BaseClassZ, SomeAssembly">
<knownType type="SomeNs.SubClassA, SomeAssembly" />
<knownType type="SomeNs.SubClassB, SomeAssembly" />
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
Wenn Sie es durch Code tun wollen, müssen Sie auf der Service-Schnittstelle dieses Attribut verwenden, und nicht auf die Arbeitsweise, aber ich würde den deklarativen Ansatz bevorzugen:
[ServiceContract]
[ServiceKnownType(typeof(SubClassA))]
[ServiceKnownType(typeof(SubClassB))]
public interface IFoo
{
[OperationContract]
BaseClassZ GetObject();
}
UPDATE:
Ich habe eine sample project geschrieben, die die Verwendung von web.config veranschaulicht, um bekannte Typen zu konfigurieren, was mein bevorzugter Ansatz ist. Und ein weiterer sample project demonstriert den zweiten Ansatz.
UPDATE 2:
Nach dem Silverlight-Anwendung Client auf Ihrem aktualisierten Code suchen bemerken wir die folgende Definition:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.IService1")]
public interface IService1 {
[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IService1/GetMany", ReplyAction="http://tempuri.org/IService1/GetManyResponse")]
System.IAsyncResult BeginGetMany(System.AsyncCallback callback, object asyncState);
System.Collections.ObjectModel.ObservableCollection<MyCommonLib.BaseClassZ> EndGetMany(System.IAsyncResult result);
[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IService1/GetSingle", ReplyAction="http://tempuri.org/IService1/GetSingleResponse")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyCommonLib.SubClassA))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyCommonLib.SubClassB))]
System.IAsyncResult BeginGetSingle(System.AsyncCallback callback, object asyncState);
MyCommonLib.BaseClassZ EndGetSingle(System.IAsyncResult result);
}
Beachten Sie, wie die BeginGetSingle
Methode der bekannten Art, während die Attribute enthält BeginGetMany
Methode nicht. Diese Attribute sollten in der Servicedefinition platziert werden, damit die Klasse so aussieht.
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.IService1")]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyCommonLib.SubClassA))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyCommonLib.SubClassB))]
public interface IService1
{
[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IService1/GetMany", ReplyAction="http://tempuri.org/IService1/GetManyResponse")]
System.IAsyncResult BeginGetMany(System.AsyncCallback callback, object asyncState);
System.Collections.ObjectModel.ObservableCollection<MyCommonLib.BaseClassZ> EndGetMany(System.IAsyncResult result);
[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IService1/GetSingle", ReplyAction="http://tempuri.org/IService1/GetSingleResponse")]
System.IAsyncResult BeginGetSingle(System.AsyncCallback callback, object asyncState);
MyCommonLib.BaseClassZ EndGetSingle(System.IAsyncResult result);
}
Da dies eine automatisch generierte Klasse ist es könnte ein Fehler in den SLsvcUtil.exe und svcutil.exe
sein, wie es das gleiche Verhalten zeigt. Die bekannten Typenattribute an der richtigen Stelle zu platzieren, löst das Problem. Das Problem ist, dass diese Klasse automatisch von einem Tool generiert wird und wenn Sie versuchen, es aus der WSDL neu zu generieren, wird es wieder versauen.
So scheint es, dass, wenn Sie die folgende Service-Definition:
[ServiceContract]
[ServiceKnownType(typeof(SubClassA))]
[ServiceKnownType(typeof(SubClassB))]
public interface IService1
{
[OperationContract]
BaseClassZ[] GetMany();
[OperationContract]
BaseClassZ GetSingle();
}
Und die drei Datenverträge von hier zwischen dem Client und dem Server freigegeben, wenn die Definition des Dienstes zu importieren, die Methode, die zurückgibt Eine Auflistung erhält nicht die korrekten bekannten Typattribute im generierten Clientproxy. Vielleicht ist das mit Absicht.
Ich sehe viel MSDN-Dokumentation und Beispiele, die Sie sicher, es so klingen möglich sein sollte, aber verdammt, wenn ich es zur Arbeit bringen kann! Hinzufügen eines Bounty ... – Aardvark