-
Message类是WCF的基本类
- 客户端与服务之间的所有通信最终都会产生要进行发送和接收的Message实例
- 通常不会与Message类直接进行交互。相反,您需要使用WCF服务模型构造(如数据协定,消息协定和操作协定)来描述传入消息和传出消息。
- 在以下情况下可能需要使用Message类
- 需要一种替代方式来创建传出的消息内容(例如,从磁盘上的文件直接创建消息),而不是序列化.net framework对象。
- 需要一种替代方式来使传入的消息内容(例如,需要将XSLT转换应用于原始XML内容),而不是反序列化为.Net Framework对象。
- 无论消息内容怎样都需要使用常规方式来处理消息(例如,在生成路由器,负载平衡器或发布-订阅系统时对消息进行路由或转发)。
- 在操作中使用Messge类
- 创建简单消息
- Message类提供了静态的CreateMessage工厂方法
- 所有CreateMessage重载都采用一个类型为MessageVersion的版本参数,该参数指示要用于消息的SOAP和WS-Addressing版本,如果要使用与传入消息相同的协议版本,则可以使用OperationContext实例(从Current属性获取)上的IncomingMessageVersion属性。
- 大多数CreateMessage重载还具有一个字符串参数,该参数指示要用于消息的SOAP操作。
- 可以将版本设置为None以禁用SOAP信封生产。消息将仅包含正文。
server:
// Copyright (c) Microsoft Corporation. All Rights Reserved.
using System;
using System.Globalization; using System.ServiceModel.Channels; using System.IO; using System.ServiceModel; using System.Xml; using System.Runtime.Serialization; namespace Microsoft.ServiceModel.Samples { // Define a service contract. [ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")] public interface ICalculator { [OperationContract] double Add(double n1, double n2); [OperationContract] double Subtract(double n1, double n2); [OperationContract] double Multiply(double n1, double n2); [OperationContract] double Divide(double n1, double n2); [OperationContract] Message Sum(Message request); [OperationContract] Message GetFirst(); [OperationContract] Message GetData(); [OperationContract] Message GetDataStream(); [OperationContract] Message GetDataFault(); } // Service class which implements the service contract. public class CalculatorService : ICalculator { public double Add(double n1, double n2) { return n1 + n2; } public double Subtract(double n1, double n2) { return n1 - n2; } public double Multiply(double n1, double n2) { return n1 * n2; } public double Divide(double n1, double n2) { return n1 / n2; } //The Sum operation operates on the WCF Message object directly public Message Sum(Message request) { int sum = 0; string text = ""; //The body of the message contains a list of numbers which will be read directly using an XmlReader XmlReader body = request.GetReaderAtBodyContents(); while (body.Read()) { text = body.ReadString().Trim(); if (text.Length > 0) { sum += Convert.ToInt32(text,CultureInfo.InvariantCulture); } } body.Close(); Message response = Message.CreateMessage(request.Version, "http://Microsoft.ServiceModel.Samples/ICalculator/SumResponse", sum); return response; } public Message GetFirst() { MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://Microsoft.ServiceModel.Samples/ICalculator/GetFirstResponse"); } public Message GetData() { Person p = new Person(); p.name = "wang"; p.age = 20; MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://Microsoft.ServiceModel.Samples/ICalculator/GetDataResponse", p); } public Message GetDataStream() { FileStream stream = new FileStream(@"C:\myfile.xml", FileMode.Open); XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "http://Microsoft.ServiceModel.Samples/ICalculator/GetDataStreamResponse", xdr); } public Message GetDataFault() { FaultCode fc = new FaultCode("Receiver"); MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, fc, "Bad data", "http://Microsoft.ServiceModel.Samples/ICalculator/GetDataFaultResponse"); } } [MessageContract] public class Person { [MessageBodyMember] public string name; [MessageBodyMember] public int age; } }
clientcode:
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:2.0.50727.4952 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="ICalculator")] public interface ICalculator { [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")] double Add(double n1, double n2); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")] double Subtract(double n1, double n2); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")] double Multiply(double n1, double n2); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")] double Divide(double n1, double n2); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Sum", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SumResponse")] System.ServiceModel.Channels.Message Sum(System.ServiceModel.Channels.Message request); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/GetFirst", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/GetFirstResponse")] System.ServiceModel.Channels.Message GetFirst(); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/GetData", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/GetDataResponse")] System.ServiceModel.Channels.Message GetData(); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/GetDataStream", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/GetDataStreamResponse")] System.ServiceModel.Channels.Message GetDataStream(); [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/GetDataFault", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/GetDataFaultResponse")] System.ServiceModel.Channels.Message GetDataFault(); } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public interface ICalculatorChannel : ICalculator, System.ServiceModel.IClientChannel { } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class CalculatorClient : System.ServiceModel.ClientBase<ICalculator>, ICalculator { public CalculatorClient() { } public CalculatorClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public CalculatorClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public double Add(double n1, double n2) { return base.Channel.Add(n1, n2); } public double Subtract(double n1, double n2) { return base.Channel.Subtract(n1, n2); } public double Multiply(double n1, double n2) { return base.Channel.Multiply(n1, n2); } public double Divide(double n1, double n2) { return base.Channel.Divide(n1, n2); } public System.ServiceModel.Channels.Message Sum(System.ServiceModel.Channels.Message request) { return base.Channel.Sum(request); } public System.ServiceModel.Channels.Message GetFirst() { return base.Channel.GetFirst(); } public System.ServiceModel.Channels.Message GetData() { return base.Channel.GetData(); } public System.ServiceModel.Channels.Message GetDataStream() { return base.Channel.GetDataStream(); } public System.ServiceModel.Channels.Message GetDataFault() { return base.Channel.GetDataFault(); } }
client:
// Copyright (c) Microsoft Corporation. All Rights Reserved. using System; using System.Globalization; using System.ServiceModel.Channels; using System.ServiceModel; using System.Xml; using System.IO; using System.Text; namespace Microsoft.ServiceModel.Samples { //The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool. [MessageContract] public class Person { [MessageBodyMember] public string name; [MessageBodyMember] public int age; } //Client implementation code. class Client { static void Main() { // Create a client CalculatorClient client = new CalculatorClient(); // Call the Add service operation. double value1 = 100.00D; double value2 = 15.99D; double result = client.Add(value1, value2); Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result); // Call the Subtract service operation. value1 = 145.00D; value2 = 76.54D; result = client.Subtract(value1, value2); Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result); // Call the Multiply service operation. value1 = 9.00D; value2 = 81.25D; result = client.Multiply(value1, value2); Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result); // Call the Divide service operation. value1 = 22.00D; value2 = 7.00D; result = client.Divide(value1, value2); Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result); // Call the Sum service operation. int[] values = { 1, 2, 3, 4, 5 }; using (new OperationContextScope(client.InnerChannel)) { Message request = Message.CreateMessage(OperationContext.Current.OutgoingMessageHeaders.MessageVersion, "http://Microsoft.ServiceModel.Samples/ICalculator/Sum", values); //Console.WriteLine(request.ToString()); Message reply = client.Sum(request); //Console.WriteLine(reply.ToString()); int sum = reply.GetBody<int>(); Console.WriteLine("Sum(1,2,3,4,5) = {0}", sum); // demo 1 //Message Reply1 = client.GetFirst(); //Console.WriteLine(Reply1.ToString()); // demo 2 //Message reply1 = client.GetData(); //Console.WriteLine(reply1.ToString()); //Person p = reply1.GetBody<Person>(); //Console.WriteLine(p.name + " " + p.age.ToString()); // demo 3 //Message reply1 = client.GetDataStream(); //Console.WriteLine(reply1.ToString()); //FileStream stream = new FileStream(@"c:\log.xml", FileMode.Create); //XmlDictionaryWriter xdw = // XmlDictionaryWriter.CreateTextWriter(stream); ////reply1.WriteBodyContents(xdw); ////reply1.WriteBody(xdw); //reply1.WriteMessage(xdw); //xdw.Flush(); // demo 4 //try //{ // Message reply1 = client.GetDataFault(); // Console.WriteLine(reply1.ToString()); //} //catch (FaultException e) //{ // Console.WriteLine(e.ToString()); //} // demo 5 //Message reply1 = client.GetDataStream(); ////Copy the message to a buffer. //MessageBuffer mb = reply1.CreateBufferedCopy(65536); ////Log to a file. //FileStream stream = new FileStream(@"C:\log.xml", FileMode.Append); //mb.WriteMessage(stream); //stream.Flush(); // demo 6 Message reply1 = client.GetData(); Console.WriteLine(reply1.ToString()); foreach (MessageHeaderInfo mhi in reply1.Headers) { Console.WriteLine(mhi.Name); } } //Closing the client gracefully closes the connection and cleans up resources client.Close(); Console.WriteLine(); Console.WriteLine("Press <ENTER> to terminate client."); Console.ReadLine(); } } }