Информация сериализации WCF вне определения класса - PullRequest
3 голосов
/ 10 июня 2011

Предположим, это простой сценарий: у моего клиента уже работает приложение .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 ]

4 голосов
/ 10 июня 2011

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

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

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

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

EDIT

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

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

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

1 голос
/ 10 июня 2011

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

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

...