Конечно! Единственное, что требуется для того, чтобы это заработало, — добавить класс B в список типов, о которых служба должна знать, используя ServiceKnownType.
Вот краткий пример, который я собрал, чтобы продемонстрировать это, представьте, что это ваш сервисный контракт:
using System.Runtime.Serialization;
using System.ServiceModel;
namespace WcfCovariance
{
[ServiceKnownType(typeof(Employee))]
[ServiceContract]
public interface IService1
{
[OperationContract]
Person GetPerson();
[OperationContract]
Person PutPerson(Person person);
}
[DataContract]
public class Person
{
[DataMember]
public string Name { get; set; }
}
[DataContract]
public class Employee : Person
{
[DataMember]
public double Salary { get; set; }
}
}
И реализация:
namespace WcfCovariance
{
public class Service1 : IService1
{
static Person Singleton = new Person { Name = "Me" };
public Person GetPerson()
{
return Singleton;
}
public Person PutPerson(Person person)
{
Singleton = person;
return Singleton;
}
}
}
Поскольку вы сообщили WCF о типе Employee
с помощью атрибута ServiceKnownType
, при его обнаружении (как во входных параметрах, так и в ответе) он сможет его сериализовать/десериализовать, независимо от того, использует он JSON или нет.
Вот простой клиент:
using System;
using WcfCovarianceTestClient.CovarianceService;
namespace WcfCovarianceTestClient
{
class Program
{
static void Main(string[] args)
{
var client = new Service1Client("WSHttpBinding_IService1");
// test get person
var person = client.GetPerson();
var employee = new Employee { Name = "You", Salary = 40 };
client.PutPerson(employee);
var person2 = client.GetPerson();
// Employee, if you add breakpoint here, you'd be able to see that it has all the correct information
Console.WriteLine(person2.GetType());
Console.ReadKey();
}
}
}
Очень распространена передача подтипов в службу WCF и из нее, единственное, что вы не сможете сделать, это указать интерфейс в качестве ответа в вашем контракте.
Надеюсь это поможет.
person
theburningmonk
schedule
02.02.2011