Вопрос

У меня возникли небольшие проблемы с пониманием 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());

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

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

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

Это было полезно?

Решение

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

Таким образом, хотя сгенерировать тег "Circle" в исходящем XML-файле не составило бы проблемы, входящий десериализатор не знал бы, что с этим делать.

KnownType "hack" - это как реестр известных типов, который должен быть реализован обеими сторонами.Это явно выражено.С помощью этого реестра десериализатор знает, что "Circle" десериализуется до типа X, без каких-либо шансов на двусмысленность и без необходимости анализировать все доступные или достижимые сборки для производных типов.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top