Я уже неоднократно писал о проблемах известных типов (Known Types) в WCF и о нескольких способах ее решения. При этом я также упоминал, что одним из наиболее радикальных способов решения этой проблемы является использование сериализатора NetDataContactSerializer, вместо DataContractSerializer, используемого по умолчанию. Основное отличие первого класса от второго заключается в том, что NetDataContractSerializer сохраняет информацию о CLR-типе в сериализированный поток байтов, передаваемый между сервисом и его клиентом. Такое поведение нарушает ключевой принцип сервис-ориентированной архитектуры (SOA, Service-Oriented Architecture), который гласит о том, что сервисы и их клиенты не должны ничего знать о тех платформах, языках или технологиях, на которых они работают. Однако иногда мы можем себе позволить пойти на такие жертвы, когда четко знаем, что наша система предназначена только для платформы .Net, а другие языки и технологии использоваться не будут.
Наиболее популярным в сети способом использования NetDatacontractSerializer-а заключается в создании custom-атрибута, которым нужно пометить все методы сервиса или сам сервис целиком (этот способ я описывал в одной из предыдущих заметок и именно его я использовал на практике), однако появились сведения, что в некоторых случаях это может привести к проблемам, поскольку в этом случае производится изменение поведения (operation behavior) уже после вызова метода OpenHost, и в некоторых случаях может привести к непредсказуемому поведению. Другим, не менее важным недостатком того подхода является то, что вам нужно захардкодить ваше решение прямо в коде (путем добавления этих атрибутам к классам и/или методам) и нельзя перейти от одного решения к другому без перекомпиляции приложения. Кроме того, этот вариант не работает совместно с получением информации о сервисе посредством mex (Metadata Exchange Endpoints), поскольку в этом случае будут сгенерированы классы и интерфейсы без этого атрибута и попытка их использования ни к чему хорошему не приведет. В данном случае клиент будет использовать сериализатор DataContractSerializer, а сервис NetDataContractSerializer, и хотя данные сериализованные первым сериализатором могут быть десериализированы вторым, в обратном направлении это работает не всегда.