Неожиданный тип - исключение сериализации
У меня есть служба 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
приведет к разрыву сериализации. Причина этого в том, что новые данные больше не могут быть проверены на фоне старых данных. Исправление для этого - использование старой версии, ожидаемой сервером/клиентом.