wcf第3步之报文分析及原生调用
最简单的调用当然是服务引用,但是我更想原生调用,所以希望能通过报文有如下研究
1.报文分析
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="DemoService" targetNamespace="http://tempuri.org/"> <wsdl:types> <xsd:schema targetNamespace="http://tempuri.org/Imports"> <xsd:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd0" namespace="http://tempuri.org/"/> <xsd:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/> <xsd:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/Contracts.Models.Demo"/> <xsd:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/DataTypes"/> <xsd:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd4" namespace="http://schemas.datacontract.org/2004/07/System"/> </xsd:schema> </wsdl:types> <wsdl:message name="IDemoService_DoSomething_InputMessage"> <wsdl:part name="parameters" element="tns:DoSomething"/> </wsdl:message> <wsdl:message name="IDemoService_DoSomething_OutputMessage"> <wsdl:part name="parameters" element="tns:DoSomethingResponse"/> </wsdl:message> <wsdl:portType name="IDemoService"> <wsdl:operation name="DoSomething"> <wsdl:input wsaw:Action="http://tempuri.org/IDemoService/DoSomething" message="tns:IDemoService_DoSomething_InputMessage"/> <wsdl:output wsaw:Action="http://tempuri.org/IDemoService/DoSomethingResponse" message="tns:IDemoService_DoSomething_OutputMessage"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="BasicHttpBinding_IDemoService" type="tns:IDemoService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="DoSomething"> <soap:operation soapAction="http://tempuri.org/IDemoService/DoSomething" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="DemoService"> <wsdl:port name="BasicHttpBinding_IDemoService" binding="tns:BasicHttpBinding_IDemoService"> <soap:address location="http://dev.xxx.io/Demo/DemoService.svc"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
可以看到
1.wcf服务地址
http://dev.xxx.io/Demo/DemoService.svc
2.引用了4个命名空间
Serialization
Contracts.Models.Demo
DataTypes
System
3.Service的名称及接口
DemoService,
IDemoService
4.服务接口的方法
DoSomething
再访问
来读取类型的具体字段
http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd3
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/DataTypes" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/DataTypes"> <xs:complexType name="Request"> <xs:sequence> <xs:element minOccurs="0" name="UserId" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:element name="Request" nillable="true" type="tns:Request"/> <xs:complexType name="Response"> <xs:sequence> <xs:element minOccurs="0" name="ErrorCode" type="xs:int"/> <xs:element minOccurs="0" name="Message" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="Success" type="xs:boolean"/> </xs:sequence> </xs:complexType> <xs:element name="Response" nillable="true" type="tns:Response"/> </xs:schema>
http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd0
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/"> <xs:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/Contracts.Models.Demo"/> <xs:element name="DoSomething"> <xs:complexType> <xs:sequence> <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/Contracts.Models.Demo" minOccurs="0" name="request" nillable="true" type="q1:SomeReq"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="DoSomethingResponse"> <xs:complexType> <xs:sequence> <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/Contracts.Models.Demo" minOccurs="0" name="DoSomethingResult" nillable="true" type="q2:SomeResp"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd2
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/Contracts.Models.Demo" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/Contracts.Models.Demo"> <xs:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd4" namespace="http://schemas.datacontract.org/2004/07/System"/> <xs:import schemaLocation="http://dev.xxx.io/Demo/DemoService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/DataTypes"/> <xs:complexType name="SomeReq"> <xs:complexContent mixed="false"> <xs:extension xmlns:q1="http://schemas.datacontract.org/2004/07/DataTypes" base="q1:Request"> <xs:sequence> <xs:element minOccurs="0" name="Date" type="xs:dateTime"/> <xs:element xmlns:q2="http://schemas.datacontract.org/2004/07/System" minOccurs="0" name="DateUTC" type="q2:DateTimeOffset"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="SomeReq" nillable="true" type="tns:SomeReq"/> <xs:complexType name="SomeResp"> <xs:complexContent mixed="false"> <xs:extension xmlns:q3="http://schemas.datacontract.org/2004/07/WHTR.DataTypes" base="q3:Response"> <xs:sequence> <xs:element minOccurs="0" name="Date" type="xs:dateTime"/> <xs:element minOccurs="0" name="DateStr" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="ResultDate" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="ResultDateUTC" nillable="true" type="xs:string"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="SomeResp" nillable="true" type="tns:SomeResp"/> </xs:schema>
根据以上信息,可以生成的最简单的 Contract代码如下:
[Serializable] [DataContract(Name = "Response", Namespace = "http://schemas.datacontract.org/2004/07/DataType")] public class Response { [DataMember] public int ErrorCode { get; set; } [DataMember] public string Message { get; set; } [DataMember] public bool Success { get; set; } } /// <summary> /// SomeResponse /// </summary> [DataContract(Name = "SomeResp", Namespace = "http://schemas.datacontract.org/2004/07/DataType")] [Serializable] public sealed class SomeResp : Response { /// <summary> /// 时间格式的Date /// </summary> [DataMember] public DateTime Date { get; set; } /// <summary> /// 格式成字符串的时间 /// </summary> [DataMember] public string DateStr { get; set; } /// <summary> /// 返回传入的Date /// </summary> [DataMember] public string ResultDate { get; set; } /// <summary> /// 返回传入的Date /// </summary> [DataMember] public string ResultDateUTC { get; set; } } [Serializable] [DataContract(Name = "Request", Namespace = "http://schemas.datacontract.org/2004/07/Contracts.Models.Demo")] public class Request { [DataMember] public string UserId { get; set; } } /// <summary> /// SomeRequest /// </summary> [DataContract(Name = "SomeReq", Namespace = "http://schemas.datacontract.org/2004/07/Contracts.Models.Demo")] [Serializable] public sealed class SomeReq : Request { /// <summary> /// 时间 /// </summary> [DataMember] public DateTime Date { get; set; } /// <summary> /// Data /// </summary> [DataMember] public DateTimeOffset DateUTC { get; set; } } /// <summary> /// IDemoService /// </summary> [ServiceContract ] public interface IDemoService { /// <summary> /// Does something. /// </summary> /// <param name="request">The request.</param> /// <returns></returns> [OperationContract ] SomeResp DoSomething(SomeReq request); }
具体调用代码如下:
using System.Runtime.Serialization;
using System.ServiceModel;
EndpointAddress address = new EndpointAddress("http://dev.xxx.io/Demo/DemoService.svc?wsdl"); BasicHttpBinding binding = new BasicHttpBinding(); ChannelFactory<IDemoService> factory = new ChannelFactory<IDemoService>(binding, address); IDemoService channel = factory.CreateChannel(); var result = channel.DoSomething(new SomeReq() { Date = DateTime.Now });