| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.ServiceModel
- {
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Runtime;
- using System.Security.Claims;
- using System.Security.Principal;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Dispatcher;
- using System.ServiceModel.Security;
- public sealed class OperationContext : IExtensibleObject<OperationContext>
- {
- [ThreadStatic]
- static Holder currentContext;
- ServiceChannel channel;
- Message clientReply;
- bool closeClientReply;
- ExtensionCollection<OperationContext> extensions;
- ServiceHostBase host;
- RequestContext requestContext;
- Message request;
- InstanceContext instanceContext;
- bool isServiceReentrant = false;
- internal IPrincipal threadPrincipal;
- TransactionRpcFacet txFacet;
- MessageProperties outgoingMessageProperties;
- MessageHeaders outgoingMessageHeaders;
- MessageVersion outgoingMessageVersion;
- EndpointDispatcher endpointDispatcher;
- public event EventHandler OperationCompleted;
- public OperationContext(IContextChannel channel)
- {
- if (channel == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("channel"));
- ServiceChannel serviceChannel = channel as ServiceChannel;
- //Could be a TransparentProxy
- if (serviceChannel == null)
- {
- serviceChannel = ServiceChannelFactory.GetServiceChannel(channel);
- }
- if (serviceChannel != null)
- {
- this.outgoingMessageVersion = serviceChannel.MessageVersion;
- this.channel = serviceChannel;
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInvalidChannelToOperationContext)));
- }
- }
- internal OperationContext(ServiceHostBase host)
- : this(host, MessageVersion.Soap12WSAddressing10)
- {
- }
- internal OperationContext(ServiceHostBase host, MessageVersion outgoingMessageVersion)
- {
- if (outgoingMessageVersion == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("outgoingMessageVersion"));
- this.host = host;
- this.outgoingMessageVersion = outgoingMessageVersion;
- }
- internal OperationContext(RequestContext requestContext, Message request, ServiceChannel channel, ServiceHostBase host)
- {
- this.channel = channel;
- this.host = host;
- this.requestContext = requestContext;
- this.request = request;
- this.outgoingMessageVersion = channel.MessageVersion;
- }
- public IContextChannel Channel
- {
- get { return this.GetCallbackChannel<IContextChannel>(); }
- }
- public static OperationContext Current
- {
- get
- {
- return CurrentHolder.Context;
- }
- set
- {
- CurrentHolder.Context = value;
- }
- }
- internal static Holder CurrentHolder
- {
- get
- {
- Holder holder = OperationContext.currentContext;
- if (holder == null)
- {
- holder = new Holder();
- OperationContext.currentContext = holder;
- }
- return holder;
- }
- }
- public EndpointDispatcher EndpointDispatcher
- {
- get
- {
- return this.endpointDispatcher;
- }
- set
- {
- this.endpointDispatcher = value;
- }
- }
- public bool IsUserContext
- {
- get
- {
- return (this.request == null);
- }
- }
- public IExtensionCollection<OperationContext> Extensions
- {
- get
- {
- if (this.extensions == null)
- {
- this.extensions = new ExtensionCollection<OperationContext>(this);
- }
- return this.extensions;
- }
- }
- internal bool IsServiceReentrant
- {
- get { return this.isServiceReentrant; }
- set { this.isServiceReentrant = value; }
- }
- public bool HasSupportingTokens
- {
- get
- {
- MessageProperties properties = this.IncomingMessageProperties;
- return properties != null && properties.Security != null &&
- properties.Security.HasIncomingSupportingTokens;
- }
- }
- public ServiceHostBase Host
- {
- get { return this.host; }
- }
- internal Message IncomingMessage
- {
- get { return this.clientReply ?? this.request; }
- }
- internal ServiceChannel InternalServiceChannel
- {
- get { return this.channel; }
- set { this.channel = value; }
- }
- internal bool HasOutgoingMessageHeaders
- {
- get { return (this.outgoingMessageHeaders != null); }
- }
- public MessageHeaders OutgoingMessageHeaders
- {
- get
- {
- if (this.outgoingMessageHeaders == null)
- this.outgoingMessageHeaders = new MessageHeaders(this.OutgoingMessageVersion);
- return this.outgoingMessageHeaders;
- }
- }
- internal bool HasOutgoingMessageProperties
- {
- get { return (this.outgoingMessageProperties != null); }
- }
- public MessageProperties OutgoingMessageProperties
- {
- get
- {
- if (this.outgoingMessageProperties == null)
- this.outgoingMessageProperties = new MessageProperties();
- return this.outgoingMessageProperties;
- }
- }
- internal MessageVersion OutgoingMessageVersion
- {
- get { return this.outgoingMessageVersion; }
- }
- public MessageHeaders IncomingMessageHeaders
- {
- get
- {
- Message message = this.clientReply ?? this.request;
- if (message != null)
- return message.Headers;
- else
- return null;
- }
- }
- public MessageProperties IncomingMessageProperties
- {
- get
- {
- Message message = this.clientReply ?? this.request;
- if (message != null)
- return message.Properties;
- else
- return null;
- }
- }
- public MessageVersion IncomingMessageVersion
- {
- get
- {
- Message message = this.clientReply ?? this.request;
- if (message != null)
- return message.Version;
- else
- return null;
- }
- }
- public InstanceContext InstanceContext
- {
- get { return this.instanceContext; }
- }
- public RequestContext RequestContext
- {
- get { return this.requestContext; }
- set { this.requestContext = value; }
- }
- public ServiceSecurityContext ServiceSecurityContext
- {
- get
- {
- MessageProperties properties = this.IncomingMessageProperties;
- if (properties != null && properties.Security != null)
- {
- return properties.Security.ServiceSecurityContext;
- }
- return null;
- }
- }
- public string SessionId
- {
- get
- {
- if (this.channel != null)
- {
- IChannel inner = this.channel.InnerChannel;
- if (inner != null)
- {
- ISessionChannel<IDuplexSession> duplex = inner as ISessionChannel<IDuplexSession>;
- if ((duplex != null) && (duplex.Session != null))
- return duplex.Session.Id;
- ISessionChannel<IInputSession> input = inner as ISessionChannel<IInputSession>;
- if ((input != null) && (input.Session != null))
- return input.Session.Id;
- ISessionChannel<IOutputSession> output = inner as ISessionChannel<IOutputSession>;
- if ((output != null) && (output.Session != null))
- return output.Session.Id;
- }
- }
- return null;
- }
- }
- public ICollection<SupportingTokenSpecification> SupportingTokens
- {
- get
- {
- MessageProperties properties = this.IncomingMessageProperties;
- if (properties != null && properties.Security != null)
- {
- return new System.Collections.ObjectModel.ReadOnlyCollection<SupportingTokenSpecification>(
- properties.Security.IncomingSupportingTokens);
- }
- return null;
- }
- }
- internal IPrincipal ThreadPrincipal
- {
- get { return this.threadPrincipal; }
- set { this.threadPrincipal = value; }
- }
- public ClaimsPrincipal ClaimsPrincipal
- {
- get;
- internal set;
- }
- internal TransactionRpcFacet TransactionFacet
- {
- get { return this.txFacet; }
- set { this.txFacet = value; }
- }
- internal void ClearClientReplyNoThrow()
- {
- this.clientReply = null;
- }
- internal void FireOperationCompleted()
- {
- try
- {
- EventHandler handler = this.OperationCompleted;
- if (handler != null)
- {
- handler(this, EventArgs.Empty);
- }
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
- }
- }
- public T GetCallbackChannel<T>()
- {
- if (this.channel == null || this.IsUserContext)
- return default(T);
- // yes, we might throw InvalidCastException here. Is it really
- // better to check and throw something else instead?
- return (T)this.channel.Proxy;
- }
- internal void ReInit(RequestContext requestContext, Message request, ServiceChannel channel)
- {
- this.requestContext = requestContext;
- this.request = request;
- this.channel = channel;
- }
- internal void Recycle()
- {
- this.requestContext = null;
- this.request = null;
- this.extensions = null;
- this.instanceContext = null;
- this.threadPrincipal = null;
- this.txFacet = null;
- this.SetClientReply(null, false);
- }
- internal void SetClientReply(Message message, bool closeMessage)
- {
- Message oldClientReply = null;
- if (!object.Equals(message, this.clientReply))
- {
- if (this.closeClientReply && (this.clientReply != null))
- {
- oldClientReply = this.clientReply;
- }
- this.clientReply = message;
- }
- this.closeClientReply = closeMessage;
- if (oldClientReply != null)
- {
- oldClientReply.Close();
- }
- }
- public void SetTransactionComplete()
- {
- if (this.txFacet == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoTransactionInContext)));
- }
- this.txFacet.Completed();
- }
- internal void SetInstanceContext(InstanceContext instanceContext)
- {
- this.instanceContext = instanceContext;
- }
- internal class Holder
- {
- OperationContext context;
- public OperationContext Context
- {
- get
- {
- return this.context;
- }
- set
- {
- this.context = value;
- }
- }
- }
- }
- }
|