作用:使用消息头向服务发送额外的信息。
1.客户端代码如下:
1 namespace Client 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 CalculatorClient client = new CalculatorClient("secure"); 8 double n1 = 5.6; 9 double n2 = 7.3; 10 double result; 11 12 result = client.Add(n2, n1); 13 Console.WriteLine("执行加法后的结果为:{0}", result.ToString()); 14 15 result = client.Subtract(n2, n1); 16 Console.WriteLine("执行减法后的结果为:{0}", result.ToString()); 17 18 result = client.Multiply(n1, n2); 19 Console.WriteLine("执行乘法后的结果为:{0}", result.ToString()); 20 21 result = client.Divide(n1, n2); 22 Console.WriteLine("执行除法后的结果为:{0}", result.ToString()); 23 24 //CalculatorSessionClient clientSeesion = new CalculatorSessionClient(); 25 //string s = clientSeesion.test("你好我做一个测试!"); 26 //string b = clientSeesion.GetServiceDescriptionInfo(); 27 //Console.WriteLine(s); 28 //Console.WriteLine(b); 29 30 Test(); 31 32 } 33 34 static void Test() 35 { 36 CalculatorSessionClient wcfClient = new CalculatorSessionClient(); 37 try 38 { 39 using (OperationContextScope scope = new OperationContextScope(wcfClient.InnerChannel)) 40 { 41 MessageHeader header 42 = MessageHeader.CreateHeader( 43 "Service-Bound-CustomHeader", 44 "http://Microsoft.WCF.Documentation", 45 "Custom Happy Value." 46 ); 47 OperationContext.Current.OutgoingMessageHeaders.Add(header); 48 49 // Making calls. 50 Console.WriteLine("Enter the greeting to send: "); 51 string greeting = Console.ReadLine(); 52 53 //Console.ReadLine(); 54 header = MessageHeader.CreateHeader( 55 "Service-Bound-OneWayHeader", 56 "http://Microsoft.WCF.Documentation", 57 "Different Happy Value." 58 ); 59 OperationContext.Current.OutgoingMessageHeaders.Add(header);//TODO:自定义传出消息头的用处? 60 61 // One-way 62 wcfClient.test(greeting); 63 64 65 // Done with service. 66 wcfClient.Close(); 67 Console.WriteLine("Done!"); 68 Console.ReadLine(); 69 } 70 } 71 catch (TimeoutException timeProblem) 72 { 73 Console.WriteLine("The service operation timed out. " + timeProblem.Message); 74 Console.ReadLine(); 75 wcfClient.Abort(); 76 } 77 catch (CommunicationException commProblem) 78 { 79 Console.WriteLine("There was a communication problem. " + commProblem.Message); 80 Console.ReadLine(); 81 wcfClient.Abort(); 82 } 83 84 } 85 } 86 }
2.服务端代码:
1 namespace Microsoft.ServiceModel.Samples 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 //创建一个ServiceHost 8 using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService))) 9 { 10 // Open the ServiceHost to create listeners 11 serviceHost.Open(); 12 Console.WriteLine("服务已经开启!"); 13 Console.WriteLine("按回车键结束服务!"); 14 Console.WriteLine(); 15 Console.ReadLine(); 16 17 serviceHost.Close(); 18 19 } 20 } 21 22 } 23 [ServiceContract]//定义服务协定完成 24 public interface ICalculator 25 { 26 [OperationContract] 27 double Add(double n1, double n2); 28 [OperationContract] 29 double Subtract(double n1, double n2); 30 [OperationContract] 31 double Multiply(double n1, double n2); 32 [OperationContract] 33 double Divide(double n1, double n2); 34 } 35 36 [ServiceContract] 37 public interface ICalculatorSession 38 { 39 [OperationContract] 40 string test(string s); 41 42 [OperationContract] 43 string GetServiceDescriptionInfo(); 44 } 45 46 public class CalculatorService : ICalculator, ICalculatorSession 47 { 48 public double Add(double n1, double n2) 49 { 50 return n1 + n2; 51 } 52 53 public double Subtract(double n1, double n2) 54 { 55 return n1 - n2; 56 } 57 58 public double Multiply(double n1, double n2) 59 { 60 return n1 * n2; 61 } 62 63 public double Divide(double n1, double n2) 64 { 65 return n1 / n2; 66 } 67 68 public string test(string s) 69 { 70 Console.WriteLine("Service Said" + s); 71 WriteHeaders(OperationContext.Current.IncomingMessageHeaders); 72 return s; 73 } 74 75 public string GetServiceDescriptionInfo() 76 { 77 StringBuilder sb = new StringBuilder(); 78 OperationContext operationContext = OperationContext.Current; 79 ServiceHost serviceHost = (ServiceHost)operationContext.Host; 80 ServiceDescription dec = serviceHost.Description; 81 sb.Append("Base addresses:\n"); 82 foreach (Uri url in serviceHost.BaseAddresses) 83 { 84 sb.Append(" " + url + "\n"); 85 } 86 sb.Append("Service endpoint:\n"); 87 foreach (ServiceEndpoint endPoint in dec.Endpoints) 88 { 89 sb.Append("Address:" + endPoint.Address + "\n"); 90 sb.Append("Binding:" + endPoint.Binding + "\n"); 91 sb.Append("Contract:" + endPoint.Contract + "\n"); 92 } 93 94 return sb.ToString(); 95 } 96 97 private void WriteHeaders(MessageHeaders headers) 98 { 99 foreach (MessageHeaderInfo header in headers) 100 { 101 Console.WriteLine("\t" + header.Actor); 102 Console.ForegroundColor = ConsoleColor.White; 103 Console.WriteLine("\t" + header.Name); 104 Console.ForegroundColor = ConsoleColor.Yellow; 105 Console.WriteLine("\t" + header.Namespace); 106 Console.WriteLine("\t" + header.Relay); 107 if (header.IsReferenceParameter == true) 108 { 109 Console.WriteLine("IsReferenceParameter header detected: " + header.ToString()); 110 } 111 } 112 Console.ResetColor(); 113 } 114 } 115 116 }
这个实例演示的是客户端通过OutgoingMessageHeaders添加了一些信息,然后服务端通过IncomingMessageHeaders
附:(也许你会有疑问,事情都是OperationContext做的,要OperationContextScope 干什么:个人理解OperationContextScope 类似于数据库连接对象类,wcfClient.InnerChannel就好像是连接字符串,告诉要连接到哪去,整个OperationContextScope 块就像是数据库中的当期连接,信息头就好像是sql语句,出了OperationContextScope 块范围就好数据库断开了连接,进行其他操作要重新连接,OperationContext 就好像是Command对象执行一些操作)
OperationContextScope 对象建立了当前操作上下文之后,可以使用 OperationContext 执行以下操作:
-
访问和修改传入和传出消息头和其他属性。
-
访问运行库,包括调度程序、主机、信道和扩展。
-
访问其他类型的上下文,如安全、实例和请求上下文。
-
访问与 OperationContext 对象关联的信道,或(如果信道实现System.ServiceModel.Channels.ISession)访问关联信道的会话标识符。
创建了 OperationContextScope 后,将存储当前的 OperationContext,并且新的 OperationContext 由Current 属性所返回。释放 OperationContextScope 后,将还原原始 OperationContext。