Информация о сериализации WCF вне определения класса
-
26-10-2019 - |
Вопрос
Предположим, что этот простой сценарий: у моего клиента уже работающее приложение .NET, и он/она хочет разоблачить некоторые функции через WCF. Таким образом, он дает мне собрание, загрязняя общественный класс, который разоблачает метод следующего.
OrderDetail GetOrderDetail (int orderId) // Suppose OrderDetail has {ProductId, Quantity, Amount)
Теперь я хочу, чтобы некоторые члены OrderDetail (сумма) не были сериализованы. Согласно с http://msdn.microsoft.com/en-us/library/aa738737.aspx, Способ сделать это посредством атрибутов [datacontract] и [datamember]/[игнорируемых игроков]. Тем не менее, это не вариант для меня, потому что я не могу изменить исходный код клиента. Поэтому я ищу способ указать, какие участники я хочу сериализовать, вне определения типа. Что -то, что должно выглядеть так:
[OperationContract]
[IgnoreMember(typeof(OrderDetail), "Amount" )]
OrderDetail QueryOrder(int orderId){
return OrderDetail.GetOrderDetail(orderId)
}
Есть ли способ к этому? Спасибо, Бернабе
Решение
Не отправляйте объекты клиентов через провод, создайте DTO из объекта клиентов, содержащей только информацию, которую вы хотите отправить, и отправить это вместо этого.
Это позволяет вам точно контролировать, какую информацию отправляется, и соответствует намерениям WCF передачи сообщений, а не объектов
Так что создайте OrderDetailDto class
и заполнить это данными из OrderDetail
Возврат вызовом методу в коде клиентов. Украсить OrderDetailDto
с DataContract
а также DataMember
Атрибуты (вы можете переименовать класс здесь, чтобы, когда он возвращался WCF, он возвращался с именем OrderDetail
)
Повторите это для всех объектов в клиентском коде, так что на границе службы вы в основном конвертируете из объектов DTO-> клиента и клиентских объектов-> DTO
РЕДАКТИРОВАТЬ
Хотя может быть вариант, который позволяет вы просили (я не знаю об этом, но, надеюсь, кто -то другой может быть) подумайте, что при отправке используйте свои клиентские объекты в качестве DTO, вы используете их для двух целей (клиент -объект и договор сообщений), который противоречит принципу единой ответственности, и когда вы получите их на стороне клиента, они не будут теми же объектами на стороне клиента, только DTO с теми же свойствами, вы не сможете получить поведение в клиенте Боковые объекты (по крайней мере, не совместно с библиотеками на стороне сервера и клиентской стороне).
Связывая контракт данных с объектами, вы также должны управлять изменениями клиентских объектов и контрактов данных как одно. Когда они отделены, вы можете управлять изменениями в объектах на стороне клиента без необходимого изменения DTO, вы можете просто заполнить по -разному.
Хотя кажется, что это много работы по созданию DTO, в конце концов, я думаю, что это того стоит.
Другие советы
Вам придется написать класс обертки, который раскрывает только желаемые свойства и просто вызывает класс, предоставленный вашему клиенту, чтобы получить свои значения.
Единственный другой вариант - издавать новый динамический класс, используя отражение и сериализовать (см. http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspx), но, вероятно, не стоит усилий, если вам не нужно построить много классов обертки.