2017-01-31 16 views
1

У меня есть следующие классы ...SerializationException при возвращении пользовательских классов из службы WCF

public abstract class Fallible<T> { 
} 

public class Success<T> : Fallible<T> { 
    public Success(T value) { 
    Value = value; 
    } 

    public T Value { get; private set; } 
} 

Подоплека этого можно найти в previous question of mine, но вам не нужно читать этот пост в качестве классы выше - все, что нужно, чтобы увидеть проблему.

Если у меня есть упрощенный вызов службы WCF, как это ...

[OperationContract] 
public Fallible<Patient> GetPatient(int id) { 
    return new Success<Patient>(new Patient {ID = 1,FirstName = "Jim",Surname = "Spriggs"}); 
} 

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

При попытке сериализовать параметр: GetPatientResult произошла ошибка. Сообщение InnerException было «Тип» PhysioDiary.Entities.FallibleClasses.Success`1 [[PhysioDiary.Entities.Patient, PhysioDiary.Entities, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]] ' с контрактом данных name> 'SuccessOfPatient0yGilFAm: http://schemas.datacontract.org/2004/07/PhysioDiary.Entities.FallibleClasses' не ожидается. Подумайте об использовании DataContractResolver, если вы используете DataContractSerializer или добавьте любые типы, не известные статически в список известных типов - например, с помощью атрибута KnownTypeAttribute или , добавив их в список известных типов, переданных в сериализатор. ' , Пожалуйста, см. InnerException для получения более подробной информации.

... с внутренним SerializationException исключением ...

Тип «PhysioDiary.Entities.FallibleClasses.Success`1 [[PhysioDiary.Entities.Patient, PhysioDiary.Entities, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]] ' с именем контракта данных>' SuccessOfPatient0yGilFAm: http://schemas.datacontract.org/2004/07/PhysioDiary.Entities.FallibleClasses ' не ожидается. Рассмотрите возможность использования DataContractResolver, если вы используете DataContractSerializer или добавляете любые типы, не известные статически в список известных типов - например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, передаваемых в сериализатор.

Я попытался добавить [DataContract] к классу и [DataMember] для каждого свойства, а также добавление атрибута [KnownType] для всех четырех классов, участвующих, и добавление [ServiceKnownType] для каждого из них по договору оказания услуг, но ничего не помогает ,

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

Кто-нибудь может объяснить, в чем проблема? Пожалуйста, дайте мне знать, если я не предоставил достаточную информацию.

ответ

0

Оказывается, все, что мне нужно сделать, это украсить метод обслуживания с [ServiceKnownType] атрибутами для базового типа, и каждого производного типа ...

[OperationContract] 
[ServiceKnownType(typeof(Fallible<Patient>)] 
[ServiceKnownType(typeof(Success<Patient>)] 
[ServiceKnownType(typeof(BadIdea<Patient>)] 
[ServiceKnownType(typeof(Failure<Patient>)] 
public Fallible<Patient> GetPatient(int id) { 
    return new Success<Patient>(new Patient {ID = 1,FirstName = "Jim",Surname = "Spriggs"}); 
} 

Хотя это боль, чтобы добавить четыре атрибута к каждому звоните, он работает.Я хотел бы знать, есть ли способ объединить их в один атрибут, но, по крайней мере, у меня сейчас работает служба.

Надеюсь, это поможет кому-то.