public MessageRpc(Message message, OperationContext operationContext, bool impersonationRequired) { Fx.Assert(message != null, "message cannot be null"); Fx.Assert(operationContext != null, "operationContext cannot be null"); this.originalMessage = message; this.OperationContext = operationContext; if (Fx.Trace.IsEtwProviderEnabled) { this.eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message); } //passing in true causes this to return null if the thread is not impersonating. this.windowsIdentity = WindowsIdentity.GetCurrent(true); if (impersonationRequired && !AspNetEnvironment.Current.AspNetCompatibilityEnabled) { if (this.windowsIdentity == null || this.windowsIdentity.ImpersonationLevel != TokenImpersonationLevel.Impersonation) { //Temporarily revert impersonation to process token to throw an exception IDisposable autoRevert = null; try { try { } finally { autoRevert = WindowsIdentity.Impersonate(IntPtr.Zero); } Win32Exception errorDetail = new Win32Exception(ERROR_BAD_IMPERSONATION_LEVEL); throw FxTrace.Exception.AsError(new SecurityNegotiationException(errorDetail.Message)); } finally { if (autoRevert != null) { autoRevert.Dispose(); } } } } ReceiveContext.TryGet(message, out this.receiveContext); this.transaction = Transaction.Current; if (this.transaction == null) { this.transaction = TransactionMessageProperty.TryGetTransaction(message); } }
// The demand is not added now (in 4.5), to avoid a breaking change. To be considered in the next version. /* * [PermissionSet(SecurityAction.Demand, Unrestricted = true)] // because we call code from a non-APTCA assembly; transactions are not supported in partial trust, so customers should not be broken by this demand */ public static Transaction GetMessageTransaction(Message message) { ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.Transaction = TransactionOption.Disabled; ServiceDomain.Enter(serviceConfig); try { return(TransactionMessageProperty.TryGetTransaction(message)); } finally { ServiceDomain.Leave(); } }
public static Transaction GetMessageTransaction(Message message) { Transaction transaction; ServiceConfig cfg = new ServiceConfig { Transaction = TransactionOption.Disabled }; ServiceDomain.Enter(cfg); try { transaction = TransactionMessageProperty.TryGetTransaction(message); } finally { ServiceDomain.Leave(); } return(transaction); }
public CallbackAsyncResult(IDuplexRouterCallback callbackInstance, Message message, AsyncCallback callback, object state) : base(callback, state) { this.callbackInstance = callbackInstance; IAsyncResult result; using (this.PrepareTransactionalCall(TransactionMessageProperty.TryGetTransaction(message))) { result = this.callbackInstance.BeginProcessMessage(message, this.PrepareAsyncCompletion(processCallback), this); } if (this.SyncContinue(result)) { this.Complete(true); } }
internal MessageRpc(RequestContext requestContext, Message request, DispatchOperationRuntime operation, ServiceChannel channel, ServiceHostBase host, ChannelHandler channelHandler, bool cleanThread, OperationContext operationContext, InstanceContext instanceContext, EventTraceActivity eventTraceActivity) { Fx.Assert((operationContext != null), "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), operationContext == null"); Fx.Assert(channelHandler != null, "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), channelHandler == null"); this.Activity = null; this.EventTraceActivity = eventTraceActivity; this.AsyncResult = null; this.CanSendReply = true; this.Channel = channel; this.channelHandler = channelHandler; this.Correlation = EmptyArray.Allocate(operation.Parent.CorrelationCount); this.CorrelationCallback = null; this.DidDeserializeRequestBody = false; this.TransactionMessageProperty = null; this.TransactedBatchContext = null; this.Error = null; this.ErrorProcessor = null; this.FaultInfo = new ErrorHandlerFaultInfo(request.Version.Addressing.DefaultFaultAction); this.HasSecurityContext = false; this.Host = host; this.Instance = null; this.MessageRpcOwnsInstanceContextThrottle = false; this.NextProcessor = null; this.NotUnderstoodHeaders = null; this.Operation = operation; this.OperationContext = operationContext; this.paused = false; this.ParametersDisposed = false; this.ReceiveContext = null; this.Request = request; this.RequestContext = requestContext; this.RequestContextThrewOnReply = false; this.SuccessfullySendReply = false; this.RequestVersion = request.Version; this.Reply = null; this.ReplyTimeoutHelper = new TimeoutHelper(); this.SecurityContext = null; this.InstanceContext = instanceContext; this.SuccessfullyBoundInstance = false; this.SuccessfullyIncrementedActivity = false; this.SuccessfullyLockedInstance = false; this.switchedThreads = !cleanThread; this.transaction = null; this.InputParameters = null; this.OutputParameters = null; this.ReturnParameter = null; this.isInstanceContextSingleton = InstanceContextProviderBase.IsProviderSingleton(this.Channel.DispatchRuntime.InstanceContextProvider); this.invokeContinueGate = null; if (!operation.IsOneWay && !operation.Parent.ManualAddressing) { this.RequestID = request.Headers.MessageId; this.ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo(request); } else { this.RequestID = null; this.ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo(); } this.HostingProperty = AspNetEnvironment.Current.GetHostingProperty(request, true); if (DiagnosticUtility.ShouldUseActivity) { this.Activity = TraceUtility.ExtractActivity(this.Request); } if (DiagnosticUtility.ShouldUseActivity || TraceUtility.ShouldPropagateActivity) { this.ResponseActivityId = ActivityIdHeader.ExtractActivityId(this.Request); } else { this.ResponseActivityId = Guid.Empty; } this.InvokeNotification = new MessageRpcInvokeNotification(this.Activity, this.channelHandler); if (this.EventTraceActivity == null && FxTrace.Trace.IsEnd2EndActivityTracingEnabled) { if (this.Request != null) { this.EventTraceActivity = EventTraceActivityHelper.TryExtractActivity(this.Request, true); } } }
internal void ResolveTransaction(ref MessageRpc rpc) { InstanceContext context; if (rpc.Operation.HasDefaultUnhandledActionInvoker) { return; } Transaction transactionForInstance = null; if (rpc.Operation.IsInsideTransactedReceiveScope) { IInstanceTransaction invoker = rpc.Operation.Invoker as IInstanceTransaction; if (invoker != null) { transactionForInstance = invoker.GetTransactionForInstance(rpc.OperationContext); } if ((transactionForInstance != null) && DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, 0xe000f, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredUsingExistingTransaction", new object[] { transactionForInstance.TransactionInformation.LocalIdentifier, rpc.Operation.Name })); } } else { transactionForInstance = this.GetInstanceContextTransaction(ref rpc); } Transaction transaction3 = null; try { transaction3 = TransactionMessageProperty.TryGetTransaction(rpc.Request); } catch (TransactionException exception) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Error); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionUnmarshalFailed", new object[] { exception.Message }), "TransactionUnmarshalingFailed", false)); } if (rpc.Operation.TransactionRequired) { if (transaction3 == null) { goto Label_0256; } if (this.isTransactedReceiveChannelDispatcher) { if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, 0xe0001, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsTransactedTransport", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name })); } goto Label_0256; } if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, 0xe0002, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsTransactionFlow", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name })); } if (PerformanceCounters.PerformanceCountersEnabled) { PerformanceCounters.TxFlowed(PerformanceCounters.GetEndpointDispatcher(), rpc.Operation.Name); } bool flag = false; if (rpc.Operation.IsInsideTransactedReceiveScope) { flag = transaction3.Equals(transactionForInstance); } else { flag = transaction3 == transactionForInstance; } if (flag) { goto Label_0256; } try { transaction3 = transaction3.DependentClone(DependentCloneOption.RollbackIfNotComplete); goto Label_0256; } catch (TransactionException exception2) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception2, TraceEventType.Error); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionAsyncAborted"), "TransactionAborted", true)); } } if ((transaction3 != null) && this.isTransactedReceiveChannelDispatcher) { try { if (rpc.TransactedBatchContext != null) { rpc.TransactedBatchContext.ForceCommit(); rpc.TransactedBatchContext = null; } else { TransactionInstanceContextFacet.Complete(transaction3, null); } } finally { transaction3.Dispose(); transaction3 = null; } } Label_0256: context = rpc.InstanceContext; if (context.Transaction.ShouldReleaseInstance && !this.isConcurrent) { if (context.Behavior.ReleaseServiceInstanceOnTransactionComplete) { context.ReleaseServiceInstance(); if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, 0xe000c, System.ServiceModel.SR.GetString("TraceCodeTxReleaseServiceInstanceOnCompletion", new object[] { transactionForInstance.TransactionInformation.LocalIdentifier })); } } context.Transaction.ShouldReleaseInstance = false; if ((transaction3 == null) || (transaction3 == transactionForInstance)) { rpc.Transaction.Current = transactionForInstance; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionAsyncAborted"), "TransactionAborted", true)); } transactionForInstance = null; } if (rpc.Operation.TransactionRequired) { if (transaction3 == null) { if (transactionForInstance != null) { transaction3 = transactionForInstance; if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, 0xe0003, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsAttachedTransaction", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name })); } } else { transaction3 = CreateTransaction(this.isolation, this.timeout); if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, 0xe0004, System.ServiceModel.SR.GetString("TraceCodeTxSourceTxScopeRequiredIsCreateNewTransaction", new object[] { transaction3.TransactionInformation.LocalIdentifier, rpc.Operation.Name })); } } } if ((this.isolation != IsolationLevel.Unspecified) && (transaction3.IsolationLevel != this.isolation)) { throw TraceUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("IsolationLevelMismatch2", new object[] { transaction3.IsolationLevel, this.isolation }), "TransactionIsolationLevelMismatch", false), rpc.Request); } rpc.Transaction.Current = transaction3; rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Current, true); try { rpc.Transaction.Clone = transaction3.Clone(); if (rpc.Operation.IsInsideTransactedReceiveScope) { rpc.Transaction.CreateDependentClone(); } } catch (ObjectDisposedException exception3) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception3, TraceEventType.Error); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFault(System.ServiceModel.SR.GetString("SFxTransactionAsyncAborted"), "TransactionAborted", true)); } rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Clone, false); rpc.OperationContext.TransactionFacet = rpc.Transaction; if (!rpc.Operation.TransactionAutoComplete) { rpc.Transaction.SetIncomplete(); } } }
internal void ResolveTransaction(ref MessageRpc rpc) { if (rpc.Operation.HasDefaultUnhandledActionInvoker) { // we ignore unhandled operations return; } Transaction contextTransaction = null; //If we are inside a TransactedReceiveScope in workflow, then we need to look into the PPD and not the InstanceContext //to get the contextTransaction if (rpc.Operation.IsInsideTransactedReceiveScope) { // We may want to use an existing transaction for the instance. IInstanceTransaction instanceTransaction = rpc.Operation.Invoker as IInstanceTransaction; if (instanceTransaction != null) { contextTransaction = instanceTransaction.GetTransactionForInstance(rpc.OperationContext); } if (contextTransaction != null) { if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.TxSourceTxScopeRequiredUsingExistingTransaction, SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredUsingExistingTransaction, contextTransaction.TransactionInformation.LocalIdentifier, rpc.Operation.Name) ); } } } else { contextTransaction = this.GetInstanceContextTransaction(ref rpc); } Transaction transaction = null; try { transaction = TransactionMessageProperty.TryGetTransaction(rpc.Request); } catch (TransactionException e) { DiagnosticUtility.TraceHandledException(e, TraceEventType.Error); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionUnmarshalFailed, e.Message), FaultCodeConstants.Codes.TransactionUnmarshalingFailed, false)); } if (rpc.Operation.TransactionRequired) { if (transaction != null) { if (this.isTransactedReceiveChannelDispatcher) { if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.TxSourceTxScopeRequiredIsTransactedTransport, SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsTransactedTransport, transaction.TransactionInformation.LocalIdentifier, rpc.Operation.Name) ); } } else { if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.TxSourceTxScopeRequiredIsTransactionFlow, SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsTransactionFlow, transaction.TransactionInformation.LocalIdentifier, rpc.Operation.Name) ); } if (PerformanceCounters.PerformanceCountersEnabled) { PerformanceCounters.TxFlowed(PerformanceCounters.GetEndpointDispatcher(), rpc.Operation.Name); } bool sameTransaction = false; if (rpc.Operation.IsInsideTransactedReceiveScope) { sameTransaction = transaction.Equals(contextTransaction); } else { sameTransaction = transaction == contextTransaction; } if (!sameTransaction) { try { transaction = transaction.DependentClone(DependentCloneOption.RollbackIfNotComplete); } catch (TransactionException e) { DiagnosticUtility.TraceHandledException(e, TraceEventType.Error); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionAsyncAborted), FaultCodeConstants.Codes.TransactionAborted, true)); } } } } } else { // We got a transaction from the ChannelHandler. // Transport is transacted. // But operation doesn't require the transaction, so no one ever will commit it. // Because of that we have to commit it here. if (transaction != null && this.isTransactedReceiveChannelDispatcher) { try { if (null != rpc.TransactedBatchContext) { rpc.TransactedBatchContext.ForceCommit(); rpc.TransactedBatchContext = null; } else { TransactionInstanceContextFacet.Complete(transaction, null); } } finally { transaction.Dispose(); transaction = null; } } } InstanceContext context = rpc.InstanceContext; if (context.Transaction.ShouldReleaseInstance && !this.isConcurrent) { if (context.Behavior.ReleaseServiceInstanceOnTransactionComplete) { context.ReleaseServiceInstance(); if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.TxReleaseServiceInstanceOnCompletion, SR.GetString(SR.TraceCodeTxReleaseServiceInstanceOnCompletion, contextTransaction.TransactionInformation.LocalIdentifier) ); } } context.Transaction.ShouldReleaseInstance = false; if (transaction == null || transaction == contextTransaction) { rpc.Transaction.Current = contextTransaction; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionAsyncAborted), FaultCodeConstants.Codes.TransactionAborted, true)); } else { contextTransaction = null; } } if (rpc.Operation.TransactionRequired) { if (transaction == null) { if (contextTransaction != null) { transaction = contextTransaction; if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.TxSourceTxScopeRequiredIsAttachedTransaction, SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsAttachedTransaction, transaction.TransactionInformation.LocalIdentifier, rpc.Operation.Name) ); } } else { transaction = TransactionBehavior.CreateTransaction(this.isolation, this.timeout); if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.TxSourceTxScopeRequiredIsCreateNewTransaction, SR.GetString(SR.TraceCodeTxSourceTxScopeRequiredIsCreateNewTransaction, transaction.TransactionInformation.LocalIdentifier, rpc.Operation.Name) ); } } } if ((this.isolation != IsolationLevel.Unspecified) && (transaction.IsolationLevel != this.isolation)) { throw TraceUtility.ThrowHelperError(TransactionBehavior.CreateFault (SR.GetString(SR.IsolationLevelMismatch2, transaction.IsolationLevel, this.isolation), FaultCodeConstants.Codes.TransactionIsolationLevelMismatch, false), rpc.Request); } rpc.Transaction.Current = transaction; rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Current, true); try { rpc.Transaction.Clone = transaction.Clone(); if (rpc.Operation.IsInsideTransactedReceiveScope) { //It is because we want to synchronize the dispatcher processing of messages with the commit //processing that is started by the completion of a TransactedReceiveScope. We need to make sure //that all the dispatcher processing is done and we can do that by creating a blocking dependent clone and only //completing it after all of the message processing is done for a given TransactionRpcFacet rpc.Transaction.CreateDependentClone(); } } catch (ObjectDisposedException e)//transaction may be async aborted { DiagnosticUtility.TraceHandledException(e, TraceEventType.Error); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(TransactionBehavior.CreateFault(SR.GetString(SR.SFxTransactionAsyncAborted), FaultCodeConstants.Codes.TransactionAborted, true)); } rpc.InstanceContext.Transaction.AddReference(ref rpc, rpc.Transaction.Clone, false); rpc.OperationContext.TransactionFacet = rpc.Transaction; if (!rpc.Operation.TransactionAutoComplete) { rpc.Transaction.SetIncomplete(); } } }
Message EndReceive(Socket listenSocket, IAsyncResult result) { // if we've started the shutdown process, then we've disposed // the socket and calls to socket.EndReceive will throw if (base.State != CommunicationState.Opened) { return(null); } byte[] buffer = ((SocketReceiveState)result.AsyncState).Buffer; Message message = null; try { int count = 0; lock (ThisLock) { // if we've started the shutdown process, socket is disposed // and calls to socket.EndReceive will throw if (base.State == CommunicationState.Opened) { EndPoint dummy = CreateDummyEndPoint(listenSocket); count = listenSocket.EndReceiveFrom(result, ref dummy); } } if (count > 0) { ArraySegment <byte> msg; Transaction transaction; // read the transaction and message TransactionMessageBuffer.ReadTransactionMessageBuffer(buffer, count, out transaction, out msg); try { message = MessageEncoderFactory.Encoder.ReadMessage(msg, bufferManager); } catch (XmlException xmlException) { throw new ProtocolException( "There is a problem with the XML that was received from the network. See inner exception for more details.", xmlException); } if (transaction != null) { // This is where we set the transaction on the message in order to be picked up by // the dispatcher, and used to call the service operation. We use the // System.ServiceModel.Channels.TransactionMessageProperty provided by the WCF framework. TransactionMessageProperty.Set(transaction, message); } } } catch (Exception e) { Debug.WriteLine("Error in completing the async receive via EndReceiveFrom method."); Debug.WriteLine(e.ToString()); } finally { if (message == null) { this.bufferManager.ReturnBuffer(buffer); buffer = null; } } return(message); }