Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В примере QueryStringFormatter показано, как точки расширяемости Windows Communication Foundation (WCF) можно использовать для разрешения данных сообщений в другом формате, отличном от ожидаемого WCF. По умолчанию методы форматирования WCF ожидают, что параметры метода будут включены в soap:body элемент. В примере показано, как реализовать настраиваемый форматировщик операций, который вместо этого анализирует данные параметров из строки запроса HTTP GET и вызывает методы, используя эти данные.
Пример основан на руководстве по началу работы, которое реализует ICalculator контракт службы. В нем показано, как можно изменить сообщения "Добавить", "Вычитать", "Умножение" и "Деление" для использования HTTP GET для запросов между клиентами и HTTP POST с сообщениями POX для ответов типа "сервер — клиент".
Для этого в примере приведено следующее:
QueryStringFormatter, который реализует IClientMessageFormatter для клиента и IDispatchMessageFormatter для сервера, и обрабатывает данные в строке запроса.UriOperationSelector, реализующий IDispatchOperationSelector на сервере для отправки операций на основе имени операции в запросе GET.EnableHttpGetRequestsBehaviorПоведение конечной точки (и соответствующая конфигурация), которая добавляет необходимый селектор операций в среду выполнения.Показывает, как вставить новый форматировщик операций в среду выполнения.
В этом примере клиент и служба являются консольными приложениями (.exe).
Замечание
Процедура установки и инструкции по сборке для этого примера находятся в конце этого раздела.
Основные понятия
QueryStringFormatter — Средство форматирования операций — это компонент в WCF, отвечающий за преобразование сообщения в массив объектов параметров и массив объектов параметров в сообщение. Это делается на клиенте с помощью IClientMessageFormatter интерфейса и на сервере с интерфейсом IDispatchMessageFormatter . Эти интерфейсы позволяют пользователям получать сообщения запроса и ответа от методов Serialize и Deserialize.
В этом примере QueryStringFormatter реализует оба этих интерфейса и реализуется на клиенте и сервере.
Запрос:
В данном примере класс TypeConverter используется для преобразования параметров сообщения запроса в строки и обратно. Если TypeConverter недоступен для определенного типа, форматировщик образца выбрасывает исключение.
В клиентском методе
IClientMessageFormatter.SerializeRequestформатирующий компонент создает URI с соответствующим адресом To и добавляет имя операции в качестве суффикса. Это имя используется для перенаправления к соответствующей операции на сервере. Затем он принимает массив объектов параметров и сериализует данные параметра в строку запроса URI с помощью имен параметров и значений, преобразованных классом TypeConverter . Параметры To и Via затем задаются этому универсальному коду ресурса (URI). MessageProperties доступен через свойство Properties.На сервере в методе
IDispatchMessageFormatter.DeserializeRequestформатировщик извлекаетViaURI в свойствах входящего сообщения запроса. Он анализирует пары "имя-значение" в строке URI-запроса, извлекая имена параметров и значения, и использует их для заполнения массива параметров, переданных в метод. Обратите внимание, что диспетчеризация операций уже произошла, поэтому суффикс имени операции игнорируется в этом методе.
Ответ:
- В этом примере HTTP GET используется только для запроса. Модуль форматирования делегирует отправку ответа исходному средству форматирования, который использовался бы для создания XML-сообщения. Одна из целей этого примера заключается в том, чтобы показать, как может быть реализован делегирующий форматтер.
Класс UriPathSuffixOperationSelector
Интерфейс IDispatchOperationSelector позволяет пользователям реализовать собственную логику для того, какое сообщение должно быть отправлено на выполнение определенной операции.
В этом примере UriPathSuffixOperationSelector должно быть реализовано на сервере, чтобы выбрать соответствующую операцию, так как имя операции включено в URI HTTP GET, а не в заголовке действия в сообщении. Образец настроен так, чтобы разрешать только имена операций, не учитывающие регистр.
Метод SelectOperation принимает входящее сообщение и ищет Via URI в его свойствах сообщения. Он извлекает суффикс имени операции из URI, ищет внутреннюю таблицу, чтобы получить имя операции, в которую должно быть отправлено сообщение, и возвращает это имя операции.
Класс EnableHttpGetRequestsBehavior
Компонент UriPathSuffixOperationSelector можно настроить программным способом или с помощью поведения конечной точки. Пример реализует EnableHttpGetRequestsBehavior поведение, указанное в файле конфигурации приложения службы.
На сервере:
Для OperationSelector реализации задано IDispatchOperationSelector значение.
По умолчанию WCF использует фильтр адресов точного соответствия. URI для входящего сообщения содержит суффикс имени операции, за которым следует строка запроса, содержащая данные параметров, поэтому поведение конечной точки также изменяет фильтр адресов, чтобы он был фильтром сопоставления префикса. Она использует WCFPrefixEndpointAddressMessageFilter для этой цели.
Установка модулей форматирования операций
Поведение операций, определяющее форматировщики, является уникальным. Одно такое поведение всегда реализуется по умолчанию для каждой операции, чтобы создать необходимый форматировщик операций. Однако эти действия выглядят как просто другое поведение операции; они не определяются любым другим атрибутом. Чтобы установить поведение замены, реализация должна искать определенные поведения форматирования, установленные загрузчиком типов WCF по умолчанию, и заменить его или добавить совместимое поведение для выполнения после поведения по умолчанию.
Эти форматировщики операций можно настроить программно перед вызовом CommunicationObject.Open или указав поведение операции, выполняемое после стандартного. Однако его нельзя легко настроить поведением конечной точки (и, следовательно, конфигурацией), так как модель поведения не разрешает поведение заменять другие поведения или изменять дерево описания.
На стороне клиента
Реализация IClientMessageFormatter должна быть выполнена таким образом, чтобы она могла преобразовать запросы в HTTP-запросы GET и делегировать их исходному средству форматирования ответов. Это делается путем вызова вспомогательного EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior метода.
Это необходимо сделать перед вызовом CreateChannel.
void ReplaceFormatterBehavior(OperationDescription operationDescription, EndpointAddress address)
{
// Remove the DataContract behavior if it is present.
IOperationBehavior formatterBehavior = operationDescription.Behaviors.Remove<DataContractSerializerOperationBehavior>();
if (formatterBehavior == null)
{
// Remove the XmlSerializer behavior if it is present.
formatterBehavior = operationDescription.Behaviors.Remove<XmlSerializerOperationBehavior>();
...
}
// Remember what the innerFormatterBehavior was.
DelegatingFormatterBehavior delegatingFormatterBehavior = new DelegatingFormatterBehavior(address);
delegatingFormatterBehavior.InnerFormatterBehavior = formatterBehavior;
operationDescription.Behaviors.Add(delegatingFormatterBehavior);
}
На сервере:
Интерфейс IDispatchMessageFormatter должен быть реализован таким образом, чтобы считывать HTTP-запросы GET и делегировать исходному форматировщику для записи ответов. Это делается путем вызова того же
EnableHttpGetRequestsBehavior.ReplaceFormatterBehaviorвспомогательного метода, что и клиент (см. предыдущий пример кода).Это необходимо сделать перед вызовом Open. В этом примере мы показываем, как форматтер изменяется вручную перед вызовом Open. Другой способ достичь той же цели — это создать класс, производный от ServiceHost, который вызывает
EnableHttpGetRequestsBehavior.ReplaceFormatterBehaviorперед открытием (см. документацию по хостингу и примеры).
Взаимодействие с пользователем
На сервере:
Реализация сервера
ICalculatorне требует изменения.App.config для службы должен использовать пользовательскую привязку POX, которая задает атрибут
messageVersionэлементаtextMessageEncodingв значениеNone.<bindings> <customBinding> <binding name="poxBinding"> <textMessageEncoding messageVersion="None" /> <httpTransport /> </binding> </customBinding> </bindings>Для службы App.config также необходимо указать настраиваемый
EnableHttpGetRequestsBehavior, добавив его в раздел расширений поведения и используйте его.<behaviors> <endpointBehaviors> <behavior name="enableHttpGetRequestsBehavior"> <enableHttpGetRequests /> </behavior> </endpointBehaviors> </behaviors> <extensions> <behaviorExtensions> <!-- Enabling HTTP GET requests: Behavior Extension --> <add name="enableHttpGetRequests" type="Microsoft.ServiceModel.Samples.EnableHttpGetRequestsBehaviorElement, QueryStringFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions>Добавьте форматировщики операций перед вызовом Open.
На стороне клиента
Реализация клиента не требует изменения.
App.config для клиента должен использовать пользовательскую привязку POX, которая устанавливает атрибут
messageVersionэлементаtextMessageEncodingвNone. Одно из различий от службы заключается в том, что клиент должен включить ручное адресование, чтобы в исходящем адресе 'To' можно было внести изменения.<bindings> <customBinding> <binding name="poxBinding"> <textMessageEncoding messageVersion="None" /> <httpTransport manualAddressing="True" /> </binding> </customBinding> </bindings>App.config для клиента должен указывать на тот же пользовательский параметр
EnableHttpGetRequestsBehavior, что и сервер.Добавьте форматировщики операций перед вызовом CreateChannel().
При запуске примера запросы и ответы операции отображаются в окне консоли клиента. Все четыре операции (добавление, вычитание, умножение и деление) должны выполняться успешно.
Настройка, сборка и запуск примера
Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.
Чтобы создать решение, следуйте инструкциям по созданию примеров Windows Communication Foundation.
Чтобы запустить пример в конфигурации с одним или несколькими компьютерами, следуйте инструкциям в запуска примеров Windows Communication Foundation.