Может быть Вы задавались вопросами что такое «WEB»?
А может быть тем что же такое «Интернет»? Без предвзятостей.
Ландж блог о четвертой среде обитания, найти ответы на многие вопросы...
«Почемучка», только об «Всемирной Паутине» и очень странная. :)
Многие знают о том, что SOAP-заголовки используются для размещения метаданных, относящихся к телу сообщения. Среда ASP.NET предоставляет механизм для определения и обработки SOAP-заголовков. В этом разделе объясняется, как формально определять SOAP-заголовки, которые предоставляются Web-сервисом ASP.NET . Здесь также показано, как обрабатывать SOAP-заголовки, полученные от клиента. Можно определить новый заголовок, который наследуется от класса SoapHeader. Этот заголовок связывается с определенной конечной точкой внутри Web-сервиса, используя атрибут. По умолчанию, классу, наследнику SoapHeader, присваивается имя корневого элемента заголовка и любые объявленные как public поля или свойства, предоставляемые классом, будут определять элементы внутри заголовка.
Многие знают такой момент, когда котировки цен, поступающие на Web от других сервисов, зачастую отстают по времени и предоставляются с двадцатиминутным запозданием. Котировки, полученные с помощью Web-метода instantQuote, не подвержены такому запаздыванию. Поскольку Web-метод instantQuote получает цену акции, по которой в настоящий момент осуществляются торги на бирже, то, по всей видимости, можно запрашивать с клиентов полтора доллара за каждую котировку. Таким образом, необходимо обеспечить, чтобы каждый SOAP-запрос к Web-методу instantQuote сопровождался SOAP-заголовком Payment, который содержит информацию о кредитной карте клиента. Эта информация будет использована для получения полутора долларов за транзакцию.SOAP-заголовки определяются классами, которые наследуются от класса SoapHeader. Элементы заголовка определяются общедоступными (public) полями или свойствами read/write.
Приведенное определение класса задает SOAP-заголовок с именем Payment и четырьмя дочерними элементами: nameOnCard, creditCardNumber, creditCardType И expirationDate. Атрибут XmlRoot используется ДЛЯ ТОГО, чтобы XML Serializer именовал элемент заголовка Payment, а не имя класса. После того как платежи получены и Web-метод выполнен, необходимо послать заголовок, содержащий подтверждение покупки, обратно клиенту. SOAP-заголовки, которые отправляются от сервера клиенту, определяются тем же способом. Следующий код описывает заголовок, который содержит размер оплаты, а также номер транзакции по кредитной карте. Как только заголовки определены, следующим шагом будет их ассоциирование с Web-методом instantQuote. Для этого используется атрибут SoapHeader. К классу webService добавлена переменная класса, декларированная как public, для хранения экземпляра класса, порожденного от класса SoapHeader. Имя этой переменной затем сообщается ASP.NET в атрибуте SoapHeader.
Далее приведено определение класса securities. Здесь созданы две переменные класса для хранения данных, содержащихся в SOAP-заголовках, - Payment (Платеж) и Receipt (Чек). Создан экземпляр класса soapReceiptHeader, так заголовок Receipt будет передаваться клиенту. Экземпляр класса SoapPaymentHeader не создается, т. к. за формирование этого объекта и заполнение его свойств данными, содержащимися в заголовке Payment, полученными от клиента, отвечает ASP.NET .Затем добавляются два атрибута SoapHeader для объявления, что заголовки должны быть явно описаны, как часть Web-метода. Конструктор атрибута soapHeader получает строку, содержащую имя (переменной класса, декларированной как public), которая должна быть ассоциирована с SOAP-загол обком.Вдобавок установлены два необязательных свойства: Direction (Направление) и Required (Обязательный). Свойство Direction показывает, кто предположительно посылает заголовок: клиент или сервер. Свойство Required показывает, должен ли заголовок входить в SOAP-сообщение.
Обсудим подробно каждое из этих свойств. Свойство Direction показывает, получено ли сообщение от клиента, послано ли оно клиенту, или то и другое вместе. Заголовок Payment получается от клиента, а заголовок Receipt посылается клиенту, поэтому свойство Direction ДЛЯ НИХ устанавливается в SoapHeaderDirection.In и в soapHeaderDirection.Out соответственно. Если SOAP-заголовок получен от клиента и затем возвращен ему, то значение свойства Direction должно устанавливаться в SoapHeaderDirection.InOut. Свойство Required показывает, должен ли заголовок включаться в SOAP-сообщение, рассматриваемое Web-сервисом как корректное (valid). Если свойство Required внутри тега attribute не установлено, то его значение по умолчанию true.
Входные заголовки, помеченные как обязательные, должны включаться в сообщение-запрос. В противном случае ASP.NET будет возбуждать исключение SoapException. Поскольку заголовок Payment должен включаться в каждый запрос, а соответствующий заголовок Receipt в каждый ответ, то свойство Required установлено равным true для обоих SOAP-заголовков. Свойство Required не связано с обработкой заголовка получателем сообщения и даже его распознаванием. Например, заголовок Receipt должен всегда возвращаться клиенту, но от клиента не требуется обработки этого заголовка.
Теперь следует ассоциировать заголовки Payment и Receipt с Web-методом, далее необходимо будет обработать заголовки Payment. Следующий код использует информацию в заголовке Payment, чтобы выставить счет на клиентскую кредитную карточку, используя любой компонент обработки кредитной карты. Приведенный код использует информацию заголовка Payment, для получения платы с кредитной карточки клиента. Если кредитная карта успешно обработана, заголовок Receipt будет заполнен соответствующим номером транзакции, а также размером платежа по данной кредитной карте. Если кредитная карта обработана некорректно, то возбуждается исключение SoapException.
Поскольку исключение - это результат получения некорректной информации от клиента, коду ошибки присваивается значениеClient. Такая реализация имеет одну проблему, относящуюся к обработке заголовков. Нужно отметить, что клиент имеет возможность посылать дополнительные заголовки, отличные от ожидаемых. В этих дополнительных заголовках клиент может к тому же установить атрибут mustunderstand равным true. В дальнейшем будет вкратце рассказано, как обрабатывать такие дополнительные заголовки. Но, прежде всего, необходимо обсудить установку и анализ атрибута mustunderstand для отдельного SOAP-сообщения.
Свойство Mustunderstand, предоставляемое классом SoapHeader, в корне отличается от свойства Required, установленного атрибутом SoapHeader. Свойство Required определяет, должен ли заголовок включаться в сообщение. Если заголовок помещен в сообщение, то свойство Mustunderstand используется, чтобы указать, должен ли получатель сообщения распознать и обработать заголовок.
Обсудим оба эти свойства подробно. Свойство Required определяет, должен ли заголовок включаться в сообщение обмена между клиентом и сервером для определенного Web-метода. Так как это свойство специфично для интерфейса Web-сервиса, то изменения в нем отражаются в WSDL-документе. Если свойство Required принимает значение true, то атрибут required элемента header, определенного элементами расширения SOAP-связывания, будет установлен равным true. Наконец, если Web-метод определяет SOAP-заголовок как обязательный (required), то ASP.NET не сможет поддерживать связывания HTTP GET/POST. Свойство Mustunderstand устанавливает, должен ли определенный заголовок в сообщении быть распознан и обработан клиентом. Поскольку это свойство специфично для конкретнрго обмена между клиентом и сервером, то изменения в нем отражаются и в самом SOAP-сообщении. Если свойство Mustunderstand имеет значение true, то атрибут mustunderstand в экземпляре заголовка будет также установлен равным true. Свойство Didunderstand объекта, унаследованное от SoapHeader, предлагает платформе ASP.NET сообщить клиенту, какие заголовки были обработаны Web-методом.
Для заголовков, явно определенных Web-методом, значение свойства Didunderstand по умолчанию - true, поэтому необходимо убедиться, что нет участков кода, в которых метод возвращается без обработки заголовков. Клиент может установить атрибут mustunderstand равным true. В таком случае, если Web-метод не возбуждает исключение SoapException, это рассматривается как ошибка. Если заголовок не обработан, можно установить значение свойства Didunderstand равным false в начале Web-метода. После того как заголовок обработан, свойству Didunderstand опять присваивается значение true.
Другой способ состоит в том, чтобы включить значение свойства Mustunderstand в принятие решения об обработке заголовка. Например, метод instantQuote устанавливает свойство Required заголовка Payment, равным true. Однако метод instantQuote отвечает за обработку заголовка только в том случае, если свойство Mustunderstand имеет значение true. Если, скажем, администратор инициирует Web-метод instantQuote, то заголовок Payment не должен обрабатываться, если свойство Mustunderstand не равно true, как в приводимом примере. Надо поставить еще одну, последнюю, точку в обсуждении свойств Mustunderstand и Didunderstand.
После возврата из Web-метода ASP.NET определит, содержат ли заголовки, посланные клиентом, атрибут mustunderstand со значением true, а также ассоциированное с ним свойство Didunderstand со значением false. В этом случае ASP.NET автоматически возбудит исключение SoapException. Web-метод должен содержать код, который попытается отменить действия со стороны клиента перед возбуждением исключения. Поскольку это исключение возбуждается после возврата из Web-метода, то этот код никогда не будет исполняться.
Скажем, клиент вызывает Web-метод instantQuote в контексте транзакции. Клиент передает заголовок Transaction вместе с заголовком Payment и устанавливает его атрибут mustunderstand равным true. Так как приведенная выше реализация не проверяет наличия заголовка Transaction, то Web-сервис обрабатывает запрос, включая выставление счета на кредитную карту клиента. После возврата из метода ASP.NET обнаруживает, что свойство Didunderstand заголовка Transaction установлено в false, и возбуждает исключение. В этом случае клиент не получает котировку, однако оплата в размере полтора доллара с клиента будет затребована. Такой сценарий, конечно, не устроит клиента.
Имеются, по крайней мере, два способа избежать этого неблагоприятного побочного эффекта. Если все задействованные ресурсы управляются менеджером ресурсов DTC, ТО можно установить свойство TransactionOption атрибута webMethod как Required. Как только ASP.NET возбуждает исключение, транзакция будет прервана и произведен откат всех изменений. Если компонент CreditCardProcessor может принимать участие в распределенной транзакции DTC, то платежи по данной кредитной карточке будут автоматически отменены. Другой вариант состоит в проверке того, что все заголовки, полученные Web-сервисом с атрибутом mustunderstand, равным true, обработаны перед возвратом из Web-метода. Перехваченные заголовки, которые должны быть распознаны, но перед этим не обрабатывались Web-сервисом в Web-методе, могут потенциально сохранять ненужные циклы обработки. Если Web-метод не знает, как обработать переданный ему заголовок, он может выбрать подходящее действие, перед тем как возбудить исключение.
Надеюсь, Вам было интересно!