Неожиданный тип - исключение сериализации

У меня есть служба WCF.

Нормальная операция увидит, что сервер выполняет некоторую обработку, возвращая заполненный объект XactTaskIn клиенту с помощью обратного вызова. Я работаю нормально.

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

Исключение - "Тип" XactException "с название контракта с данными 'XactException: HTTP://schemas.datacontract.org/2004/07/' не ожидается. Рассмотрите возможность использования DataContractResolver или добавить любые типы неизвестно статически в списке известных типов - например, используя атрибут KnownTypeAttribute или добавив их в список известных типов передан в DataContractSerializer." (Исключение System.Runtime.Serialization.SerializationException) Исключение Сообщение = "Тип" XactException "с название контракта с данными 'XactException: HTTP://schemas.datacontract.org/2004/07/' не ожидается. Рассмотрите возможность использования DataContractResolver или добавить любые типы неизвестно статически в списке известных типов - например, используя атрибут KnownTypeAttribute или добавив их в список известных типов передан в DataContractSerializer.", Тип исключения = "System.Runtime.Serialization.SerializationException"

Вот класс XactTaskIn

[DataContract]
public class XactTaskIn
{
    [DataMember]
    public DateTime timeOut;
    [DataMember]
    public DateTime timeIn;
    [DataMember]
    public string name;
    [DataMember]
    public string responseTo;
    [DataMember]
    public String moduleFromName;
    [DataMember]
    public String moduleFromType;
    [DataMember]
    public String methodFromName;
    [DataMember]
    public object[] originalInputs;
    [DataMember]
    public String returnMethodToCall;
    [DataMember]
    public String returnModuleToCall;
    [DataMember]
    public object returnData;

    public XactTaskIn(DateTime timeOut, DateTime timeIn, string name, string responseTo, String moduleFromName, String moduleFromType, String methodFromName, object[] originalInputs, String returnMethodToCall, String returnModuleToCall, object returnData)
    {
        this.timeOut = timeOut;
        this.timeIn = timeIn;
        this.name = name;
        this.responseTo = responseTo;
        this.moduleFromName = moduleFromName;
        this.moduleFromType = moduleFromType;
        this.methodFromName = methodFromName;
        this.originalInputs = originalInputs;
        this.returnMethodToCall = returnMethodToCall;
        this.returnModuleToCall = returnModuleToCall;
        this.returnData = returnData;
    }
}

Вот класс XactException:

[DataContract]    
public class XactException
{
    [DataMember]
    string message;

    public XactException(string message)
    {
        this.message = message;
        // Add implementation.
    }
}

Update:

Итак, комментарий от Дэниела помог мне.

Теперь он выглядит так, как сервер отправляет обратный вызов клиенту, но клиент бросает следующее исключение.

  • Пойманный: "Форматирщик сделал исключение, пытаясь десериализовать сообщение: произошла ошибка, пока попытка десериализации параметра http://tempuri.org/:taskIn. Сообщение InnerException было" Ошибка в строка 1 позиция 960. Элемент 'Http://schemas.datacontract.org/2004/07/:returnData' содержит данные от типа, который отображает имя 'Http://schemas.datacontract.org/2004/07/:XactException. Дезериализатор не знает любой тип, который сопоставляется с этим именем. Рассмотрите возможность использования DataContractResolver или добавьте тип, соответствующий "XactException" в список известных типов - например, используя Атрибут KnownTypeAttribute или добавив его в список известных типов передан в DataContractSerializer. '. См. InnerException для получения дополнительной информации. Детали. "(System.ServiceModel.Dispatcher.NetDispatcherFaultException) Исключение Сообщение =" Формататор бросил исключение при попытке десериализации сообщение: произошла ошибка, пока попытка десериализации параметра http://tempuri.org/:taskIn. Сообщение InnerException было" Ошибка в строка 1 позиция 960. Элемент 'Http://schemas.datacontract.org/2004/07/:returnData' содержит данные от типа, который отображает имя 'Http://schemas.datacontract.org/2004/07/:XactException. Дезериализатор не знает любой тип, который сопоставляется с этим именем. Рассмотрите возможность использования DataContractResolver или добавьте тип, соответствующий "XactException" в список известных типов - например, используя Атрибут KnownTypeAttribute или добавив его в список известных типов передан в DataContractSerializer. '. См. InnerException для получения дополнительной информации. детали. ", Тип исключения = "System.ServiceModel.Dispatcher.NetDispatcherFaultException"

Ответ 1

В вашем классе

    [DataContract]
    public class XactTaskIn

у вас есть свойства, возвращающие объекты:

        [DataMember]
        public object[] originalInputs;

        [DataMember]
        public object returnData;

WCF должен заранее знать, какие типы могут быть там, чтобы он мог сообщить клиенту (через WSDL), что все типы. Для любых/всех неинформативных типов (ничего, что isnt int, string, DateTime и т.д.) Вам нужно будет добавить атрибут [KnownType] для каждого возможного типа, который может быть передан обратно в этих свойствах объекта, например:

    [KnownType(typeof(XactException))]
    [KnownType(typeof(...))]
    [KnownType(typeof(...))]
    [DataContract]
    public class XactTaskIn

Таким образом, когда WCF создает WSDL для этой службы, он будет знать, как добавить XactException в список типов данных, а также будет знать, что эти сериализаторы будут искать эти классы.


Побочное записка; если ваш клиент был создан с использованием SrvUtil, Service Reference или каким-то образом создан из WSDL, вам нужно будет перестроить клиент после добавления атрибутов [KnownType]!

Ответ 2

Ваш клиент ожидает, что XactTaskIn не исключает XactException.

Вам нужно изменить XactTaskIn, чтобы иметь возможность передать объект исключения обратно вашему клиенту.

Отбросьте исключение datacontract и добавьте тип XactException в класс XactTaskIn как член данных

Ответ 3

Исключения для Seriliazation происходят, когда данные изменяются, например, что-то как тривиальное, так как изменение имени поля от awesomeString до awesomeString приведет к разрыву сериализации. Причина этого в том, что новые данные больше не могут быть проверены на фоне старых данных. Исправление для этого - использование старой версии, ожидаемой сервером/клиентом.