Можно ли создавать элементы «только для чтения» в веб-службах SOAP? - PullRequest
3 голосов
/ 27 мая 2009

У меня есть класс с определенным свойством только для чтения. В моем коде я определяю это как свойство только с геттером.

Я хочу иметь возможность отправлять этот объект туда и обратно через веб-сервис. Когда я вызываю метод «Get» в сервисе, он заполняется значением на стороне сервиса. Как только я определю это свойство, я не хочу, чтобы потребитель веб-службы мог устанавливать / изменять это свойство.

Когда я добавляю ссылку на этот веб-сервис в проект, свойство объекта сериализуется несколькими различными способами в зависимости от того, как я пытаюсь определить объект на стороне сервиса:

  • внутренний установщик : Создает свойство в WSDL. Visual Studio генерирует для этого свойства класс как с геттером, так и с сеттером.
  • без установщика : не создает свойство в WSDL. Тогда Visual Studio, очевидно, вообще не определяет это свойство.
  • Общедоступная переменная-член только для чтения - Не создает свойство в WSDL. Опять же, Visual Studio не будет ничего делать с этим свойством, поскольку не знает об этом.

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

Есть ли способ определить свойство только для чтения? Прямо сейчас мы используем C # /. NET 2.0 для веб-службы, и (по крайней мере, на данный момент) мы контролируем всех потребителей этой службы, поэтому я могу попробовать изменить конфигурации при необходимости, но я предпочитаю только изменять вещи в веб-сервисе, а не потребители.

Ответы [ 3 ]

3 голосов
/ 27 мая 2009

Я могу ошибаться, но я думаю, что проблема здесь в том, как работает сериализация - чтобы десериализовать объект, сериализатор создает пустой объект и затем устанавливает все свойства для этого объекта - поэтому вам нужен установщик для свойств быть включенным в сериализацию. Код клиента имеет тот же «интерфейс» к объекту, что и десериализатор.

1 голос
/ 27 мая 2009

Предостережение, я парень по Java, поэтому первая часть моего ответа посвящена тому, что возможно в C #.

Во-первых, с помощью настраиваемого сериализатора в Java вы можете делать практически все, что захотите, включая непосредственную установку значений защищенного или частного поля с использованием отражения, если диспетчер безопасности не предотвращает эту операцию. Я не знаю, есть ли в C # аналогичные компоненты для менеджера безопасности, доступа к полям и пользовательских сериализаторов, но я подозреваю, что они есть.

Во-вторых, я думаю, что есть фундаментальная разница в том, как вы просматриваете веб-сервисы и интерфейс веб-сервисов как часть вашего приложения. Вы щелкаете правой кнопкой мыши, генерируя интерфейс веб-службы из существующего кода, известного как «сначала код». Есть много статей о том, почему WSDL сначала является предпочтительным подходом. Этот достаточно хорошо суммирует, но я бы рекомендовал прочитать и другие. Хотя вы думаете с точки зрения библиотеки общего кода между клиентской и серверной сторонами вашего веб-сервиса и сохранением структуры и доступности объектов, такой гарантии нет, если вы публикуете API как веб-сервис и не имеете контроля над ним. все потребители. WSDL и XSD служат общим описанием вашего API веб-службы, а ваш сервер и клиент могут быть реализованы с использованием различных конфигураций привязки данных, классов объектов или языков. Вы должны думать об интерфейсе вашего веб-сервиса и о XML, который вы передаете и выводите из него, как описание семантики обмена, но не обязательно синтаксиса данных (структуры вашего класса), как только они интернализуются (десериализуются) в вашем клиенте или сервер.

Кроме того, рекомендуется отделить структуры, связанные с транспортом, от внутренних структур бизнес-логики, чтобы вам не пришлось одновременно проводить рефакторинг как реализации вашего сервера, API веб-службы, так и ваших (и других) клиентских реализаций. .

0 голосов
/ 01 июня 2009

Насколько я знаю, в .NET 2.0 нет встроенного способа сделать это. В тех случаях, когда я хотел сериализовать свойство только для чтения, я реализовывал интерфейс IXmlSerializable, чтобы можно было управлять методами ReadXml() и WriteXml().

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

...