Visual Studio и .NET Framework позволяют вам просмотреть Web-сервис внутри Web- браузера. Эта возможность полезна как для тестирования Web-сервиса, так и для исследования его работы (возвращаемых и требуемых им сообщений). Для доступа к Web- сервису вы сначала собираете (компилируете) его в Visual Studio, а затем запускаете asmx-файл в браузере.
На рис. 19.7 показан пример Web-сервиса CustomerProfile в окне браузера. Обратите внимание, что все методы сервиса перечислены. Показано также описание каждого метода. Это то самое описание, которое было указано в определении Web-метода (WebMethodAttribute).
Для того чтобы увидеть реальное формальное описание Web-сервиса на WSDL, вы можете выбрать ссылку Service Description в верхней части страницы (показана на рис. 19.7). Когда
вы нажмете эту ссылку, то внутри QueryString в asmx-файл будет передан параметр WSDL. Это дает указание ASP.NET вернуть WSDL сервиса.
WSDL будет сгенерирован. Он соответствует стандартам WSDL и поэтому может использоваться клиентами, которые хотят получить доступ к вашему сервису. Эти клиенты используют WSDL для того, чтобы понять, как работает ваш Web-сервис.
Примечание
.NET поставляется с инструментом Disco.exe. Visual Studio использует его для генерирования файлов, относящихся к обнаружению и пониманию \Л/еЬ-сервисов. Вы тоже можете запускать этот инструмент из командной строки для генерирования таких документов и сохранения их с целью последующего изучения и использования.
Создаваемые программой Disco.exe документы служат вводными данными для клиентских приложений, которые пользуются Web-сервисом. Эти клиентские приложения создаются при помощи инструмента WSDL.exe.
В листинге 19.4 вы можете увидеть полный WSDL для сервиса CustomerProfile. Этот листинг легче просматривать в браузере (где у вас будут цветовая кодировка и древовидная структура для перемещения по XML). Однако этот листинг приведен в справочных целях. При просмотре обратите внимание на описания всех сервисов. Обратите также внимание и на то, как сложный тип Customer встроен в WSDL. Этот сложный тип был сгенерирован на основе объекта Customer (BusinessEntities . Customer). Вспомним, что этот тип является возвращаемым значением для одного метода и параметром для другого. .NET преобразует все это в тип XML для использования в Web-сервисах.
<wsdl:definitions xmlns:soap="
xmlns:tns="
xmlns:soapl2="
xmlns:http="
targetNamespace="
xmlns:wsdl="http: //schemas .xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault=Mqualified"
targetNamespace="
<s:element name="GetCustomerProfile">
<s:complexType>
<s:sequence>
<s:element min0ccurs="0" тах0ссигз=и1и name="customerId"
type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetCustomerProfileResponse">
<s:complexType>
<s:sequence>
<s:element min0ccurs=,,0" maxOccurs=Hl"
name="GetCustomerProfileResult" type="tns:Customer" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="Customer'^
<s:sequence> '
<s:element min0ccurs="0" maxOccurs=,,l,, name="Id"
type="s:string" />
<s:element minOccurs=H0" maxOccurs="l" name="Name"
type="s:string" />
<s:element min0ccurs="0" maxOccurs="l" name="Email"
type="s:string" />
<s:element min0ccurs="0" maxOccurs="l" name="AddressLinel"
type="s:string" />
<s:element minOccurs="On maxOccurs="l" name="AddressLine2"
type="s:string" />
<s:element minOccurs="0" maxOccurs="l" name="City"
type="s:string" />
<s:element min0ccurs="0" maxOccurs="l" name="State"
type="s:string" />
<s:element minOccurs=nO" maxOccurs="l" name="PostalCode"
type="s:string" />
<s:element min0ccurs="0" maxOccurs="l" name="Phone"
type="s:string" />
<s:element minOccurs="l" maxOccurs="l" name="ContactEmail"
type="s-.boolean" />
<s:element minOccurs="l" maxOccurs="l" name="ContactPhone"
type="s:boolean" />
</s:sequence>
</s:complexType>
<s:element name="SaveCustomerM>
<s:complexType>
<s:sequence>
<s:element min0ccurs="0" maxOccurs="l" name="customer"
type="tns:Customer" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="SaveCustomerResponse">
<s:complexType />
</s:element>
<s:element name="DeleteCustomer">
<s:complexType>
<s:sequence>
<s:element min0ccurs="0" maxOccurs="l" name="customerId"
type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="DeleteCustomerResponse">
<s:complexType />
</s:element>
</s:schema>
</wsdl:types>
<wsdlimessage name="GetCustomerProfileSoapIn">
<wsdl:part name="parameters" element="tns:GetCustomerProfile" /> </wsdl:message>
<wsdl:message name=,rGetCustomerProfileSoapOutM>
<wsdl:part name="parameters"
element="tns:GetCustomerProfileResponse"/>
</wsdl:message>
<wsdlrmessage name="SaveCustomerSoapIn">
<wsdl:part name="parameters" element="tns:SaveCustomer" />
</wsdl:message>
<wsdlrmessage name="SaveCustomerSoapOut">
<wsdl:part name="parameters" element="tns:SaveCustomerResponse" /> </wsdl:message>
<wsdlrmessage name="DeleteCustomerSoapIn">
<wsdl:part name="parameters" element="tns:DeleteCustomer" />
</wsdl:message>
<wsdlimessage name="DeleteCustomerSoapOut">
<wsdl:part name="parameters" element="tns:DeleteCustomerResponse" /> </wsdl:message>
<wsdl:portType name="CustomerProfileSoap">
<wsdl:operation name="GetCustomerProfile">
<wsdl:documentation xmlns:wsdl=
"
<wsdl:output message="tns:GetCustomerProfileSoapOut" />
</wsdl:operation>
<wsdl:operation name="SaveCustomer">
<wsdl:documentation xmlns:wsdl=
"
<wsdl:input message="tns:SaveCustomerSoapIn" />
<wsdl:output message="tns:SaveCustomerSoapOut" />
</wsdl:operation>
<wsdl:operation name="DeleteCustomer">
<wsdl:documentation xmlns:wsdl=
"
<wsdl:input message="tns:DeleteCustomerSoapIn" />
<wsdl:output message="tns:DeleteCustomerSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CustomerProfileSoap"
type="tns:CustomerProfileSoap">
<soap:binding transport="
<soap:operation soapAction="
style=MdocumentM />
<wsdl:input>
<soap:body use="literaln />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SaveCustomer">
<soap:operation soapAction="
style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literalM />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name=MDeleteCustomer">
<soap:operation soapAction="
style="documentn />
<wsdl:input>
<soap:body use="literaln />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="CustomerProfileSoapl2"
type="tns:CustomerProfileSoap">
<soapl2:binding transport="
<soapl2:operation soapAction=
"
<soapl2:body use="literal" />
</wsdl:input>
<wsdl:output>
<soapl2:body use=MliteralM />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SaveCustomer">
<soapl2:operation soapAction="
style="document" />
<wsdl:input>
<soapl2:body use="literal" />
</wsdl:input>
<wsdl:output>
<soapl2:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DeleteCustomer">
<soapl2:operation soapAction="
style="document" />
<wsdl:input>
<soapl2:body use="literal" />
</wsdl:input>
<wsdl:output>
<soapl2:body use="literal" />
</wsdl:output>
* </wsdl:operation>
</wsdl:binding>
<wsdl:service name="CustomerProfile">
<wsdl:port name="CustomerProfileSoap"
binding="tns:CustomerProfileSoap">
<soap:address location="
<wsdl:port name="CustomerProfileSoapl2"
binding="tns:CustomerProfileSoapl2">
<soapl2:address location=
"
</wsdl:port>
</wsdl:service>
</wsdl:definitions>