Наследуй от класса в сервисе wcf - PullRequest
1 голос
/ 22 сентября 2010

Я хочу наследовать от класса, который находится в службе WCF. Наследование работает нормально (я вижу свойства базового класса в моем дочернем классе), моя проблема возникает, когда я пытаюсь вызвать метод из службы и передать дочерний тип в качестве параметра, а не базовый тип.

Базовый класс в службе WCF (Pet):

[ServiceContract]
public interface IService
{
    [OperationContract]
    void BringPet(Pet pet);

    [OperationContract]
    void TakePet(Pet pet);

    [OperationContract]
    List<Pet> GetAllPets();
}

[DataContract]
public class Pet
{
    private string _name;
    private string _color;

    [DataMember]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    [DataMember]
    public string Color
    {
        get { return _color; }
        set { _color = value; }
    }
}

Класс на клиенте (Dog наследуется от Pet):

[DataContract()]
class Dog : PetService.Pet
{
    [DataMember()]
    public bool HasPedigree { get; set; }
    [DataMember()]
    public string Race { get; set; }
}

Когда я пытаюсь вызвать что-то вроде этого:

        Dog dog = new Dog()
        {
            Color = "Black",
            Name = "Pluto",
            HasPedigree = true,
            Race = "Travolta"
        };

        _client.BringPet(dog);

Я получаю CommunicationException, который говорит, что тип Dog не ожидается методом BringPet(Pet pet). Я бы решил эту проблему, установив атрибуты KnownType на стороне службы, но поскольку моя служба не должна знать тип Dog, я не могу установить атрибуты KnownType или ServiceKnownType.

Может кто-нибудь мне помочь?

Ответы [ 2 ]

4 голосов
/ 22 сентября 2010

Если вы хотите, чтобы унаследованные классы возвращались вместо тех, которые определены в вашем контракте на обслуживание, вы должны сообщить об этом WCF посредством атрибута ServiceKnownType:

[ServiceContract]
[ServiceKnownType(typeof(Dog))]
public interface IService
{
    [OperationContract]
    void BringPet(Pet pet);

    [OperationContract]
    void TakePet(Pet pet);

    [OperationContract]
    List<Pet> GetAllPets();
}

Это в основном говорит службе WCF также разрешить использование классов типа Dog в вашей службе.

Или вы можете украсить свой контракт с данными атрибутом KnownType:

[DataContract]
[KnownType(typeof(Dog))]
public class Pet
{
.....
}

, чтобы связать ваш тип контракта данных с дополнительными типами, которые могут быть использованы вместо него.

Так или иначе: вы должны сделать ваш дополнительный тип известным во время выполнения WCF - WCF не может выяснить этот факт, просто проверяя наследование типов .NET.

2 голосов
/ 22 сентября 2010

Я думаю, что это очень похоже на этот вопрос: Сервис - интерфейс клиента, совет по архитектуре

Как вы увидите, на самом деле нет простого способа сделать это без создания вашего сервисаоперация более общая.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...