1 // 2 // OperationContext.cs 3 // 4 // Author: Atsushi Enomoto (atsushi@ximian.com) 5 // 6 // Copyright (C) 2005,2007 Novell, Inc (http://www.novell.com) 7 // 8 // Permission is hereby granted, free of charge, to any person obtaining 9 // a copy of this software and associated documentation files (the 10 // "Software"), to deal in the Software without restriction, including 11 // without limitation the rights to use, copy, modify, merge, publish, 12 // distribute, sublicense, and/or sell copies of the Software, and to 13 // permit persons to whom the Software is furnished to do so, subject to 14 // the following conditions: 15 // 16 // The above copyright notice and this permission notice shall be 17 // included in all copies or substantial portions of the Software. 18 // 19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 // 27 using System; 28 using System.Collections.Generic; 29 using System.Collections.ObjectModel; 30 using System.ServiceModel.Channels; 31 using System.ServiceModel.Dispatcher; 32 using System.ServiceModel.Security; 33 using System.Threading; 34 35 namespace System.ServiceModel 36 { 37 public sealed class OperationContext : IExtensibleObject<OperationContext> 38 { 39 [ThreadStatic] 40 static OperationContext current; 41 42 public static OperationContext Current { 43 get { return current; } 44 set { current = value; } 45 } 46 47 Message incoming_message; 48 #if !MOBILE && !XAMMAC_4_5 49 EndpointDispatcher dispatcher; 50 #endif 51 IContextChannel channel; 52 RequestContext request_ctx; 53 ExtensionCollection<OperationContext> extensions; 54 MessageHeaders outgoing_headers; 55 MessageProperties outgoing_properties; 56 InstanceContext instance_context; 57 OperationContext(IContextChannel channel)58 public OperationContext (IContextChannel channel) 59 : this (channel, true) 60 { 61 } 62 OperationContext(IContextChannel channel, bool isUserContext)63 internal OperationContext (IContextChannel channel, bool isUserContext) 64 { 65 if (channel == null) 66 throw new ArgumentNullException ("channel"); 67 this.channel = channel; 68 IsUserContext = isUserContext; 69 } 70 71 public event EventHandler OperationCompleted; 72 73 public IContextChannel Channel { 74 get { return channel; } 75 } 76 77 public IExtensionCollection<OperationContext> Extensions { 78 get { 79 if (extensions == null) 80 extensions = new ExtensionCollection<OperationContext> (this); 81 return extensions; 82 } 83 } 84 85 86 #if !MOBILE && !XAMMAC_4_5 87 public EndpointDispatcher EndpointDispatcher { 88 get { return dispatcher; } 89 set { dispatcher = value; } 90 } 91 public bool HasSupportingTokens { 92 get { return SupportingTokens != null ? SupportingTokens.Count > 0 : false; } 93 } 94 95 public ServiceHostBase Host { 96 get { return dispatcher != null ? dispatcher.ChannelDispatcher.Host : null; } 97 } 98 #endif 99 100 public MessageHeaders IncomingMessageHeaders { 101 get { return incoming_message != null ? incoming_message.Headers : null; } 102 } 103 104 public MessageProperties IncomingMessageProperties { 105 get { return incoming_message != null ? incoming_message.Properties : null; } 106 } 107 108 public MessageVersion IncomingMessageVersion { 109 get { return incoming_message != null ? incoming_message.Version : null; } 110 } 111 112 [MonoTODO] 113 public InstanceContext InstanceContext { 114 get { 115 return instance_context; 116 } 117 internal set { 118 instance_context = value; 119 } 120 } 121 122 public bool IsUserContext { get; private set; } 123 124 public MessageHeaders OutgoingMessageHeaders { 125 get { 126 if (outgoing_headers == null) 127 outgoing_headers = new MessageHeaders (channel.GetProperty<MessageVersion> () ?? MessageVersion.Default); 128 return outgoing_headers; 129 } 130 } 131 132 public MessageProperties OutgoingMessageProperties { 133 get { 134 if (outgoing_properties == null) 135 outgoing_properties = new MessageProperties (); 136 return outgoing_properties; 137 } 138 } 139 140 public RequestContext RequestContext { 141 get { return request_ctx; } 142 set { request_ctx = value; } 143 } 144 145 public string SessionId { 146 get { return Channel.SessionId; } 147 } 148 149 #if !MOBILE 150 public ServiceSecurityContext ServiceSecurityContext { 151 get { return IncomingMessageProperties != null ? IncomingMessageProperties.Security.ServiceSecurityContext : null; } 152 } 153 154 public ICollection<SupportingTokenSpecification> SupportingTokens { 155 get { return IncomingMessageProperties != null ? IncomingMessageProperties.Security.IncomingSupportingTokens : null; } 156 } 157 GetCallbackChannel()158 public T GetCallbackChannel<T> () 159 { 160 // It is correct; OperationContext.Channel and OperationContext.GetCallbackChannel<T>() returns the same instance on .NET. (at least as far as I tested.) 161 return (T) (object) channel; 162 } 163 164 [MonoTODO] SetTransactionComplete()165 public void SetTransactionComplete () 166 { 167 throw new NotImplementedException (); 168 } 169 #endif 170 171 internal Message IncomingMessage { 172 get { 173 return incoming_message; 174 } 175 set { 176 incoming_message = value; 177 } 178 } 179 } 180 } 181