|
WCF 的一切都是圍繞著 Message 進(jìn)行,那么 Message 究竟是什么樣子?
[ServiceContract]
public interface ICalculate { [OperationContract] double Add(double a, double b); } public class CalculateService : ICalculate { public double Add(double a, double b) { Message msg = OperationContext.Current.RequestContext.RequestMessage; Console.WriteLine(msg); return a + b; } } public class WcfTest { public static void Test() { AppDomain.CreateDomain("Server").DoCallBack(delegate { ServiceHost host = new ServiceHost(typeof(CalculateService)); host.AddServiceEndpoint(typeof(ICalculate), new BasicHttpBinding(), "http://localhost:8080/calc"); host.Open(); }); ChannelFactory<ICalculate> factory = new ChannelFactory<ICalculate>(new BasicHttpBinding(), "http://localhost:8080/calc"); ICalculate o = factory.CreateChannel(); Console.WriteLine(o.Add(1, 2)); } } 輸出 <s:Envelope xmlns:s="http://schemas./soap/envelope/">
<s:Header> <To s:mustUnderstand="1" xmlns="http://...">http://localhost:8080/calc</To> <Action s:mustUnderstand="1" xmlns="http://...">http:///ICalculate/Add</Action> </s:Header> <s:Body> <Add xmlns="http:///"> <a>1</a> <b>2</b> </Add> </s:Body> </s:Envelope> 事實(shí)上我們可以直接基于 Message Layer 進(jìn)行編程,利用 OperationContract.Action 捕獲特定 Action 的消息。 [ServiceContract]
public interface ICalculate { [OperationContract(Action = "Add", ReplyAction="Add")] Message ProcessMessage(Message m); } public class CalculateService : ICalculate { public Message ProcessMessage(Message m) { Data d = m.GetBody<Data>(); Console.WriteLine(d.I); return Message.CreateMessage(MessageVersion.Soap11, "Add", new Data(9999)); } } [DataContract] public class Data { [DataMember] public int I; public Data(int i) { this.I = i; } } public class WcfTest { public static void Test() { AppDomain.CreateDomain("Server").DoCallBack(delegate { ServiceHost host = new ServiceHost(typeof(CalculateService)); host.AddServiceEndpoint(typeof(ICalculate), new BasicHttpBinding(), "http://localhost:8080/calc"); host.Open(); }); ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>( new BasicHttpBinding(), "http://localhost:8080/calc"); IRequestChannel channel = factory.CreateChannel(); channel.Open(); Message request = Message.CreateMessage(MessageVersion.Soap11, "Add", new Data(1234)); Message reply = channel.Request(request); Console.WriteLine("-------------------"); Console.WriteLine(reply); channel.Close(); factory.Close(); } } 輸出: 1234
------------------- <s:Envelope xmlns:s="http://schemas./soap/envelope/"> <s:Header /> <s:Body> <Data xmlns="http://..." xmlns:i="http://..."> <I>9999</I> </Data> </s:Body> </s:Envelope> 正如上面所看到的,所有的調(diào)用都被轉(zhuǎn)換成消息后發(fā)送。這也符合 SOA 的規(guī)范,完全隔離,清晰的邊界。(調(diào)用 "m.GetBody<Data>()" 后,會(huì)導(dǎo)致 Message.State 變更,再次訪問會(huì)出錯(cuò),有關(guān)詳細(xì)信息請(qǐng)參考 MSDN 文檔。) 我們還可以使用 MessageContractAttribute / MessageHeaderAttribute 來控制消息格式,這比 DataContractAttribute 要更加靈活。我們可以設(shè)置消息標(biāo)頭、消息體,包括是否對(duì)其中某些進(jìn)行簽名和加密處理。 [ServiceContract]
public interface ICalculate { [OperationContract] void Add(Data d); } public class CalculateService : ICalculate { public void Add(Data d) { Console.WriteLine(OperationContext.Current.RequestContext.RequestMessage); Console.WriteLine("----------------"); Console.WriteLine("{0}/{1}", d.a, d.b); } } [MessageContract] public class Data { [MessageHeader] public double a = 1; [MessageBodyMember] public double b = 2; } public class WcfTest { public static void Test() { AppDomain.CreateDomain("Server").DoCallBack(delegate { ServiceHost host = new ServiceHost(typeof(CalculateService)); host.AddServiceEndpoint(typeof(ICalculate), new BasicHttpBinding(), "http://localhost:8080/calc"); host.Open(); }); ChannelFactory<ICalculate> factory = new ChannelFactory<ICalculate>(new BasicHttpBinding(), "http://localhost:8080/calc"); ICalculate o = factory.CreateChannel(); Data d = new Data(); d.a = 1234; d.b = 5678; o.Add(d); } } 輸出: <s:Envelope xmlns:s="http://schemas./soap/envelope/">
<s:Header> <h:a xmlns:h="http:///">1</h:a> <To s:mustUnderstand="1" xmlns="http://s...">http://localhost:8080/calc</To> <Action s:mustUnderstand="1" xmlns="http://...">http:///ICalculate/Add</Action> </s:Header> <s:Body> <Data xmlns="http:///"> <b>2</b> </Data> </s:Body> </s:Envelope> ---------------- 1234/5678 有關(guān) Message 更詳細(xì)的信息,可以參考 MSDN (Microsoft Windows SDK) 文檔。 |
|
|