Сервисный метод, возвращающий список базовых объектов, дает мне сообщение «Сложные типы не могут указывать KnownTypeAttribute» - PullRequest
0 голосов
/ 23 декабря 2011

Я использую службы WCF RIA для возврата пользовательского объекта передачи данных клиенту Silverlight.

Я хотел бы вернуть объект, скажем FruitBasket (аналогично этой записи ), который содержит список фруктов.Класс Fruit является базовым классом для производных классов, таких как Apple, Pear, Peach и т. Д. Во время выполнения список Fruits может содержать любой из этих производных типов.Я хочу, чтобы службы RIA сериализовали и десериализовали весь объект FruitBasket, включая его коллекцию Fruits.

  • Если я просто определяю свою иерархию классов и возвращаю весь объект FruitBasket, я получаю ошибку времени выполнения:

Тип 'Peach' с именем контракта данных 'Peach: http://schemas.datacontract.org/2004/07/FruitApp' не ожидается.Попробуйте использовать DataContractResolver или добавить любые типы, которые не известны статически, в список известных типов - например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, передаваемых в DataContractSerializer.

  • Если я затем укажу атрибут [KnownType(typeof(Peach))] в своем классе Fruit, я получу ошибку во время компиляции:

Недопустимый комплексный тип 'Fruit'.Сложные типы не могут указывать KnownTypeAttribute.

Как настроить модель данных, чтобы я мог получить доступ к коллекции Fruit на клиенте?На стороне клиента было бы хорошо, если бы объекты распознавались только как объекты "Fruit".Мне просто нужно их десериализовать.

Ответы [ 2 ]

2 голосов
/ 24 декабря 2011

Службы RIA поддерживают 2 типа пользовательских типов: сложные типы и типы объектов. Сущность - это постоянный объект, у которого есть ключ, который однозначно идентифицирует его. Сложный тип - это просто объединение нескольких полей примитивного типа в один объект. Они не работают с общей концепцией классов и иерархий, они накладывают ограничения на то, что вы можете или не можете делать, чтобы более эффективно решать некоторые конкретные проблемы.

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

Теперь есть несколько вариантов решения проблемы:

  1. Если у вас уже есть соответствующий ключ в вашем классе Fruit (скажем, идентификатор базы данных), просто пометьте его атрибутом [Key].
  2. Если у вас нет ключа и вам все равно, добавьте свойство Guid, которое возвращает Guid.NewGuid(), пометьте его [Key] и все будет в порядке. Обратите внимание , что в этом случае вы не сможете установить какие-либо отношения к Fruit сущностям, а также сохранить изменения на сервере.
  3. Не используйте наследование. Если в этом нет необходимости, почему бы не жить без него?
  4. Использовать обычный WCF. RIA Services не являются общей коммуникационной платформой. Они очень специфичны для всех этих сущностей-отношений.

Выбор за вами, потому что это зависит от ваших требований.

0 голосов
/ 23 декабря 2011

Очевидно, что службы WCF RIA будут рассматривать любой класс без KeyAttribute как сложный тип, что приведет к ошибке.

Таким образом, если у вас есть свойство в базовом классе Fruit, которое можно использовать в качестве ключа, то для его украшения [Key] должно появиться сообщение об ошибке сложного типа.

...