1.环境win7 64位,vs2010
2.新建一个asp.net web应用程序
3.右键项目添加一个web服务
4.程序本来就有一个helloworld方法,现在添加一个自定义的方法,,如下CarMoveRequest
[WebMethod]
public Car CarMoveRequest(string Name, int X, int Y )
{
Car car = new Car();
car.Name = Name;
car.X = 8;
car.Y = 12;
return car;
}
其中Car是一个类,具体见后面
5.在vs上测试:按debug按钮,执行道如下页面
执行之后是如下结果
6.使用soapui测试
需要先生成wsdl文件才能导入给soapui,soapui会分析wsdl文件提取出消息,才能测试
在浏览器里面输入 http://localhost:55278/WebService1.asmx?wsdl,会得到wsdl的文件,右键查看源代码然后复制内容保存为wsdl文件即可
7.使用soapui打开ws.wsdl,此时需要保持webservce服务在线才能正常打开
8.解析ws.wsdl
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="HelloWorld">
<s:complexType />
</s:element>
<s:element name="HelloWorldResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CarMoveRequest">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="X" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Y" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CarMoveRequestResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="CarMoveRequestResult" type="tns:Car" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="Car">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="X" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Y" type="s:int" />
</s:sequence>
</s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="HelloWorldSoapIn">
<wsdl:part name="parameters" element="tns:HelloWorld" />
</wsdl:message>
<wsdl:message name="HelloWorldSoapOut">
<wsdl:part name="parameters" element="tns:HelloWorldResponse" />
</wsdl:message>
<wsdl:message name="CarMoveRequestSoapIn">
<wsdl:part name="parameters" element="tns:CarMoveRequest" />
</wsdl:message>
<wsdl:message name="CarMoveRequestSoapOut">
<wsdl:part name="parameters" element="tns:CarMoveRequestResponse" />
</wsdl:message>
<wsdl:portType name="WebService1Soap">
<wsdl:operation name="HelloWorld">
<wsdl:input message="tns:HelloWorldSoapIn" />
<wsdl:output message="tns:HelloWorldSoapOut" />
</wsdl:operation>
<wsdl:operation name="CarMoveRequest">
<wsdl:input message="tns:CarMoveRequestSoapIn" />
<wsdl:output message="tns:CarMoveRequestSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WebService1Soap" type="tns:WebService1Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="HelloWorld">
<soap:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CarMoveRequest">
<soap:operation soapAction="http://tempuri.org/CarMoveRequest" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="WebService1Soap12" type="tns:WebService1Soap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="HelloWorld">
<soap12:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CarMoveRequest">
<soap12:operation soapAction="http://tempuri.org/CarMoveRequest" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WebService1">
<wsdl:port name="WebService1Soap" binding="tns:WebService1Soap">
<soap:address location="http://localhost:55278/WebService1.asmx" />
</wsdl:port>
<wsdl:port name="WebService1Soap12" binding="tns:WebService1Soap12">
<soap12:address location="http://localhost:55278/WebService1.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
从最下面的wsdl:service节看起,定义了两个ws服务,用两个wsdl:port节来表示对,名字分别是WebService1Soap和WebService1Soap12,和soapui的右侧解析出来的两个ws服务的名字一致,并且指示了每个ws的连接地址和端口
再看binding,
binding 元素有两个属性 - name 属性和 type 属性。
name 属性定义 binding 的名称,而 type 属性指向用于 binding 的端口,在这个例子中是 "glossaryTerms" 端口。
soap:binding 元素有两个属性 - style 属性和 transport 属性。
style 属性可取值 "rpc" 或 "document"。在这个例子中我们使用 document。transport 属性定义了要使用的 SOAP 协议。在这个例子中我们使用 HTTP。
operation 元素定义了每个端口提供的操作符。
对于每个操作,相应的 SOAP 行为都需要被定义。同时您必须如何对输入和输出进行编码。在这个例子中我们使用了 "literal"。
再看port,port里面指定了操作operation,WSDL 定义了四种操作类型:
类型 定义
One-way 此操作可接受消息,但不会返回响应。
Request-response 此操作可接受一个请求并会返回一个响应,是最常见的,本例即是
Solicit-response 此操作可发送一个请求,并会等待一个响应。
Notification 此操作可发送一条消息,但不会等待响应。
所以每个operation节里面要么含有一个消息(比如One-way类型的操作),要么含有两个消息(比如Request-response类型的操作)
本例中的操作CarMoveRequest是Request-response 类型的操作(operation的类型哪里设置的?),所以operation节里面包含两个message。而这个operation节里面的每个message,在上面都会有顶层wsdl:message节来详细这个消息在实际传输xml中叫什么名字----用这个顶层wsdl:message节里面的element来指示
再看types,在types里面的每一个element节都会与一个顶层的wsdl:message节的element节相对应,用来具体描述这条message参数
通过types就可以构造要发送的消息名和参数,和应回应的的消息名和参数
从图中,看出来基本一致,但是soapui发出的消息里面都有一个tem:前缀,这是什么东东?
原来这是命名空间,在wsdl文件中的开头部分有定义的,用targetNamespace来指定。soapui解析出来这个targetNamespace,然后再发送消息的时候直接给挂在各个元素前面了,如下
9.使用socket调试工具模拟发送webservice帧,
可以把c#那个页面的的示例代码改改参数和长度值,直接发给webservice即可
也可以用soapui里面的raw和xml的信息作为请求信息一块发给webservice (需要稍微修改一下soapui的POST后面的地址信息)