internal override void InferMessageDescription(OperationDescription operation, object owner, MessageDirection direction)
        {
            ContractInferenceHelper.CheckForDisposableParameters(operation, this.InternalDeclaredMessageType);
            string           overridingAction       = null;
            SerializerOption dataContractSerializer = SerializerOption.DataContractSerializer;
            Send             send = owner as Send;

            if (send != null)
            {
                overridingAction       = send.Action;
                dataContractSerializer = send.SerializerOption;
            }
            else
            {
                SendReply reply = owner as SendReply;
                overridingAction       = reply.Action;
                dataContractSerializer = reply.Request.SerializerOption;
            }
            if (direction == MessageDirection.Input)
            {
                ContractInferenceHelper.AddInputMessage(operation, overridingAction, this.InternalDeclaredMessageType, dataContractSerializer);
            }
            else
            {
                ContractInferenceHelper.AddOutputMessage(operation, overridingAction, this.InternalDeclaredMessageType, dataContractSerializer);
            }
        }
        internal override void InferMessageDescription(OperationDescription operation, object owner, MessageDirection direction)
        {
            ContractInferenceHelper.CheckForDisposableParameters(operation, this.InternalDeclaredMessageType);

            string           overridingAction = null;
            SerializerOption serializerOption = SerializerOption.DataContractSerializer;
            Send             send             = owner as Send;

            if (send != null)
            {
                overridingAction = send.Action;
                serializerOption = send.SerializerOption;
            }
            else
            {
                SendReply sendReply = owner as SendReply;
                Fx.Assert(sendReply != null, "The owner of SendMessageContent can only be Send or SendReply!");
                overridingAction = sendReply.Action;
                serializerOption = sendReply.Request.SerializerOption;
            }

            if (direction == MessageDirection.Input)
            {
                ContractInferenceHelper.AddInputMessage(operation, overridingAction, this.InternalDeclaredMessageType, serializerOption);
            }
            else
            {
                ContractInferenceHelper.AddOutputMessage(operation, overridingAction, this.InternalDeclaredMessageType, serializerOption);
            }
        }
Beispiel #3
0
        static SendReply BuildFaultReplies(FaultDescription faultDescription, bool isMessageContract)
        {
            Fx.Assert(faultDescription != null, "fault Description cannot be null");
            if (faultDescription.DetailType == TypeHelper.VoidType || faultDescription.DetailType == null)
            {
                throw FxTrace.Exception.ArgumentNullOrEmpty("FaultDescription.DetailType");
            }

            SendReply faultReply = new SendReply()
            {
                DisplayName = faultDescription.Name + "SendFaultReply",
                Action      = faultDescription.Action,
            };

            Type[] substitute = { faultDescription.DetailType };
            Type   faultType  = typeof(FaultException <>).MakeGenericType(substitute);

            if (isMessageContract)
            {
                faultReply.Content = new SendMessageContent()
                {
                    Message = (InArgument)(InArgument.Create(faultType, ArgumentDirection.In)),
                };
            }
            else
            {
                InArgument            argument = (InArgument)(InArgument.Create(faultType, ArgumentDirection.In));
                SendParametersContent faultReplyParameterContent = new SendParametersContent();
                faultReplyParameterContent.Parameters.Add(faultDescription.Name, argument);
                faultReply.Content = faultReplyParameterContent;
            }

            return(faultReply);
        }
        public static OperationDescription CreateOperationDescription(Receive receive, ContractDescription contract)
        {
            OperationDescription operation = new OperationDescription(NamingHelper.XmlName(receive.OperationName), contract);

            if (receive.ProtectionLevel.HasValue)
            {
                operation.ProtectionLevel = receive.ProtectionLevel.Value;
            }
            receive.InternalContent.InferMessageDescription(operation, receive, MessageDirection.Input);
            if (receive.HasReply)
            {
                SendReply owner = receive.FollowingReplies[0];
                owner.InternalContent.InferMessageDescription(operation, owner, MessageDirection.Output);
            }
            else if (receive.HasFault)
            {
                CheckForDisposableParameters(operation, System.ServiceModel.Activities.Constants.EmptyTypeArray);
                AddOutputMessage(operation, null, System.ServiceModel.Activities.Constants.EmptyStringArray, System.ServiceModel.Activities.Constants.EmptyTypeArray);
            }
            PostProcessOperation(operation);
            AddSerializerProvider(operation, receive.SerializerOption);
            AddWorkflowOperationBehaviors(operation, receive.OperationBookmarkName, receive.CanCreateInstance);
            if (receive.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope)
            {
                operation.IsInsideTransactedReceiveScope = true;
                EnableTransactionBehavior(operation);
                if (receive.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree)
                {
                    operation.IsFirstReceiveOfTransactedReceiveScopeTree = true;
                }
            }
            return(operation);
        }
        internal override void ValidateContract(NativeActivityContext context, OperationDescription targetOperation, object owner, MessageDirection direction)
        {
            MessageDescription targetMessage;
            string             overridingAction;
            bool             isResponse;
            SerializerOption serializerOption;

            if (direction == MessageDirection.Input)
            {
                Fx.Assert(targetOperation.Messages.Count >= 1, "There must be at least one MessageDescription in an OperationDescription!");
                targetMessage = targetOperation.Messages[0];

                Send send = owner as Send;
                Fx.Assert(send != null, "The parent of a SendMessageContent with in-message can only be Send!");

                overridingAction = send.Action;
                serializerOption = send.SerializerOption;

                isResponse = false;
            }
            else
            {
                Fx.Assert(targetOperation.Messages.Count == 2, "There must be exactly two MessageDescription objects for a two-way operation!");
                targetMessage = targetOperation.Messages[1];

                SendReply sendReply = owner as SendReply;
                Fx.Assert(sendReply != null, "The parent of a SendMessageContent with out-message can only be SendReply!");
                Fx.Assert(sendReply.Request != null, "SendReply.Request should not be null by now!");
                overridingAction = sendReply.Action;
                serializerOption = sendReply.Request.SerializerOption;

                isResponse = true;
            }

            if (!this.IsFault)
            {
                ContractValidationHelper.ValidateAction(context, targetMessage, overridingAction, targetOperation, isResponse);
                if (ContractValidationHelper.IsSendParameterContent(targetOperation))
                {
                    Constraint.AddValidationError(context, new ValidationError(SR.MisuseOfMessageContent(targetOperation.Name, targetOperation.DeclaringContract.Name)));
                }
                else
                {
                    ContractValidationHelper.ValidateMessageContent(context, targetMessage, this.InternalDeclaredMessageType,
                                                                    serializerOption, targetOperation, isResponse);
                }
            }
            else
            {
                Fx.Assert(this.InternalDeclaredMessageType != null, "IsFault returns true only when argument is of exception type!");
                Type argumentType = this.InternalDeclaredMessageType;

                if (argumentType.IsGenericType && argumentType.GetGenericTypeDefinition() == ContractInferenceHelper.FaultExceptionType)
                {
                    Type faultType = argumentType.GetGenericArguments()[0];
                    ContractValidationHelper.ValidateFault(context, targetOperation, overridingAction, faultType);
                }
            }
        }
        public static void CorrectOutMessageForOperation(Receive receive, OperationDescription operation)
        {
            operation.Messages.RemoveAt(1);
            SendReply owner = receive.FollowingReplies[0];

            owner.InternalContent.InferMessageDescription(operation, owner, MessageDirection.Output);
            PostProcessOperation(operation);
        }
Beispiel #7
0
        private void CollectCorrelationQueryFromReply(ref Collection <CorrelationQuery> correlationQueries, XName serviceContractName, Activity reply, OperationDescription operation)
        {
            SendReply reply2 = reply as SendReply;

            if (reply2 != null)
            {
                CorrelationQuery correlationQuery = ContractInferenceHelper.CreateServerCorrelationQuery(null, reply2.CorrelationInitializers, operation, true);
                this.CollectCorrelationQuery(ref correlationQueries, serviceContractName, correlationQuery);
            }
        }
Beispiel #8
0
        public static void CorrectOutMessageForOperation(Receive receive, OperationDescription operation)
        {
            // Remove the original outMessage
            Fx.Assert(operation.Messages.Count == 2, "OperationDescription must be two-way for CorrectOutMessageForOperation to be invoked!");
            operation.Messages.RemoveAt(1);

            SendReply sendReply = receive.FollowingReplies[0];

            sendReply.InternalContent.InferMessageDescription(operation, sendReply, MessageDirection.Output);

            ContractInferenceHelper.PostProcessOperation(operation);
        }
 public OperationScope()
     : base()
 {
     assigns = new Collection<Assign>();
     variables = new Collection<Variable>();
     receive = new Receive()
     {
         Content = new ReceiveParametersContent()
     };
     reply = new SendReply()
     {
         Request = receive,
         Content = new SendParametersContent()
     };
 }
        public static void ValidateSendReplyWithSendReply(SendReply sendReply1, SendReply sendReply2)
        {
            Fx.Assert(sendReply1 != null && sendReply2 != null, "Validation argument cannot be null!");
            Fx.Assert(sendReply1.Request != null, "Request cannot be null in SendReply");
            string operationName = sendReply1.Request.OperationName;

            if (sendReply1.Action != sendReply2.Action)
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendRepliesWithSameNameButDifferentAction(operationName)));
            }

            if (sendReply1.InternalContent is SendMessageContent && sendReply2.InternalContent is SendMessageContent)
            {
                SendMessageContent sendMessage1 = sendReply1.InternalContent as SendMessageContent;
                SendMessageContent sendMessage2 = sendReply2.InternalContent as SendMessageContent;

                if (sendMessage1.InternalDeclaredMessageType != sendMessage2.InternalDeclaredMessageType)
                {
                    throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendRepliesWithSameNameButDifferentValueType(operationName)));
                }
            }
            else if (sendReply1.InternalContent is SendParametersContent && sendReply2.InternalContent is SendParametersContent)
            {
                SendParametersContent sendReplyParameters1 = sendReply1.InternalContent as SendParametersContent;
                SendParametersContent sendReplyParameters2 = sendReply2.InternalContent as SendParametersContent;

                int count = sendReplyParameters1.ArgumentNames.Length;
                if (count != sendReplyParameters2.ArgumentNames.Length)
                {
                    throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendReplyParametersWithSameNameButDifferentParameterCount(operationName)));
                }
                for (int i = 0; i < count; i++)
                {
                    if (sendReplyParameters1.ArgumentNames[i] != sendReplyParameters2.ArgumentNames[i])
                    {
                        throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendReplyParametersWithSameNameButDifferentParameterName(operationName)));
                    }
                    if (sendReplyParameters1.ArgumentTypes[i] != sendReplyParameters2.ArgumentTypes[i])
                    {
                        throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendReplyParametersWithSameNameButDifferentParameterType(operationName)));
                    }
                }
            }
            else
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.ReceivePairedWithSendReplyAndSendReplyParameters(operationName)));
            }
        }
Beispiel #11
0
        // Create server side OperationDescription.
        // Note this method assumes that CacheMetadata has been called on the Receive activity (as part of
        // the activity tree walk that is done in WorkflowService.GetContractDescriptions) because it relies on
        // InternalReceiveMessage property of the Receive actitivy to be non-null.
        public static OperationDescription CreateOperationDescription(Receive receive, ContractDescription contract)
        {
            Fx.Assert(receive.InternalReceive != null, "This method can only be called if CacheMetadata has been called on the receive activity");

            OperationDescription operation = new OperationDescription(NamingHelper.XmlName(receive.OperationName), contract);

            if (receive.ProtectionLevel.HasValue)
            {
                operation.ProtectionLevel = receive.ProtectionLevel.Value;
            }

            // Infer In-Message
            receive.InternalContent.InferMessageDescription(operation, receive, MessageDirection.Input);

            // Infer Out-Message
            if (receive.HasReply)
            {
                // At this point, we already know all the following SendReplies are equivalent
                SendReply sendReply = receive.FollowingReplies[0];
                sendReply.InternalContent.InferMessageDescription(operation, sendReply, MessageDirection.Output);
            }
            else if (receive.HasFault)
            {
                // We infer Receive-SendFault pair as a two-way operation with void return value
                CheckForDisposableParameters(operation, Constants.EmptyTypeArray);
                AddOutputMessage(operation, null, Constants.EmptyStringArray, Constants.EmptyTypeArray);
            }

            PostProcessOperation(operation);

            // Behaviors
            AddSerializerProvider(operation, receive.SerializerOption);
            AddWorkflowOperationBehaviors(operation, receive.InternalReceive.OperationBookmarkName, receive.CanCreateInstance);

            if (receive.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope)
            {
                operation.IsInsideTransactedReceiveScope = true;
                EnableTransactionBehavior(operation);
                if (receive.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree)
                {
                    operation.IsFirstReceiveOfTransactedReceiveScopeTree = true;
                }
            }

            return(operation);
        }
Beispiel #12
0
        public static void ValidateSendReplyWithSendReply(SendReply sendReply1, SendReply sendReply2)
        {
            string operationName = sendReply1.Request.OperationName;

            if (sendReply1.Action != sendReply2.Action)
            {
                throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.TwoSendRepliesWithSameNameButDifferentAction(operationName)));
            }
            if ((sendReply1.InternalContent is SendMessageContent) && (sendReply2.InternalContent is SendMessageContent))
            {
                SendMessageContent internalContent = sendReply1.InternalContent as SendMessageContent;
                SendMessageContent content2        = sendReply2.InternalContent as SendMessageContent;
                if (internalContent.InternalDeclaredMessageType != content2.InternalDeclaredMessageType)
                {
                    throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.TwoSendRepliesWithSameNameButDifferentValueType(operationName)));
                }
            }
            else
            {
                if (!(sendReply1.InternalContent is SendParametersContent) || !(sendReply2.InternalContent is SendParametersContent))
                {
                    throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.ReceivePairedWithSendReplyAndSendReplyParameters(operationName)));
                }
                SendParametersContent content3 = sendReply1.InternalContent as SendParametersContent;
                SendParametersContent content4 = sendReply2.InternalContent as SendParametersContent;
                int length = content3.ArgumentNames.Length;
                if (length != content4.ArgumentNames.Length)
                {
                    throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.TwoSendReplyParametersWithSameNameButDifferentParameterCount(operationName)));
                }
                for (int i = 0; i < length; i++)
                {
                    if (content3.ArgumentNames[i] != content4.ArgumentNames[i])
                    {
                        throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.TwoSendReplyParametersWithSameNameButDifferentParameterName(operationName)));
                    }
                    if (content3.ArgumentTypes[i] != content4.ArgumentTypes[i])
                    {
                        throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.TwoSendReplyParametersWithSameNameButDifferentParameterType(operationName)));
                    }
                }
            }
        }
        public static SendReply FromOperationDescription(OperationDescription operation, out IEnumerable<SendReply> faultReplies)
        {
            if (operation == null)
            {
                throw FxTrace.Exception.ArgumentNull("operation", "OperationDescription cannot be null");
            }

            bool contentIsParameter = false;
            bool contentIsMessage = false; 
            bool isSendContentEmpty = false;
            
            MessageDescription message;

            faultReplies = null; 
            List<SendReply> faultRepliesList = new List<SendReply>();
            SendReply reply = null;
            
            if (operation.IsOneWay)
            {
                return null;
            }

            if (operation.Messages.Count > 1)
            {
                reply = new SendReply();
                reply.Action = operation.Messages[1].Action;
                reply.DisplayName = operation.Name + "SendReply";

                message = operation.Messages[1];

                contentIsParameter = false;

                if (message.MessageType == null)
                {
                    if (message.Body.ReturnValue != null && message.Body.ReturnValue.Type != typeof(void))
                    {
                        if (!message.Body.ReturnValue.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                        {
                            contentIsParameter = true;
                        }

                        isSendContentEmpty = true;
                    }
                }

                if (message.MessageType == null)
                {
                    if (message.Body.Parts != null)
                    {
                        if (message.Body.Parts.Count > 0)
                        {
                            MessagePartDescriptionCollection parts = message.Body.Parts;
                            foreach (MessagePartDescription messagePart in parts)
                            {
                                if (messagePart.Index >= 0)
                                {
                                    contentIsParameter = true;
                                    break;
                                }
                                if (!messagePart.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                                {
                                    contentIsParameter = true;
                                }
                            }
                            isSendContentEmpty = true;
                        }
                    }
                }

                if (isSendContentEmpty)
                {
                    if (contentIsParameter)
                    {
                        SendParametersContent content = new SendParametersContent();
                        if (message.Direction == MessageDirection.Output
                            && message.Body.ReturnValue != null
                            && message.Body.ReturnValue.Type != typeof(void))
                        {
                            Argument returnArgument = InArgument.Create(message.Body.ReturnValue.Type, ArgumentDirection.In);
                            content.Parameters.Add(message.Body.ReturnValue.Name, (InArgument)returnArgument);
                        }

                        if (message.Direction == MessageDirection.Output && message.Body.Parts != null)
                        {
                            foreach (MessagePartDescription messagePart in message.Body.Parts)
                            {
                                Argument inArgument = InArgument.Create(messagePart.Type, ArgumentDirection.In);
                                content.Parameters.Add(messagePart.Name, (InArgument)(inArgument));
                            }
                        }
                        contentIsMessage = false;
                        reply.Content = content;
                    }
                    else
                    {
                        // We must have an untyped message contract
                        // 
                        SendMessageContent content = new SendMessageContent();
                        if (message.Direction == MessageDirection.Output)
                        {
                            content.DeclaredMessageType = message.Body.ReturnValue.Type;
                            Argument inArgument = InArgument.Create(content.DeclaredMessageType, ArgumentDirection.In);
                            content.Message = (InArgument)(inArgument);
                        }
                        contentIsMessage = true; 
                        reply.Content = content;
                    }
                }
                else
                {
                    if (message.MessageType != null && message.MessageType.IsDefined(typeof(MessageContractAttribute), false))
                    {
                        SendMessageContent sendMessageContent;
                        sendMessageContent = new SendMessageContent();
                        sendMessageContent.DeclaredMessageType = message.MessageType;
                        Argument inArgument = InArgument.Create(sendMessageContent.DeclaredMessageType, ArgumentDirection.In);
                        sendMessageContent.Message = (InArgument)(inArgument);
                        reply.Content = sendMessageContent;
                        contentIsMessage = true; 
                    }
                    else if (operation.Messages[0].MessageType != null)
                    {
                        reply.Content = new SendMessageContent();
                        contentIsMessage = true; 
                    }
                    else if (operation.Messages[0].Body.Parts != null
                        && operation.Messages[0].Body.Parts.Count == 1
                        && operation.Messages[0].Body.Parts[0].Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                    {
                        reply.Content = new SendMessageContent();
                        contentIsMessage = true; 
                    }
                    else
                    {
                        reply.Content = new SendParametersContent();
                        contentIsMessage = false; 
                    }
                }
            }

            if (operation.Faults != null)
            {
                foreach (FaultDescription faultDescription in operation.Faults)
                {
                    faultRepliesList.Add(BuildFaultReplies(faultDescription, contentIsMessage));
                }
            }

            faultReplies = faultRepliesList;

            return reply;
        }
        public static void ValidateSendReplyWithSendReply(SendReply sendReply1, SendReply sendReply2)
        {
            Fx.Assert(sendReply1 != null && sendReply2 != null, "Validation argument cannot be null!");
            Fx.Assert(sendReply1.Request != null, "Request cannot be null in SendReply");
            string operationName = sendReply1.Request.OperationName;

            if (sendReply1.Action != sendReply2.Action)
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendRepliesWithSameNameButDifferentAction(operationName)));
            }

            if (sendReply1.InternalContent is SendMessageContent && sendReply2.InternalContent is SendMessageContent)
            {
                SendMessageContent sendMessage1 = sendReply1.InternalContent as SendMessageContent;
                SendMessageContent sendMessage2 = sendReply2.InternalContent as SendMessageContent;

                if (sendMessage1.InternalDeclaredMessageType != sendMessage2.InternalDeclaredMessageType)
                {
                    throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendRepliesWithSameNameButDifferentValueType(operationName)));
                }
            }
            else if (sendReply1.InternalContent is SendParametersContent && sendReply2.InternalContent is SendParametersContent)
            {
                SendParametersContent sendReplyParameters1 = sendReply1.InternalContent as SendParametersContent;
                SendParametersContent sendReplyParameters2 = sendReply2.InternalContent as SendParametersContent;

                int count = sendReplyParameters1.ArgumentNames.Length;
                if (count != sendReplyParameters2.ArgumentNames.Length)
                {
                    throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendReplyParametersWithSameNameButDifferentParameterCount(operationName)));
                }
                for (int i = 0; i < count; i++)
                {
                    if (sendReplyParameters1.ArgumentNames[i] != sendReplyParameters2.ArgumentNames[i])
                    {
                        throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendReplyParametersWithSameNameButDifferentParameterName(operationName)));
                    }
                    if (sendReplyParameters1.ArgumentTypes[i] != sendReplyParameters2.ArgumentTypes[i])
                    {
                        throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoSendReplyParametersWithSameNameButDifferentParameterType(operationName)));
                    }
                }
            }
            else
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.ReceivePairedWithSendReplyAndSendReplyParameters(operationName)));
            }
        }
        static SendReply BuildFaultReplies(FaultDescription faultDescription, bool isMessageContract)
        {
            Fx.Assert(faultDescription != null, "fault Description cannot be null");
            if (faultDescription.DetailType == TypeHelper.VoidType || faultDescription.DetailType == null)
            {
                throw FxTrace.Exception.ArgumentNullOrEmpty("FaultDescription.DetailType");
            }

            SendReply faultReply = new SendReply()
            {
                DisplayName = faultDescription.Name + "SendFaultReply",
                Action = faultDescription.Action,
            };

            Type[] substitute = { faultDescription.DetailType };
            Type faultType = typeof(FaultException<>).MakeGenericType(substitute);
            if (isMessageContract)
            {
                faultReply.Content = new SendMessageContent()
                {
                    Message = (InArgument)(InArgument.Create(faultType, ArgumentDirection.In)),
                };
            }
            else
            {
                InArgument argument = (InArgument)(InArgument.Create(faultType, ArgumentDirection.In));
                SendParametersContent faultReplyParameterContent = new SendParametersContent();
                faultReplyParameterContent.Parameters.Add(faultDescription.Name, argument);
                faultReply.Content = faultReplyParameterContent;
            }

            return faultReply;
        }
Beispiel #16
0
 private void WalkActivityTree()
 {
     if (this.knownServiceActivities == null)
     {
         if (this.Body == null)
         {
             throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new ValidationException(System.ServiceModel.Activities.SR.MissingBodyInWorkflowService));
         }
         WorkflowInspectionServices.CacheMetadata(this.Body);
         this.knownServiceActivities = new List <Receive>();
         this.receiveAndReplyPairs   = new HashSet <ReceiveAndReplyTuple>();
         Queue <QueueItem> queue = new Queue <QueueItem>();
         queue.Enqueue(new QueueItem(this.Body, null, null));
         while (queue.Count > 0)
         {
             QueueItem item     = queue.Dequeue();
             Activity  activity = item.Activity;
             TransactedReceiveScope parentTransactedReceiveScope = item.ParentTransactedReceiveScope;
             TransactedReceiveScope rootTransactedReceiveScope   = item.RootTransactedReceiveScope;
             if (activity is Receive)
             {
                 Receive receive = (Receive)activity;
                 if (rootTransactedReceiveScope != null)
                 {
                     receive.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope = true;
                     if ((receive == parentTransactedReceiveScope.Request) && (parentTransactedReceiveScope == rootTransactedReceiveScope))
                     {
                         receive.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree = true;
                     }
                 }
                 this.knownServiceActivities.Add(receive);
             }
             else if (activity is SendReply)
             {
                 SendReply reply   = (SendReply)activity;
                 Receive   request = reply.Request;
                 if (reply.InternalContent.IsFault)
                 {
                     request.FollowingFaults.Add(reply);
                 }
                 else
                 {
                     if (request.HasReply)
                     {
                         SendReply reply2 = request.FollowingReplies[0];
                         ContractValidationHelper.ValidateSendReplyWithSendReply(reply2, reply);
                     }
                     request.FollowingReplies.Add(reply);
                 }
                 ReceiveAndReplyTuple tuple = new ReceiveAndReplyTuple(request, reply);
                 this.receiveAndReplyPairs.Add(tuple);
             }
             if (activity is TransactedReceiveScope)
             {
                 parentTransactedReceiveScope = activity as TransactedReceiveScope;
                 if (rootTransactedReceiveScope == null)
                 {
                     rootTransactedReceiveScope = parentTransactedReceiveScope;
                 }
             }
             foreach (Activity activity2 in WorkflowInspectionServices.GetActivities(activity))
             {
                 QueueItem item2 = new QueueItem(activity2, parentTransactedReceiveScope, rootTransactedReceiveScope);
                 queue.Enqueue(item2);
             }
         }
     }
 }
Beispiel #17
0
        public static SendReply FromOperationDescription(OperationDescription operation, out IEnumerable <SendReply> faultReplies)
        {
            if (operation == null)
            {
                throw FxTrace.Exception.ArgumentNull("operation", "OperationDescription cannot be null");
            }

            bool contentIsParameter = false;
            bool contentIsMessage   = false;
            bool isSendContentEmpty = false;

            MessageDescription message;

            faultReplies = null;
            List <SendReply> faultRepliesList = new List <SendReply>();
            SendReply        reply            = null;

            if (operation.IsOneWay)
            {
                return(null);
            }

            if (operation.Messages.Count > 1)
            {
                reply             = new SendReply();
                reply.Action      = operation.Messages[1].Action;
                reply.DisplayName = operation.Name + "SendReply";

                message = operation.Messages[1];

                contentIsParameter = false;

                if (message.MessageType == null)
                {
                    if (message.Body.ReturnValue != null && message.Body.ReturnValue.Type != typeof(void))
                    {
                        if (!message.Body.ReturnValue.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                        {
                            contentIsParameter = true;
                        }

                        isSendContentEmpty = true;
                    }
                }

                if (message.MessageType == null)
                {
                    if (message.Body.Parts != null)
                    {
                        if (message.Body.Parts.Count > 0)
                        {
                            MessagePartDescriptionCollection parts = message.Body.Parts;
                            foreach (MessagePartDescription messagePart in parts)
                            {
                                if (messagePart.Index >= 0)
                                {
                                    contentIsParameter = true;
                                    break;
                                }
                                if (!messagePart.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                                {
                                    contentIsParameter = true;
                                }
                            }
                            isSendContentEmpty = true;
                        }
                    }
                }

                if (isSendContentEmpty)
                {
                    if (contentIsParameter)
                    {
                        SendParametersContent content = new SendParametersContent();
                        if (message.Direction == MessageDirection.Output &&
                            message.Body.ReturnValue != null &&
                            message.Body.ReturnValue.Type != typeof(void))
                        {
                            Argument returnArgument = InArgument.Create(message.Body.ReturnValue.Type, ArgumentDirection.In);
                            content.Parameters.Add(message.Body.ReturnValue.Name, (InArgument)returnArgument);
                        }

                        if (message.Direction == MessageDirection.Output && message.Body.Parts != null)
                        {
                            foreach (MessagePartDescription messagePart in message.Body.Parts)
                            {
                                Argument inArgument = InArgument.Create(messagePart.Type, ArgumentDirection.In);
                                content.Parameters.Add(messagePart.Name, (InArgument)(inArgument));
                            }
                        }
                        contentIsMessage = false;
                        reply.Content    = content;
                    }
                    else
                    {
                        // We must have an untyped message contract
                        //
                        SendMessageContent content = new SendMessageContent();
                        if (message.Direction == MessageDirection.Output)
                        {
                            content.DeclaredMessageType = message.Body.ReturnValue.Type;
                            Argument inArgument = InArgument.Create(content.DeclaredMessageType, ArgumentDirection.In);
                            content.Message = (InArgument)(inArgument);
                        }
                        contentIsMessage = true;
                        reply.Content    = content;
                    }
                }
                else
                {
                    if (message.MessageType != null && message.MessageType.IsDefined(typeof(MessageContractAttribute), false))
                    {
                        SendMessageContent sendMessageContent;
                        sendMessageContent = new SendMessageContent();
                        sendMessageContent.DeclaredMessageType = message.MessageType;
                        Argument inArgument = InArgument.Create(sendMessageContent.DeclaredMessageType, ArgumentDirection.In);
                        sendMessageContent.Message = (InArgument)(inArgument);
                        reply.Content    = sendMessageContent;
                        contentIsMessage = true;
                    }
                    else if (operation.Messages[0].MessageType != null)
                    {
                        reply.Content    = new SendMessageContent();
                        contentIsMessage = true;
                    }
                    else if (operation.Messages[0].Body.Parts != null &&
                             operation.Messages[0].Body.Parts.Count == 1 &&
                             operation.Messages[0].Body.Parts[0].Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                    {
                        reply.Content    = new SendMessageContent();
                        contentIsMessage = true;
                    }
                    else
                    {
                        reply.Content    = new SendParametersContent();
                        contentIsMessage = false;
                    }
                }
            }

            if (operation.Faults != null)
            {
                foreach (FaultDescription faultDescription in operation.Faults)
                {
                    faultRepliesList.Add(BuildFaultReplies(faultDescription, contentIsMessage));
                }
            }

            faultReplies = faultRepliesList;

            return(reply);
        }