Para evitar disuadir el código de servicio puso a los tipos conocidos en web.config del servicio:
<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>
Si desea hacerlo por código que necesita para utilizar este atributo en la interfaz de servicio y no en el método de operación, pero yo preferiría el enfoque declarativo:
[ServiceContract]
[ServiceKnownType(typeof(SubClassA))]
[ServiceKnownType(typeof(SubClassB))]
public interface IFoo
{
[OperationContract]
BaseClassZ GetObject();
}
ACTUALIZACIÓN:
He puesto un sample project que ilustra el uso de web.config para configurar tipos conocidos, que es mi enfoque preferido. Y otro sample project demostrando el segundo enfoque.
ACTUALIZACIÓN 2:
Después de mirar el código actualizado con el cliente aplicación de Silverlight notamos la siguiente definición:
[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);
}
Aviso cómo el método BeginGetSingle
contiene el tipo conocido atributos mientras que el BeginGetMany
método no. De hecho, esos atributos se deben colocar en la definición del servicio para que la clase se vea así.
[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);
}
Como se trata de una clase autogenerada podría haber un error en el SLsvcUtil.exe y svcutil.exe
ya que presenta el mismo comportamiento. Poner los atributos de tipo conocidos en su lugar correcto resuelve el problema. El problema es que esta clase es autogenerada por una herramienta y si intentas regenerarla desde el WSDL se volverá a enredar.
Así que parece que si tiene la siguiente definición de servicio:
[ServiceContract]
[ServiceKnownType(typeof(SubClassA))]
[ServiceKnownType(typeof(SubClassB))]
public interface IService1
{
[OperationContract]
BaseClassZ[] GetMany();
[OperationContract]
BaseClassZ GetSingle();
}
Y los 3 contratos de datos utilizados aquí son compartidas entre el cliente y el servidor al importar la definición del servicio, el método que devuelve una colección no obtiene los atributos de tipo conocidos correctos en el proxy del cliente generado. Tal vez esto es por diseño.
veo un montón de documentación de MSDN y muestras que asegurarse de que suene como esto debería ser posible , pero maldita sea si puedo hacer que funcione! Agregar un bounty ... – Aardvark