//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ namespace System.Workflow.Activities { using System; using System.Reflection; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Globalization; using System.IdentityModel.Claims; using System.Security.Permissions; using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; using System.Workflow.Activities; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Design; using System.Workflow.ComponentModel.Serialization; using System.Workflow.Runtime; using System.Xml; [SR2Description(SR2DescriptionAttribute.ReceiveActivityDescription)] [SR2Category(SR2CategoryAttribute.Standard)] [Designer(typeof(ReceiveActivityDesigner), typeof(IDesigner))] [ToolboxBitmap(typeof(ReceiveActivity), "Design.Resources.ReceiveActivity.png")] [ActivityValidator(typeof(ReceiveActivityValidator))] [Serializable] [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")] public sealed class ReceiveActivity : SequenceActivity, IEventActivity, IActivityEventListener, IServiceDescriptionBuilder { [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly DependencyProperty FaultMessageProperty = DependencyProperty.Register("FaultMessage", typeof(FaultException), typeof(ReceiveActivity), new PropertyMetadata(null)); [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly DependencyProperty OperationValidationEvent = DependencyProperty.Register("OperationValidation", typeof(EventHandler), typeof(ReceiveActivity)); [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly DependencyProperty WorkflowServiceAttributesProperty = DependencyProperty.RegisterAttached("WorkflowServiceAttributes", typeof(WorkflowServiceAttributes), typeof(ReceiveActivity), new PropertyMetadata(null, DependencyPropertyOptions.Metadata, ReceiveActivity.GetWorkflowServiceAttributesValueOverride, null), typeof(WorkflowServiceAttributesDynamicPropertyValidator)); [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] internal static readonly DependencyProperty CanCreateInstanceProperty = DependencyProperty.Register("CanCreateInstance", typeof(bool), typeof(ReceiveActivity), new PropertyMetadata(false, DependencyPropertyOptions.Metadata)); [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] internal static readonly DependencyProperty ContextTokenProperty = DependencyProperty.Register("ContextToken", typeof(ContextToken), typeof(ReceiveActivity), new PropertyMetadata(null, DependencyPropertyOptions.Metadata)); [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] internal static readonly DependencyProperty ParameterBindingsProperty = DependencyProperty.Register("ParameterBindings", typeof(WorkflowParameterBindingCollection), typeof(ReceiveActivity), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly)); [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] internal static readonly DependencyProperty ServiceOperationInfoProperty = DependencyProperty.Register("ServiceOperationInfo", typeof(OperationInfoBase), typeof(ReceiveActivity), new PropertyMetadata(DependencyPropertyOptions.Metadata)); private static readonly DependencyProperty QueueNameProperty = DependencyProperty.Register("QueueName", typeof(string), typeof(ReceiveActivity)); private static readonly DependencyProperty RequestContextProperty = DependencyProperty.Register("RequestContext", typeof(WorkflowRequestContext), typeof(ReceiveActivity)); static DependencyProperty QueueInitializationModeProperty = DependencyProperty.Register("QueueInitializationMode", typeof(QueueInitializationMode), typeof(ReceiveActivity), new PropertyMetadata(QueueInitializationMode.Standalone)); [NonSerialized] private ReceiveOperationInfoHelper operationHelper; private IActivityEventListener securityShim; private IActivityEventListener validationShim; [NonSerialized] private static Hashtable requestContextsCache = Hashtable.Synchronized(new Hashtable()); private bool isContextCached; public ReceiveActivity() { base.SetReadOnlyPropertyValue(ReceiveActivity.ParameterBindingsProperty, new WorkflowParameterBindingCollection(this)); } public ReceiveActivity(string name) : base(name) { base.SetReadOnlyPropertyValue(ReceiveActivity.ParameterBindingsProperty, new WorkflowParameterBindingCollection(this)); } [SRCategory(SR2CategoryAttribute.Handlers)] [SR2Description(SR2DescriptionAttribute.Receive_OperationValidation_Description)] [MergableProperty(false)] public event EventHandler OperationValidation { add { base.AddHandler(OperationValidationEvent, value); } remove { base.RemoveHandler(OperationValidationEvent, value); } } [Browsable(true)] [DefaultValue(false)] [SR2Category(SR2CategoryAttribute.Activity)] [SR2Description(SR2DescriptionAttribute.Receive_CanCreateInstance_Description)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool CanCreateInstance { get { return ((bool)(base.GetValue(ReceiveActivity.CanCreateInstanceProperty))); } set { base.SetValue(ReceiveActivity.CanCreateInstanceProperty, value); } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IDictionary Context { get { if (this.ContextToken == null) { return ReceiveActivity.GetRootContext(this); } return ReceiveActivity.GetContext(this, this.ContextToken); } } [DefaultValue(null)] [MergableProperty(false)] [RefreshProperties(RefreshProperties.All)] [SR2Category(SR2CategoryAttribute.Activity)] [SR2Description(SR2DescriptionAttribute.Receive_ContextToken_Description)] [TypeConverter(typeof(ContextTokenTypeConverter))] public ContextToken ContextToken { get { return base.GetValue(ContextTokenProperty) as ContextToken; } set { base.SetValue(ContextTokenProperty, value); } } [Browsable(true)] [DefaultValue(null)] [SR2Category(SR2CategoryAttribute.Activity)] [SR2Description(SR2DescriptionAttribute.Receive_FaultMessage_Description)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public FaultException FaultMessage { get { return ((FaultException)base.GetValue(ReceiveActivity.FaultMessageProperty)); } set { base.SetValue(ReceiveActivity.FaultMessageProperty, value); } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public WorkflowParameterBindingCollection ParameterBindings { get { return ((WorkflowParameterBindingCollection)(base.GetValue(ReceiveActivity.ParameterBindingsProperty))); } } [Browsable(true)] [SR2Category(SR2CategoryAttribute.Activity)] [SR2Description(SR2DescriptionAttribute.Receive_OperationInfo_Description)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public OperationInfoBase ServiceOperationInfo { get { return ((OperationInfoBase)(base.GetValue(ReceiveActivity.ServiceOperationInfoProperty))); } set { OperationInfoBase currentValue = ((OperationInfoBase)(base.GetValue(ReceiveActivity.ServiceOperationInfoProperty))); if (value != null && currentValue != value) { DependencyProperty ParentDependencyObjectProperty = DependencyProperty.FromName("ParentDependencyObject", typeof(DependencyObject)); Activity currentParent = value.GetValue(ParentDependencyObjectProperty) as Activity; if (currentParent != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "value", SR2.GetString(SR2.Error_OperationIsAlreadyAssociatedWithActivity, value, currentParent.QualifiedName)); } if (currentValue != null) { currentValue.SetValue(ParentDependencyObjectProperty, null); } value.SetValue(ParentDependencyObjectProperty, this); } if (this.DesignMode && value is OperationInfo) { Activity rootActivity = this.RootActivity; rootActivity.RemoveProperty(DynamicContractTypeBuilder.DynamicContractTypesProperty); } base.SetValue(ReceiveActivity.ServiceOperationInfoProperty, value); } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] internal WorkflowRequestContext RequestContext { get { return ((WorkflowRequestContext)(base.GetValue(ReceiveActivity.RequestContextProperty))); } set { base.SetValue(ReceiveActivity.RequestContextProperty, value); } } IComparable IEventActivity.QueueName { get { return this.GetValue(ReceiveActivity.QueueNameProperty) as string; } } ReceiveOperationInfoHelper OperationHelper { get { if (this.operationHelper == null) { if (this.UserData.Contains(typeof(ReceiveOperationInfoHelper))) { this.operationHelper = this.UserData[typeof(ReceiveOperationInfoHelper)] as ReceiveOperationInfoHelper; } } if (this.operationHelper == null) { this.operationHelper = new ReceiveOperationInfoHelper(this.Site, this); this.UserData[typeof(ReceiveOperationInfoHelper)] = this.operationHelper; } return this.operationHelper; } } private QueueInitializationMode QueueInitializationMode { get { return (QueueInitializationMode)base.GetValue(ReceiveActivity.QueueInitializationModeProperty); } set { base.SetValue(ReceiveActivity.QueueInitializationModeProperty, value); } } public static IDictionary GetContext(Activity activity, ContextToken contextToken) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } if (contextToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contextToken"); } if (contextToken.IsRootContext) { return GetRootContext(activity); } return GetContext(activity, contextToken.Name, contextToken.OwnerActivityName); } public static IDictionary GetContext(Activity activity, string contextName, string ownerActivityName) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } if (string.IsNullOrEmpty(contextName)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("contextName", SR2.GetString(SR2.Error_ArgumentValueNullOrEmptyString)); } ReceiveContext receiveContext = ContextToken.GetReceiveContext(activity, contextName, ownerActivityName); if (receiveContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_CannotFindReceiveContext, contextName))); } return receiveContext.Properties; } public static IDictionary GetRootContext(Activity activity) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } ReceiveContext receiveContext = ContextToken.GetRootReceiveContext(activity); if (receiveContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_CannotFindReceiveContext, ContextToken.RootContextName))); } return receiveContext.Properties; } public static object GetWorkflowServiceAttributes(object dependencyObject) { if (dependencyObject == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dependencyObject"); } if (!(dependencyObject is Activity)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "dependencyObject", SR2.GetString(SR2.Error_UnexpectedArgumentType, typeof(Activity).FullName)); } return (dependencyObject as DependencyObject).GetValue(ReceiveActivity.WorkflowServiceAttributesProperty); } public static void SetWorkflowServiceAttributes(object dependencyObject, object value) { if (dependencyObject == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dependencyObject"); } if (!(dependencyObject is Activity)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "dependencyObject", SR2.GetString(SR2.Error_UnexpectedArgumentType, typeof(Activity).FullName)); } (dependencyObject as DependencyObject).SetValue(ReceiveActivity.WorkflowServiceAttributesProperty, value); } void IActivityEventListener.OnEvent(object sender, QueueEventArgs e) { if (sender == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sender"); } if (e == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("e"); } ActivityExecutionContext executionContext = sender as ActivityExecutionContext; if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentException(SR2.GetString(SR2.Error_ArgumentTypeInvalid, "sender", typeof(ActivityExecutionContext)))); } WorkflowQueuingService queuingService = executionContext.GetService(); if (queuingService == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(WorkflowQueuingService)))); } WorkflowQueue workflowQueue = queuingService.GetWorkflowQueue(e.QueueName); if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_QueueNotFound, e.QueueName))); } if (workflowQueue.Count != 0) { WorkflowRequestContext requestContext = workflowQueue.Peek() as WorkflowRequestContext; if (requestContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_RequestContextUnavailable, this.QualifiedName))); } if (ValidationShim.EvaluateSecurityConstraints(executionContext, this, requestContext)) { workflowQueue.UnregisterForQueueItemAvailable(this); this.RequestContext = workflowQueue.Dequeue() as WorkflowRequestContext; CacheRequestContext(this.RequestContext); if (this.QueueInitializationMode == QueueInitializationMode.Standalone) { if (this.securityShim != null) { workflowQueue.UnregisterForQueueItemArrived(this.securityShim); this.securityShim = null; } workflowQueue.Enabled = false; } if (this.RequestContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_RequestContextUnavailable, this.QualifiedName))); } if (ExecuteActivity(this.RequestContext, executionContext) == ActivityExecutionStatus.Closed) { try { executionContext.CloseActivity(); } finally { RemoveRequestContext(); } } } else { workflowQueue.Dequeue(); try { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - message validation failed. Message will be discarded.", this.WorkflowInstanceId, this.QualifiedName); requestContext.SendFault(new FaultException(SR2.GetString(SR2.SecurityCheckFailed)), null); } catch (CommunicationException cex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault for rejected message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, cex); } catch (TimeoutException tex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault for rejected message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, tex); } if (requestContext.ContextProperties == null || !(requestContext.ContextProperties.Keys.Contains(WellKnownContextProperties.InstanceId))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new FaultException(SR2.GetString(SR2.Error_FailedToValidateActivatingMessage, this.WorkflowInstanceId))); } } } } void IEventActivity.Subscribe(ActivityExecutionContext parentContext, IActivityEventListener parentEventHandler) { if (parentContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parentContext"); } if (parentEventHandler == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parentEventHandler"); } if (this.QueueInitializationMode == QueueInitializationMode.Standalone) { this.QueueInitializationMode = QueueInitializationMode.EventDriven; } // make sure that we are getting the proper queue // even if that means creating a new queue // given our conversation context and execution context. // WorkflowQueue workflowQueue = GetWorkflowQueue(parentContext); if (workflowQueue != null) { if (this.QueueInitializationMode == QueueInitializationMode.EventDriven) { workflowQueue.Enabled = true; } if (this.validationShim == null) { this.validationShim = new ValidationShim(this, parentEventHandler); } if (this.securityShim == null) { this.securityShim = new SecurityShim(this); } workflowQueue.RegisterForQueueItemArrived(this.securityShim); workflowQueue.RegisterForQueueItemAvailable(this.validationShim, this.QualifiedName); } return; } void IEventActivity.Unsubscribe(ActivityExecutionContext parentContext, IActivityEventListener parentEventHandler) { if (parentContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parentContext"); } if (parentEventHandler == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parentEventHandler"); } WorkflowQueuingService queuingService = parentContext.GetService(); if (queuingService == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(WorkflowQueuingService)))); } // get the queue using the queue name // at this point the conversation context should have been re-initialized if necessary // WorkflowQueue workflowQueue = queuingService.GetWorkflowQueue(((IEventActivity)this).QueueName); if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_QueueNotFound, ((IEventActivity)this).QueueName))); } if (this.securityShim != null) { workflowQueue.UnregisterForQueueItemArrived(this.securityShim); this.securityShim = null; } if (this.validationShim != null) { workflowQueue.UnregisterForQueueItemAvailable(this.validationShim); } if (this.QueueInitializationMode == QueueInitializationMode.EventDriven) { workflowQueue.Enabled = false; } return; } [SuppressMessage("Microsoft.Security", "CA2103")] // Review imperative security, because constructing PrincipalPermission void IServiceDescriptionBuilder.BuildServiceDescription(ServiceDescriptionContext context) { if (context == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } if (!this.Enabled) { return; } OperationInfoBase serviceOperationInfo = this.ServiceOperationInfo; if (serviceOperationInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name))); } // set the workflow service behavior // IServiceDescriptionBuilder serviceAttributes = GetWorkflowServiceAttributes(this.RootActivity) as IServiceDescriptionBuilder; if (serviceAttributes != null) { serviceAttributes.BuildServiceDescription(context); } if (context.ReflectedContracts == null || context.WorkflowOperationBehaviors == null) { return; } // add contract types and configure the operation behavior // Type contractType = serviceOperationInfo.GetContractType(((IComponent)this).Site); List interfaces = ServiceOperationHelpers.GetContracts(contractType); for (int i = 0; i < interfaces.Count; i++) { Type interfaceType = interfaces[i]; ContractDescription contractDescription = null; if (!context.ReflectedContracts.Contains(interfaceType)) { contractDescription = ContractDescription.GetContract(interfaceType); ServiceOperationHelpers.SetWorkflowOperationBehavior(contractDescription, context); context.Contracts.Add(contractDescription.ConfigurationName, contractDescription); context.ReflectedContracts.Add(contractDescription.ContractType); } else { contractDescription = context.Contracts[ContractDescription.GetContract(interfaceType).ConfigurationName]; } Collection inheritedContractDescriptions = contractDescription.GetInheritedContracts(); for (int j = 0; j < inheritedContractDescriptions.Count; j++) { ContractDescription inheritedContractDescription = inheritedContractDescriptions[j]; if (!context.ReflectedContracts.Contains(inheritedContractDescription.ContractType)) { ServiceOperationHelpers.SetWorkflowOperationBehavior(inheritedContractDescription, context); context.Contracts.Add(inheritedContractDescription.ConfigurationName, inheritedContractDescription); context.ReflectedContracts.Add(inheritedContractDescription.ContractType); } } } Type operationDeclaringType = null; MethodInfo methodInfo = serviceOperationInfo.GetMethodInfo(((IComponent)this).Site); if (methodInfo != null) { operationDeclaringType = methodInfo.DeclaringType; } if (operationDeclaringType != null) { WorkflowOperationBehavior behavior = null; KeyValuePair operationKey = new KeyValuePair(operationDeclaringType, serviceOperationInfo.Name); if (context.WorkflowOperationBehaviors.TryGetValue(operationKey, out behavior) && behavior != null) { if (!behavior.CanCreateInstance && this.CanCreateInstance) { behavior.CanCreateInstance = true; } if (!string.IsNullOrEmpty(serviceOperationInfo.PrincipalPermissionRole) || !string.IsNullOrEmpty(serviceOperationInfo.PrincipalPermissionName)) { if (behavior.ServiceAuthorizationManager == null) { PrincipalPermission permission = new PrincipalPermission(serviceOperationInfo.PrincipalPermissionName, serviceOperationInfo.PrincipalPermissionRole, true); PrincipalPermissionServiceAuthorizationManager authManager = new PrincipalPermissionServiceAuthorizationManager(permission); behavior.ServiceAuthorizationManager = authManager; } } } } } protected internal override void Initialize(IServiceProvider provider) { if (provider == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("provider"); } ContextToken.Register(this, this.WorkflowInstanceId); SetQueueInitializationMode(); // make sure that we are getting the proper queue // even if that means creating a new queue // given our conversation context and execution context. // WorkflowQueue workflowQueue = GetWorkflowQueue(provider); if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_QueueNotFound, ((IEventActivity)this).QueueName))); } if (this.QueueInitializationMode == QueueInitializationMode.StateMachine) { workflowQueue.Enabled = true; } base.Initialize(provider); } internal void GetParameterPropertyDescriptors(IDictionary properties) { if (properties == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties"); } if (((IComponent)this).Site == null) { return; } OperationInfoBase serviceOperationInfo = this.ServiceOperationInfo; if (serviceOperationInfo != null) { MethodInfo methodInfo = serviceOperationInfo.GetMethodInfo(((IComponent)this).Site); if (methodInfo != null) { ArrayList paramInfo = new ArrayList(methodInfo.GetParameters()); if (!(methodInfo.ReturnType == typeof(void))) { paramInfo.Add(methodInfo.ReturnParameter); } foreach (ParameterInfo param in paramInfo) { if (param.ParameterType != null) { PropertyDescriptor prop = new ParameterInfoBasedPropertyDescriptor(typeof(ReceiveActivity), param, true, DesignOnlyAttribute.Yes); properties[prop.Name] = prop; } } } } } protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) { try { if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext"); } WorkflowQueuingService queuingService = executionContext.GetService(); if (queuingService == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(WorkflowQueuingService)))); } WorkflowQueue workflowQueue = GetWorkflowQueue(executionContext); if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_QueueNotFound, ((IEventActivity)this).QueueName))); } workflowQueue.UnregisterForQueueItemAvailable(this); if (this.QueueInitializationMode == QueueInitializationMode.Standalone) { if (this.securityShim != null) { workflowQueue.UnregisterForQueueItemArrived(this.securityShim); this.securityShim = null; } workflowQueue.Enabled = false; } } finally { RemoveRequestContext(); } return base.Cancel(executionContext); } protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext"); } WorkflowQueuingService queuingService = executionContext.GetService(); if (queuingService == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(WorkflowQueuingService)))); } // make sure that we are getting the proper queue // even if that means creating a new queue // given our conversation context and execution context. // WorkflowQueue workflowQueue = GetWorkflowQueue(executionContext); if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_QueueNotFound, ((IEventActivity)this).QueueName))); } if (this.QueueInitializationMode == QueueInitializationMode.Standalone && workflowQueue.Count == 0) { workflowQueue.Enabled = true; if (this.securityShim == null) { this.securityShim = new SecurityShim(this); } workflowQueue.RegisterForQueueItemArrived(this.securityShim); workflowQueue.RegisterForQueueItemAvailable(this, this.QualifiedName); return ActivityExecutionStatus.Executing; } else if (workflowQueue.Count == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_RequestContextUnavailable, this.QualifiedName))); } WorkflowRequestContext requestContext = workflowQueue.Dequeue() as WorkflowRequestContext; if (requestContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_RequestContextUnavailable, this.QualifiedName))); } else { if (this.validationShim != null) { this.RequestContext = requestContext; CacheRequestContext(requestContext); } else if (ValidationShim.EvaluateSecurityConstraints(executionContext, this, requestContext) == true) { this.RequestContext = requestContext; CacheRequestContext(requestContext); if (this.QueueInitializationMode == QueueInitializationMode.Standalone) { workflowQueue.Enabled = false; } } else { try { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - message validation failed. Message will be discarded.", this.WorkflowInstanceId, this.QualifiedName); requestContext.SendFault(new FaultException(SR2.GetString(SR2.SecurityCheckFailed)), null); } catch (CommunicationException cex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault for rejected message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, cex); } catch (TimeoutException tex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault for rejected message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, tex); } if (requestContext.ContextProperties == null || !(requestContext.ContextProperties.Keys.Contains(WellKnownContextProperties.InstanceId))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new FaultException(SR2.GetString(SR2.Error_FailedToValidateActivatingMessage, this.WorkflowInstanceId))); } if (this.QueueInitializationMode == QueueInitializationMode.Standalone) { if (this.securityShim == null) { this.securityShim = new SecurityShim(this); } workflowQueue.RegisterForQueueItemArrived(this.securityShim); } workflowQueue.RegisterForQueueItemAvailable(this, this.QualifiedName); return ActivityExecutionStatus.Executing; } } return ExecuteActivity(this.RequestContext, executionContext); } [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Supress any exceptions thrown by SendFault to avoid calling HandleFault infinitely.")] protected override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception) { try { if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext"); } if (exception == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exception"); } if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext"); } WorkflowQueuingService queuingService = executionContext.GetService(); if (queuingService == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(WorkflowQueuingService)))); } WorkflowQueue workflowQueue = GetWorkflowQueue(executionContext); if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_QueueNotFound, ((IEventActivity)this).QueueName))); } workflowQueue.UnregisterForQueueItemAvailable(this); if (this.QueueInitializationMode == QueueInitializationMode.Standalone) { if (this.securityShim != null) { workflowQueue.UnregisterForQueueItemArrived(this.securityShim); this.securityShim = null; } workflowQueue.Enabled = false; } RestoreRequestContext(); if (this.RequestContext != null) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - sending fault response message", this.WorkflowInstanceId, this.QualifiedName); if (this.FaultMessage != null) { try { this.RequestContext.SendFault(this.FaultMessage, null); } catch { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send response fault message.", this.WorkflowInstanceId, this.QualifiedName); } } else { try { this.RequestContext.SendFault(exception, null); } catch { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send response fault message.", this.WorkflowInstanceId, this.QualifiedName); } } } } finally { RemoveRequestContext(); } return base.HandleFault(executionContext, exception); } protected override void InitializeProperties() { OperationInfoBase serviceOperationInfo = this.ServiceOperationInfo; if (serviceOperationInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name))); } OperationParameterInfoCollection parameters = null; Activity definitionRoot = base.RootActivity.GetValue(Activity.WorkflowDefinitionProperty) as Activity; if (definitionRoot != null) { ReceiveActivity definition = definitionRoot.GetActivityByName(this.QualifiedName, true) as ReceiveActivity; if ((definition != null) && definition.UserData.Contains(typeof(OperationParameterInfoCollection))) { parameters = definition.UserData[typeof(OperationParameterInfoCollection)] as OperationParameterInfoCollection; } } if (parameters == null) { parameters = serviceOperationInfo.GetParameters(this.Site); this.UserData[typeof(OperationParameterInfoCollection)] = parameters; } WorkflowParameterBindingCollection bindings = this.ParameterBindings; foreach (OperationParameterInfo parameter in parameters) { if (!bindings.Contains(parameter.Name)) { bindings.Add(new WorkflowParameterBinding(parameter.Name)); } } base.InitializeProperties(); } protected override void OnSequenceComplete(ActivityExecutionContext executionContext) { if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext"); } try { RestoreRequestContext(); if (this.RequestContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_RequestContextUnavailable, this.QualifiedName))); } object returnValue; object[] outputValues; if (this.FaultMessage != null) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - sending fault response message", this.WorkflowInstanceId, this.QualifiedName); try { this.RequestContext.SendFault(this.FaultMessage, null); } catch (CommunicationException cex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault response message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, cex); throw; } catch (TimeoutException tex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault response message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, tex); throw; } } else if (!this.OperationHelper.IsOneWay) { returnValue = this.OperationHelper.GetOutputs(this, out outputValues); System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - sending response message", this.WorkflowInstanceId, this.QualifiedName); try { this.RequestContext.SendReply(returnValue, outputValues, null); } catch (CommunicationException cex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send response message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, cex); throw; } catch (TimeoutException tex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send response message. Error: {2}", this.WorkflowInstanceId, this.QualifiedName, tex); throw; } } else { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - completing one way operation", this.WorkflowInstanceId, this.QualifiedName); this.RequestContext.SetOperationCompleted(); } base.OnSequenceComplete(executionContext); // Null out the request context to reduce serialization size of the activity. this.RequestContext = null; } finally { RemoveRequestContext(); } } static object GetWorkflowServiceAttributesValueOverride(object dependencyObject) { if (dependencyObject == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dependencyObject"); } if (!(dependencyObject is Activity)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "dependencyObject", SR2.GetString(SR2.Error_UnexpectedArgumentType, typeof(Activity).FullName)); } Activity activity = dependencyObject as Activity; if (activity.GetValueBase(ReceiveActivity.WorkflowServiceAttributesProperty) == null) { if (activity.DesignMode) { WorkflowServiceAttributes workflowServiceAttribsValue = new WorkflowServiceAttributes(); Activity rootActivity = activity.RootActivity; if (rootActivity != null) { string fullClassName = (String)rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty); if (!String.IsNullOrEmpty(fullClassName)) { string namespaceName; string className; Helpers.GetNamespaceAndClassName(fullClassName, out namespaceName, out className); workflowServiceAttribsValue.ConfigurationName = fullClassName; workflowServiceAttribsValue.Name = className; } } activity.SetValue(ReceiveActivity.WorkflowServiceAttributesProperty, workflowServiceAttribsValue); return workflowServiceAttribsValue; } } return activity.GetValueBase(ReceiveActivity.WorkflowServiceAttributesProperty); } private ActivityExecutionStatus ExecuteActivity(WorkflowRequestContext requestContext, ActivityExecutionContext executionContext) { if (requestContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestContext"); } if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("executionContext"); } System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - received message", this.WorkflowInstanceId, this.QualifiedName); this.OperationHelper.PopulateInputs(this, requestContext.Inputs); return base.Execute(executionContext); } private WorkflowQueue GetWorkflowQueue(IServiceProvider provider) { if (provider == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("provider"); } if (this.ServiceOperationInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, this.Name))); } WorkflowQueuingService queuingService = provider.GetService(typeof(WorkflowQueuingService)) as WorkflowQueuingService; if (queuingService == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(WorkflowQueuingService)))); } WorkflowQueue workflowQueue = null; string queueName = this.OperationHelper.GetWorkflowQueueName(this.Context); this.SetValue(QueueNameProperty, queueName); if (!queuingService.Exists(queueName)) { workflowQueue = queuingService.CreateWorkflowQueue(queueName, false); workflowQueue.Enabled = false; } else { workflowQueue = queuingService.GetWorkflowQueue(queueName); } return workflowQueue; } private void SetQueueInitializationMode() { if (this.parent != null && this.parent is EventDrivenActivity) { if (this.parent.parent != null && this.parent.parent is StateActivity) { this.QueueInitializationMode = QueueInitializationMode.StateMachine; } } } private void CacheRequestContext(WorkflowRequestContext requestContext) { string keyValue = WorkflowEnvironment.WorkflowInstanceId.ToString() + ":" + this.GetValue(ReceiveActivity.QueueNameProperty) as string; requestContextsCache[keyValue] = requestContext; this.isContextCached = true; } private void RestoreRequestContext() { string keyValue = WorkflowEnvironment.WorkflowInstanceId.ToString() + ":" + this.GetValue(ReceiveActivity.QueueNameProperty) as string; if (requestContextsCache.ContainsKey(keyValue)) { this.RequestContext = requestContextsCache[keyValue] as WorkflowRequestContext; } } private void RemoveRequestContext() { requestContextsCache.Remove(WorkflowEnvironment.WorkflowInstanceId.ToString() + ":" + this.GetValue(ReceiveActivity.QueueNameProperty) as string); } protected override void Dispose(bool disposing) { try { if (disposing && this.isContextCached) { RemoveRequestContext(); } } finally { base.Dispose(disposing); } } [Serializable] class ReceiveOperationInfoHelper { string baseQueueName; bool hasReturnValue = false; IList> inputParameters; bool isOneWay = false; IDictionary notNullableParameters; bool nullableReturnValue = true; string operationName; IList> outputParameters; string returnTypeName; public ReceiveOperationInfoHelper(IServiceProvider serviceProvider, ReceiveActivity activity) { outputParameters = new List>(); inputParameters = new List>(); notNullableParameters = new Dictionary(); hasReturnValue = false; nullableReturnValue = true; if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } OperationInfoBase serviceOperationInfo = activity.ServiceOperationInfo; if (serviceOperationInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ServiceOperationInfoNotSpecified, activity.Name))); } MethodInfo methodInfo = serviceOperationInfo.GetMethodInfo(serviceProvider); if (methodInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_MethodInfoNotAvailable, activity.Name))); } if (methodInfo.ReturnType != null && methodInfo.ReturnType != typeof(void)) { hasReturnValue = true; this.returnTypeName = methodInfo.ReturnType.FullName; nullableReturnValue = !((methodInfo.ReturnType.IsPrimitive || methodInfo.ReturnType.IsEnum || methodInfo.ReturnType.IsValueType) && !ServiceOperationHelpers.IsNullableType(methodInfo.ReturnType)); } foreach (ParameterInfo parameter in methodInfo.GetParameters()) { if (parameter.ParameterType.IsByRef || parameter.IsOut || (parameter.IsIn && parameter.IsOut)) { outputParameters.Add(new KeyValuePair(parameter.Position, parameter.Name)); if (parameter.ParameterType.IsByRef && parameter.ParameterType.GetElementType().IsValueType && !ServiceOperationHelpers.IsNullableType(parameter.ParameterType)) { notNullableParameters.Add(parameter.Position, parameter.ParameterType); } } if (!parameter.IsOut || (parameter.IsIn && parameter.IsOut)) { inputParameters.Add(new KeyValuePair(parameter.Position, parameter.Name)); } } this.operationName = serviceOperationInfo.Name; this.baseQueueName = QueueNameHelper.Create(methodInfo.DeclaringType, this.operationName); object[] operationContractAttribs = methodInfo.GetCustomAttributes(typeof(OperationContractAttribute), true); if (operationContractAttribs != null && operationContractAttribs.Length > 0) { if (operationContractAttribs[0] is OperationContractAttribute) { this.isOneWay = ((OperationContractAttribute)operationContractAttribs[0]).IsOneWay; } } } public bool IsOneWay { get { return this.isOneWay; } } public object GetOutputs(ReceiveActivity activity, out object[] outputs) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } outputs = new object[outputParameters.Count]; object returnValue = null; WorkflowParameterBindingCollection bindings = activity.ParameterBindings; for (int index = 0; index < outputParameters.Count; ++index) { KeyValuePair parameterInfo = outputParameters[index]; if (bindings[parameterInfo.Value].Value == null && this.notNullableParameters.Keys.Contains(parameterInfo.Key)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ReceiveActivityInvalidParameterValue, activity.Name, parameterInfo.Value, this.notNullableParameters[parameterInfo.Key]))); } outputs[index] = bindings[parameterInfo.Value].Value; } if (hasReturnValue) { if (bindings["(ReturnValue)"].Value == null && !this.nullableReturnValue) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ReceiveActivityInvalidReturnValue, activity.Name, this.returnTypeName))); } returnValue = bindings["(ReturnValue)"].Value; } return returnValue; } public string GetWorkflowQueueName(IDictionary context) { return QueueNameHelper.Create(this.baseQueueName, context); } public void PopulateInputs(ReceiveActivity activity, ReadOnlyCollection inputs) { if (activity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); } if (inputs == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inputs"); } WorkflowParameterBindingCollection bindings = activity.ParameterBindings; for (int index = 0; index < inputParameters.Count; index++) { KeyValuePair parameterInfo = inputParameters[index]; if (!bindings.Contains(parameterInfo.Value)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_ParameterBindingMissing, parameterInfo.Value, this.operationName, activity.Name))); } if (index >= inputs.Count) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_InputValueUnavailable, parameterInfo.Value, this.operationName, activity.Name))); } WorkflowParameterBinding parameterBinding = bindings[parameterInfo.Value]; parameterBinding.Value = inputs[index]; } } } [Serializable] class SecurityShim : IActivityEventListener, IDisposable { ReceiveActivity receiveActivity; internal SecurityShim(ReceiveActivity receiveActivity) { if (receiveActivity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("receiveActivity"); } this.receiveActivity = receiveActivity; } void IActivityEventListener.OnEvent(object sender, QueueEventArgs queueEventArgs) { if (sender == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sender"); } if (queueEventArgs == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("queueEventArgs"); } WorkflowQueue workflowQueue = sender as WorkflowQueue; if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentException(SR2.GetString(SR2.Error_ArgumentTypeInvalid, "sender", typeof(WorkflowQueue)))); } WorkflowRequestContext requestContext = workflowQueue.Peek() as WorkflowRequestContext; if (requestContext != null) { IDependencyObjectAccessor doa = (IDependencyObjectAccessor)receiveActivity; EventHandler[] eventHandlers = doa.GetInvocationList>( ReceiveActivity.OperationValidationEvent); if (eventHandlers != null && eventHandlers.Length > 0) { requestContext.PopulateAuthorizationState(); } } } void IDisposable.Dispose() { this.receiveActivity.Dispose(); GC.SuppressFinalize(this); } } [Serializable] class ValidationShim : IActivityEventListener, IDisposable { IActivityEventListener activityEventListener; ReceiveActivity receiveActivity; internal ValidationShim(ReceiveActivity receiveActivity, IActivityEventListener activityEventListener) { if (receiveActivity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("receiveActivity"); } if (activityEventListener == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activityEventListener"); } this.receiveActivity = receiveActivity; this.activityEventListener = activityEventListener; } void IActivityEventListener.OnEvent(object sender, QueueEventArgs queueEventArgs) { if (sender == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sender"); } if (queueEventArgs == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("queueEventArgs"); } ActivityExecutionContext executionContext = sender as ActivityExecutionContext; if (executionContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentException(SR2.GetString(SR2.Error_ArgumentTypeInvalid, "sender", typeof(ActivityExecutionContext)))); } WorkflowQueuingService queuingService = executionContext.GetService(); if (queuingService == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(WorkflowQueuingService)))); } WorkflowQueue workflowQueue = queuingService.GetWorkflowQueue(queueEventArgs.QueueName); if (workflowQueue == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.Error_QueueNotFound, queueEventArgs.QueueName))); } WorkflowRequestContext requestContext = workflowQueue.Peek() as WorkflowRequestContext; if (requestContext != null) { if (EvaluateSecurityConstraints(executionContext, this.receiveActivity, requestContext) == true) { this.activityEventListener.OnEvent(sender, queueEventArgs); } else { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Verbose, 0, "Workflow Instance {0}, receive activity {1} - message validation failed. Message will be discarded.", this.receiveActivity.WorkflowInstanceId, this.receiveActivity.QualifiedName); workflowQueue.Dequeue(); try { requestContext.SendFault(new FaultException(SR2.GetString(SR2.SecurityCheckFailed)), null); } catch (CommunicationException cex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault for rejected message. Error: {2}", this.receiveActivity.WorkflowInstanceId, this.receiveActivity.QualifiedName, cex); } catch (TimeoutException tex) { System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Instance {0}, receive activity {1} - failed to send fault for rejected message. Error: {2}", this.receiveActivity.WorkflowInstanceId, this.receiveActivity.QualifiedName, tex); } if (requestContext.ContextProperties == null || !(requestContext.ContextProperties.Keys.Contains(WellKnownContextProperties.InstanceId))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new FaultException(SR2.GetString(SR2.Error_FailedToValidateActivatingMessage, this.receiveActivity.WorkflowInstanceId))); } } } else { this.activityEventListener.OnEvent(sender, queueEventArgs); } } void IDisposable.Dispose() { this.receiveActivity.Dispose(); GC.SuppressFinalize(this); } internal static bool EvaluateSecurityConstraints(IServiceProvider serviceProvider, ReceiveActivity receiveActivity, WorkflowRequestContext requestContext) { bool retVal = true; if (serviceProvider == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceProvider"); } if (receiveActivity == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("receiveActivity"); } if (requestContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestContext"); } IDependencyObjectAccessor doa = (IDependencyObjectAccessor)receiveActivity; EventHandler[] eventHandlers = doa.GetInvocationList>( ReceiveActivity.OperationValidationEvent); if (eventHandlers != null && eventHandlers.Length > 0) { ReadOnlyCollection claims = requestContext.AuthorizationContext == null ? new ReadOnlyCollection(new List()) : requestContext.AuthorizationContext.ClaimSets; OperationValidationEventArgs e = new OperationValidationEventArgs(claims); receiveActivity.RaiseGenericEvent(ReceiveActivity.OperationValidationEvent, receiveActivity, e); retVal = e.IsValid; } return retVal; } } } }