#wcf #silverlight-4.0 #datacontractserializer
#wcf #silverlight-4.0 #datacontractserializer
Вопрос:
У меня есть служба, через которую я пытаюсь передать словарь объектов. Все хорошо и работает, пока я не добавлю словарь объектов, который затем содержит словарь, к еще одному объекту. Словарь, вызывающий проблему, был бы класса A в приведенном ниже примере.
//example
public class A
{
public Dictionary<string,B> BValues { get; set; }
}
public class B
{
public Dictionary<string, C> CValues { get; set; }
}
public class C
{
int x;
int y;
}
Я попытался создать в своем сервисе словари knowntypes, а также убедиться, что другие классы помечены как контракт с данными, а их свойства отмечены атрибутом DataMember. Я в недоумении, что еще мне нужно или даже могу сделать, чтобы заставить это работать.
Редактировать
Исключение:
Элемент ‘schemas.microsoft.com/2003/10/Serialization/Arrays:Value ‘; содержит данные ‘schemas.microsoft.com/2003/10/Serialization / …; контракт с данными. Десериализатор не знает ни о каком типе, который соответствует этому контракту. Добавьте тип, соответствующий ‘ArrayOfKeyValueOfstringClassValuesNSpYOWsW’, в список известных типов — например, с помощью атрибута KnownTypeAttribute или добавив его в список известных типов, передаваемых DataContractSerializer.’
Комментарии:
1. В чем проблема? Вы получаете исключение сериализации или просто пустые свойства? Требуется дополнительная информация.
2. все строится и обновляется нормально. когда я запускаюсь, и он фактически пытается сериализовать объект для отправки клиенту, он получает исключение сериализации.
3. исключение таково: Элемент ‘ schemas.microsoft.com/2003/10/Serialization/Arrays:Value ‘ содержит данные ‘ schemas.microsoft.com/2003/10/Serialization / … ‘контракт данных. Десериализатор не знает ни о каком типе, который соответствует этому контракту. Добавьте тип, соответствующий ‘ArrayOfKeyValueOfstringClassValuesNSpYOWsW’, в список известных типов — например, с помощью атрибута KnownTypeAttribute или добавив его в список известных типов, передаваемых DataContractSerializer.’.
4. В одном я не уверен, это создает информацию в xsd таким образом, что в конце имени искажены буквы, не уверен, есть ли проблема с этим, но, возможно, это источник моего разочарования?
Ответ №1:
Чтобы попытаться выяснить, где это не удается, я настроил простую службу WCF, которая возвращает очень простой вложенный Dictionary
файл, который отлично работает с рядом добавленных к нему элементов.
[OperationContract]
Dictionary<int, Dictionary<int, int>> GetDictionary();
Исходя из этого, я предполагаю, что это проблема с вашими объектами (и, возможно, тот факт, что они находятся в Dictionary
коллекциях). Я предлагаю вам провести несколько тестов, чтобы сузить круг вашей проблемы.
Сериализуем ли ваш класс — можете ли вы десериализовать один экземпляр вашего типа? (например, напишите операцию для возврата объекта, подобного MyClass GetOneInstance();
). Можете ли вы вернуть простой Dictionary
вашего класса?
Существует несколько конфликтов именования, которые WCF может вызвать у вас — если ваши классы имеют то же имя, что и ваша служба или ваша операция, например, операция GetSomething
и объект с именем GetSomethingRequest
or GetSomethingResponse
не будут хорошо работать вместе — в основном из-за того, что запрос и ответ помещаются в конверты SOAP с автоматическими именами. Если ваши классы названы с использованием некоторого зарезервированного слова, вы могли бы попробовать переименовать их.
Исключение предполагает, что вы добавляете KnownType
атрибут. Обычно это применимо, когда вы возвращаете базовый тип, который может быть экземпляром наследуемого типа — так ли это? Связаны ли ваши объекты с наследованием и возвращаете ли вы базовые типы, которые могут быть экземплярами наследуемых типов? (например, A:B
и ваша операция возвращает a B
, но это может быть A
)
Комментарии:
1. Я прошел через это, как вы предложили, определенно помогло мне сузить проблему.
2. с известным типом, если вы возвращаете словарь<строка, объект> и в этом словаре у вас будет экземпляр A или B, должен ли атрибут KnowTypeAttribute быть для
KnownType(typeof(A))
илиKnownType(typeof(Dictionary<string,A>))
?3. @tam Я полагаю, вам нужно указать только известные типы, которые нуждаются в устранении неоднозначности (т. Е. A или B). Это всегда будет словарь, поэтому тип словаря уже будет включен в контракт. Это просто A amp; B, которые не являются конкретными.