Понимание ServiceKnownType в WCF - PullRequest
10 голосов
/ 03 мая 2010

У меня небольшая проблема с пониманием ServiceKnownType в WCF.

Взято из этого блога , следующий код не работает:

[DataContract(Namespace = “http://mycompany.com/”)]
public class Shape{…}

[DataContract(Namespace = “http://mycompany.com/”)]
public class Circle : Shape {…}

[ServiceContract]
public interface IMyServer
{
    [OperationContract]
    bool AddShape(Shape shape);
}

.

IMyServer client = new ChannelFactory<IMyServer>(binding, endPoint).CreateChannel();

client.AddShape(new Circle());

Причина, по которой это не работает, заключается в том, что вы пытаетесь добавить круг, но сервисный контракт допускает только форму. Предполагается, что вы делаете что-то с ноу-типами, но я немного озадачен тем, как это работает.

Поскольку этот код находится в сервисе, почему он не знает автоматически, что Circle получен из Shape? Кроме того, что на самом деле делает ServiceKnownType?

Когда ServiceKnownType ставится ниже DataContract, очевидно, это заставляет его работать. Я предполагаю, что это говорит, эй, этот конкретный тип объекта, называемый Shape, также может быть Кругом. У меня возникают проблемы с пониманием того, почему это происходит именно так, потому что, если вы добавите новый тип, такой как Square, вам придется добавить в класс Shape ServiceKnownType для него. Разве не имеет смысла выводить KnownType на квадрат, а не на форму, если он не может это сделать? Итак, Квадрат говорит: «Эй, я Шейп, а тебе не нужно возиться с классом Шейп? Если ваш класс Shape встроен в библиотеку, и вы хотите создать свою собственную фигурную форму, такую ​​как DiamondShape, вы не можете добавить ее в класс Shape, потому что у вас нет доступа к исходному коду.

1 Ответ

12 голосов
/ 03 мая 2010

Проблема в том, что WCF не входит во все сборки и пытается найти все возможные подтипы Shape. Он также не передает информацию о типе (сборка, полное имя типа) с документом XML.

Таким образом, хотя генерировать тег «Круг» в исходящем XML не будет проблемой, входящий десериализатор не будет знать, что с этим делать.

KnackType "hack" подобен реестру известных типов, который должен быть реализован обеими сторонами. Это явно. С этим реестром десериализатор знает, что «Круг» десериализуется до типа X без какой-либо вероятности двусмысленности и без необходимости разбора всех доступных или достижимых сборок для производных типов.

Помните, Square не говорит "Я фигура", он приходит как тег XML, и из-за этого вам нелегко и автоматически узнать, какой класс .NET использовать.

...