Проблема WCF с сериализацией заголовка сообщения
-
19-09-2019 - |
Вопрос
У меня есть следующий код:
public virtual void Initialise()
{
this.AddHeader("SystemContext", this.UserSettings.SystemContext);
}
public virtual void AddHeader(string key, object value)
{
var customHeader = MessageHeader.CreateHeader(key, this.SystemSettings.SystemServiceNamespace, value);
OperationContext.Current.OutgoingMessageHeaders.Add(customHeader);
}
Когда я пытаюсь запустить сервер после запуска приведенного выше кода, я получаю следующую ошибку:
Введите «ACSIS.Core.Common.Configuration.UserAcountDetials» с именем контракта данных «UserAcountDetials:http://schemas.datacontract.org/2004/07/ACSIS.Core.Common.Configuration' не ожидается.Добавьте любые типы, которые не известны статически, в список известных типов, например, с помощью метода
KnownTypeAttribute
атрибут или добавив их в список известных типов, передаваемых в DataContractSerializer.
Сейчас UserSettings
описывает SystemContext
как принадлежащий к типу IDictionary
.Я понимаю, что WCF не может волшебным образом создавать объекты из воздуха или чего-то еще, поэтому мне нужно немного помочь.
Есть ли какой-нибудь способ передать тип объекта времени выполнения по проводу и преобразовать его обратно в этот тип на другой стороне.Я не использую WCF для Java-материалов SOA для .net или чего-то в этом роде, я знаю, что конкретный тип будет на другой стороне провода.
Если WCF на самом деле не поддерживает это (хотя должен быть какой-то способ), есть ли способ сериализовать данные в двоичный формат, прикрепить двоичный файл к заголовку и самостоятельно выполнить сериализацию, используя информацию о типе, которую я передаю.
Решение
Вы можете попробовать применить атрибутknownType к вашему сервисному контракту, например:
[ServiceKnownType(typeof(ACSIS.Core.Common.Configuration.UserAcountDetials))]
[ServiceContract]
public interface IMyService
{...
И да, хотя это менее элегантно, вы можете использовать BinaryFormatter для сериализации вашего объекта заголовка в массив byte[], вставить его в заголовок, а затем десериализовать на другой стороне.Двоичная сериализация сложна, когда дело доходит до управления версиями, поэтому вам следует быть немного осторожным.