Информация сериализации WCF вне определения класса

Предположим, это простой сценарий: у моего клиента уже работает приложение.net, и он / она хочет показать некоторые функции через WCF. Поэтому он дает мне сборку, связываясь с публичным классом, который раскрывает метод followig.

OrderDetail GetOrderDetail (int orderId) // Suppose OrderDetail has {ProductId, Quantity, Amount)

Теперь я хочу, чтобы некоторые члены OrderDetail (Amount) не были сериализованы. Согласно http://msdn.microsoft.com/en-us/library/aa738737.aspx, это можно сделать с помощью атрибутов [DataContract] и [DataMember]/[IgnoreDataMember]. Однако это не вариант для меня, потому что я не могу изменить исходный код клиента. Поэтому я ищу способ указать, какие члены я хочу сериализовать, вне определения типа. Что-то, что должно выглядеть так:

    [OperationContract]
    [IgnoreMember(typeof(OrderDetail), "Amount" )]
    OrderDetail QueryOrder(int orderId){
          return OrderDetail.GetOrderDetail(orderId)  
    }

Есть ли способ к этому? Спасибо Бернабе

2 ответа

Решение

Не отправляйте объекты клиентов по сети, создайте DTO из объекта клиентов, содержащего только ту информацию, которую вы хотите отправить, и отправьте ее вместо этого.

Это позволяет точно контролировать, какая информация отправляется, и соответствует намерениям WCF о передаче сообщений, а не объектов

Так что создайте OrderDetailDto class и заполнить это данными из OrderDetail возвращается при вызове метода в коде клиентов. Украсьте OrderDetailDto с DataContract а также DataMember атрибуты (вы можете переименовать класс здесь, чтобы при возвращении WCF он возвращался с именем OrderDetail)

Повторите это для всех объектов в клиентском коде, чтобы на границе службы вы в основном конвертировали из DTO-> клиентских объектов и клиентских объектов->DTO

РЕДАКТИРОВАТЬ

Хотя может существовать опция, позволяющая просить то, о чем вы просили (я не знаю об этом, но, надеюсь, кто-то еще), учтите, что при отправке используйте ваши клиентские объекты в качестве DTO, вы используете их для двух целей (клиентский объект и контракт на передачу сообщений), что противоречит принципу единой ответственности, и когда вы получите их на стороне клиента, они не будут одинаковыми объектами на стороне клиента, только DTO с одинаковыми свойствами, вы не сможете получить поведение на клиенте сторонние объекты (по крайней мере, без совместного использования библиотек на стороне сервера и на стороне клиента).

Привязывая контракт данных к объектам, вы также в конечном итоге должны будете управлять изменениями в клиентских объектах и ​​контрактах данных как единое целое. Когда они разделены, вы можете управлять изменениями объектов на стороне клиента без необходимости изменять DTO, вы можете просто заполнить их по-другому.

Хотя кажется, что создание ОТО - это большая работа, но в конце я думаю, что это того стоит.

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

Единственным другим вариантом будет создание нового динамического класса с использованием отражения и его сериализация (см. http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspx), но его, вероятно, нет. стоит усилий, если вам не нужно создавать много классов-оболочек.

Другие вопросы по тегам