WCF - подкласс, добавленный в список [DataMember] <BaseClass>, вызывает исключение - PullRequest
4 голосов
/ 03 августа 2009

Один из моих классов [DataContract] содержит [DataMember], который является списком. BaseClass имеет несколько различных подклассов.

Всякий раз, когда этот Список содержит экземпляры какого-либо подкласса, возникает исключение во время / после того, как Сервис возвращается в канал запроса. Если в списке нет подклассов, он работает нормально.

Вот пример моего кода (который сам не работает):

public class BaseClass
{
}
public class BaseClassSub : BaseClass
{
}

[DataContract]
public class MyClass
{
    List<BaseClass> m_Classes = new List<BaseClass>();

    [DataMember]
    public List<BaseClass> Classes
    {
        get { return m_Classes; }
        set { m_Classes = value; }
    }
}


[ServiceContract]
public interface IMyService
{
    [OperationContract]
    MyClass GetMyClass();   

}

public class MyService : IMyService
{
    public MyClass GetMyClass()
    {
        MyClass o = new MyClass();

        //THIS WORKS!!!!
        //o.Classes = new List<BaseClass>() { new BaseClass() };

        //THIS DOES NOT WORK!!!!
        o.Classes = new List<BaseClass>() { new BaseClassSub() };

        return o;
    }
}

При отладке я получаю следующую ошибку:

Соединение с сокетом было прервано. Это может быть вызвано ошибкой обработки вашего сообщения или превышением тайм-аута приема удаленным хостом, или проблемой основного сетевого ресурса. Тайм-аут локального сокета был '00: 00: 59.6560000 '.

Кто-нибудь знает, как решить эту проблему (заставить ее обрабатывать подклассы)?

Ответы [ 3 ]

4 голосов
/ 03 августа 2009

Вам нужно сообщить Сериализатору Контракта Данных типы, с которыми он может столкнуться. См. Известные типы контрактов данных .

0 голосов
/ 28 декабря 2009

Десериализация DataContrat не вызывает конструктор, и начальные значения для членов не присваиваются

Это означает, что m_Classes будут нулевыми после десериализации. Убедитесь, что вы включили это в свой код либо событием OnDeserialize, либо создав список в getter.

0 голосов
/ 03 августа 2009

После дополнительного поиска я продолжил и добавил атрибут [KnownType] в BaseClass (см. Ниже), и теперь он работает.

[KnownType(typeof(BaseClassSub))]
public class BaseClass
{
}

Надеюсь, это поможет хотя бы другим!

...