Информация сериализации 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), но его, вероятно, нет. стоит усилий, если вам не нужно создавать много классов-оболочек.