protected override void Execute(NativeActivityContext context)
        {
            CorrelationHandle correlationHandle = (this.Correlation == null) ? null : this.Correlation.Get(context);

            if (correlationHandle == null)
            {
                //throw only if ambient correlation handle is also null
                correlationHandle = context.Properties.Find(CorrelationHandle.StaticExecutionPropertyName) as CorrelationHandle;
                if (correlationHandle == null)
                {
                    throw FxTrace.Exception.AsError(
                              new InvalidOperationException(SR2.NullCorrelationHandleInInitializeCorrelation(this.DisplayName)));
                }
            }

            CorrelationExtension extension = context.GetExtension <CorrelationExtension>();

            if (extension != null)
            {
                Dictionary <string, string> dictionary = new Dictionary <string, string>();
                foreach (KeyValuePair <string, InArgument <string> > pair in this.CorrelationData)
                {
                    Fx.Assert(pair.Value != null, "pair.Value should be validated during cache metadata");
                    dictionary.Add(pair.Key, pair.Value.Get(context));
                }

                correlationHandle.InitializeBookmarkScope(context, extension.GenerateKey(dictionary));
            }
            else
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.InitializeCorrelationRequiresWorkflowServiceHost(this.DisplayName)));
            }
        }
 public static OperationExecutionFault CreateTransactedLockException(Guid instanceId, string operationName)
 {
     if (instanceLockedFaultCode == null)
     {
         instanceLockedFaultCode = new FaultCode(XD2.WorkflowControlServiceFaults.InstanceLockedUnderTransaction, XD2.WorkflowServices.Namespace);
     }
     return(new OperationExecutionFault(SR2.InstanceLockedUnderTransaction(operationName, instanceId), instanceLockedFaultCode));
 }
 public static OperationExecutionFault CreateOperationNotAvailableFault(Guid instanceId, string operationName)
 {
     if (operationNotAvailableFaultCode == null)
     {
         operationNotAvailableFaultCode = new FaultCode(XD2.WorkflowControlServiceFaults.OperationNotAvailable, XD2.WorkflowServices.Namespace);
     }
     return(new OperationExecutionFault(SR2.OperationNotAvailable(operationName, instanceId), operationNotAvailableFaultCode));
 }
 public static OperationExecutionFault CreateSuspendedFault(Guid instanceId, string operationName)
 {
     if (instanceSuspendedFaultCode == null)
     {
         instanceSuspendedFaultCode = new FaultCode(XD2.WorkflowControlServiceFaults.InstanceSuspended, XD2.WorkflowServices.Namespace);
     }
     return(new OperationExecutionFault(SR2.InstanceSuspended(operationName, instanceId), instanceSuspendedFaultCode));
 }
        static void ValidateReceiveWithReceive(ReceiveMessageContent receive1, ReceiveMessageContent receive2, string receiveOperationName)
        {
            Fx.Assert(receive1 != null && receive2 != null, "Validation argument cannot be null!");

            if (receive1.InternalDeclaredMessageType != receive2.InternalDeclaredMessageType)
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceivesWithSameNameButDifferentValueType(receiveOperationName)));
            }
        }
 public static void ValidateAction(NativeActivityContext context, MessageDescription targetMessage, string overridingAction,
                                   OperationDescription targetOperation, bool isResponse)
 {
     if (overridingAction == null && targetMessage.Action != NamingHelper.GetMessageAction(targetOperation, isResponse) ||
         overridingAction != null && overridingAction != targetMessage.Action)
     {
         Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(overridingAction, "Action", targetMessage.Action, targetOperation.Name, targetOperation.DeclaringContract.Name)));
     }
 }
示例#7
0
 protected override void CacheMetadata(NativeActivityMetadata metadata)
 {
     if (this.Request == null)
     {
         metadata.AddValidationError(new ValidationError(SR2.TransactedReceiveScopeMustHaveValidReceive(this.DisplayName), false, RequestPropertyName));
     }
     metadata.AddChild(this.Request);
     metadata.AddChild(this.Body);
     metadata.SetVariablesCollection(this.Variables);
     metadata.AddImplementationVariable(this.transactionHandle);
     metadata.AddImplementationVariable(this.isNested);
 }
        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)));
            }
        }
        public static void ValidateReceiveWithReceive(Receive receive1, Receive receive2)
        {
            Fx.Assert(receive1 != null && receive2 != null, "Validation argument cannot be null!");
            Fx.Assert(receive1.OperationName != null, "OperationName cannot be null in Receive");
            string receiveOperationName = receive1.OperationName;

            if (receive1.Action != receive2.Action)
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceivesWithSameNameButDifferentAction(receiveOperationName)));
            }

            if (receive1.InternalContent is ReceiveMessageContent && receive2.InternalContent is ReceiveMessageContent)
            {
                ReceiveMessageContent receiveMessage1 = receive1.InternalContent as ReceiveMessageContent;
                ReceiveMessageContent receiveMessage2 = receive2.InternalContent as ReceiveMessageContent;

                ValidateReceiveWithReceive(receiveMessage1, receiveMessage2, receiveOperationName);
            }
            else if (receive1.InternalContent is ReceiveParametersContent && receive2.InternalContent is ReceiveParametersContent)
            {
                ReceiveParametersContent receiveParameters1 = receive1.InternalContent as ReceiveParametersContent;
                ReceiveParametersContent receiveParameters2 = receive2.InternalContent as ReceiveParametersContent;

                ValidateReceiveParametersWithReceiveParameters(receiveParameters1, receiveParameters2, receiveOperationName);
            }
            else
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.ReceiveAndReceiveParametersHaveSameName(receiveOperationName)));
            }

            if (receive1.HasReply && receive2.HasReply)
            {
                ValidateSendReplyWithSendReply(receive1.FollowingReplies[0], receive2.FollowingReplies[0]);
            }
            else if ((receive1.HasReply || receive1.HasFault) != (receive2.HasReply || receive2.HasFault))
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceivesWithSameNameButDifferentIsOneWay(receiveOperationName)));
            }

            if ((receive1.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope != receive2.InternalReceive.AdditionalData.IsInsideTransactedReceiveScope) ||
                (receive1.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree != receive2.InternalReceive.AdditionalData.IsFirstReceiveOfTransactedReceiveScopeTree))
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceivesWithSameNameButDifferentTxProperties(receiveOperationName)));
            }
        }
        public static void ValidateFault(NativeActivityContext context, OperationDescription targetOperation, string overridingAction, Type faultType)
        {
            bool faultTypeExistOnContract = false;

            for (int index = 0; index < targetOperation.Faults.Count; index++)
            {
                FaultDescription targetFault = targetOperation.Faults[index];

                if (targetFault.DetailType == faultType)
                {
                    string name   = NamingHelper.TypeName(faultType) + TypeLoader.FaultSuffix;
                    string action = overridingAction ?? NamingHelper.GetMessageAction(targetOperation, false) + name;

                    if (targetFault.Action != action)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(action, "Fault Action", targetFault.Action, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                    }
                    if (targetFault.Name != NamingHelper.XmlName(name))
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(NamingHelper.XmlName(name), "Fault Name", targetFault.Name, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                    }
                    if (targetFault.Namespace != targetOperation.DeclaringContract.Namespace)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(targetOperation.DeclaringContract.Namespace, "Fault Namespace", targetFault.Namespace, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                    }
                    if (targetFault.HasProtectionLevel)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.ProtectionLevelNotSupported(targetOperation.Name, targetOperation.DeclaringContract.Name)));
                    }

                    // TypeLoader guarantees that fault types are unique in the Faults collection.
                    faultTypeExistOnContract = true;
                    break;
                }
            }

            // It is OK to have fewer fault types than defined on the contract.
            // But we do not allow workflow to define more fault types than specified on the contract.
            if (!faultTypeExistOnContract)
            {
                Constraint.AddValidationError(context, new ValidationError(SR2.FaultTypeMismatch(faultType.FullName, targetOperation.Name, targetOperation.DeclaringContract.Name)));
            }
        }
 public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 {
     // Validate that ReceiveContext.ManualControl is set for each operation
     foreach (ServiceEndpoint serviceEndpoint in serviceDescription.Endpoints)
     {
         if (BufferedReceiveServiceBehavior.IsWorkflowEndpoint(serviceEndpoint))
         {
             foreach (OperationDescription operation in serviceEndpoint.Contract.Operations)
             {
                 ReceiveContextEnabledAttribute receiveContextEnabled = operation.Behaviors.Find <ReceiveContextEnabledAttribute>();
                 if (receiveContextEnabled == null || !receiveContextEnabled.ManualControl)
                 {
                     throw FxTrace.Exception.AsError(
                               new InvalidOperationException(SR.BufferedReceiveRequiresReceiveContext(operation.Name)));
                 }
             }
         }
     }
 }
        static void ValidateReceiveParametersWithReceiveParameters(ReceiveParametersContent receiveParameters1, ReceiveParametersContent receiveParameters2, string receiveOperationName)
        {
            Fx.Assert(receiveParameters1 != null && receiveParameters2 != null, "Validation argument cannot be null!");

            int count = receiveParameters1.ArgumentNames.Length;

            if (count != receiveParameters2.ArgumentNames.Length)
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceiveParametersWithSameNameButDifferentParameterCount(receiveOperationName)));
            }
            for (int i = 0; i < count; i++)
            {
                if (receiveParameters1.ArgumentNames[i] != receiveParameters2.ArgumentNames[i])
                {
                    throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceiveParametersWithSameNameButDifferentParameterName(receiveOperationName)));
                }
                if (receiveParameters1.ArgumentTypes[i] != receiveParameters2.ArgumentTypes[i])
                {
                    throw FxTrace.Exception.AsError(new ValidationException(SR2.TwoReceiveParametersWithSameNameButDifferentParameterType(receiveOperationName)));
                }
            }
        }
示例#13
0
        protected override void Execute(NativeActivityContext context)
        {
            if (this.Request == null)
            {
                throw FxTrace.Exception.AsError(new ValidationException(SR2.TransactedReceiveScopeRequiresReceive(this.DisplayName)));
            }
            // we have to do this in code since we aren't fully modeled (in order for
            // dynamic update to work correctly)
            RuntimeTransactionHandle handleInstance = this.transactionHandle.Get(context);

            Fx.Assert(handleInstance != null, "RuntimeTransactionHandle is null");

            //This is used by InternalReceiveMessage to update the InitiatingTransaction so that we can later call Commit/Complete on it
            context.Properties.Add(TransactedReceiveData.TransactedReceiveDataExecutionPropertyName, new TransactedReceiveData());

            RuntimeTransactionHandle foundHandle = context.Properties.Find(handleInstance.ExecutionPropertyName) as RuntimeTransactionHandle;

            if (foundHandle == null)
            {
                context.Properties.Add(handleInstance.ExecutionPropertyName, handleInstance);
            }
            else
            {
                //nested case
                if (foundHandle.SuppressTransaction)
                {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.CannotNestTransactedReceiveScopeWhenAmbientHandleIsSuppressed(this.DisplayName)));
                }

                // Verify if TRS is root and if the foundHandle is not from the parent HandleScope<RTH>
                if (foundHandle.GetCurrentTransaction(context) != null)
                {
                    handleInstance = foundHandle;
                    this.isNested.Set(context, true);
                }
            }
            context.ScheduleActivity(this.Request, new CompletionCallback(OnReceiveCompleted));
        }
示例#14
0
        // both receive and send initialize correlations using this method
        // if selectHandle is not null, we first try to initalize instanceKey with it , else we try to initalize the ambient handle
        // if ambient handle is not used for initializing instance key , we might use it for initalizing  queryCorrelationsInitalizer.

        // SelectHandle usage:
        // Receive: selectHandle is the correlatesWith handle
        // SendReply: in case of context based correlation, this is the context handle
        // Send: in case of context based correlation, this will be the callback handle
        // ReceiveReply: selectHandle will be always null
        // Note that only Receive can initialize a content based correlation with a selectHandle (parallel convoy)
        internal static void InitializeCorrelationHandles(NativeActivityContext context,
                                                          CorrelationHandle selectHandle, CorrelationHandle ambientHandle, Collection <CorrelationInitializer> additionalCorrelations,
                                                          InstanceKey instanceKey, ICollection <InstanceKey> additionalKeys)
        {
            bool isAmbientHandleUsed = false;

            if (instanceKey != null && instanceKey.IsValid)
            {
                if (selectHandle != null)
                {
                    selectHandle.InitializeBookmarkScope(context, instanceKey);
                }
                else if (ambientHandle != null)
                {
                    ambientHandle.InitializeBookmarkScope(context, instanceKey);
                    isAmbientHandleUsed = true;
                }
                else if (context.DefaultBookmarkScope.IsInitialized)
                {
                    if (context.DefaultBookmarkScope.Id != instanceKey.Value)
                    {
                        throw FxTrace.Exception.AsError(
                                  new InvalidOperationException(SR2.CorrelationHandleInUse(context.DefaultBookmarkScope.Id, instanceKey.Value)));
                    }
                }
                else
                {
                    context.DefaultBookmarkScope.Initialize(context, instanceKey.Value);
                }
            }

            if (additionalKeys != null && additionalCorrelations != null)
            {
                // The ordering of items in SelectAdditional and additional correlations are the same
                // Therefore, we assign keys iteratively

                IEnumerator <CorrelationInitializer> enumerator = additionalCorrelations.GetEnumerator();

                foreach (InstanceKey key in additionalKeys)
                {
                    Fx.Assert(key != null && key.IsValid, "only valid keys should be passed into InitializeCorrelationHandles");

                    while (enumerator.MoveNext())
                    {
                        QueryCorrelationInitializer queryCorrelation = enumerator.Current as QueryCorrelationInitializer;
                        if (queryCorrelation != null)
                        {
                            CorrelationHandle handle = (queryCorrelation.CorrelationHandle != null ? queryCorrelation.CorrelationHandle.Get(context) : null);
                            if (handle == null)
                            {
                                if (ambientHandle != null && !isAmbientHandleUsed)
                                {
                                    handle = ambientHandle;
                                    isAmbientHandleUsed = true;
                                }
                                else
                                {
                                    throw FxTrace.Exception.AsError(
                                              new InvalidOperationException(SR2.QueryCorrelationInitializerCannotBeInitialized));
                                }
                            }
                            handle.InitializeBookmarkScope(context, key);
                            break;
                        }
                    }
                }
            }
        }
        public static void ValidateParametersContent(NativeActivityContext context, MessageDescription targetMessage, IDictionary parameters,
                                                     OperationDescription targetOperation, bool isResponse)
        {
            // The following properties can only be set via message contract. Therefore, we do not need to validate them here.
            // MessageDescription: Headers, Properties, ProtectionLevel
            // MessagePartDescription: Namespace, ProtectionLevel, Multiple, Index
            MessageBodyDescription targetMessageBody = targetMessage.Body;

            Fx.Assert(targetMessageBody != null, "MessageDescription.Body is never null!");

            if (targetMessageBody.WrapperName == null)
            {
                Constraint.AddValidationError(context, new ValidationError(SR2.UnwrappedMessageNotSupported(targetOperation.Name, targetOperation.DeclaringContract.Name)));
            }
            if (targetMessageBody.WrapperNamespace == null)
            {
                Constraint.AddValidationError(context, new ValidationError(SR2.UnwrappedMessageNotSupported(targetOperation.Name, targetOperation.DeclaringContract.Name)));
            }

            IDictionaryEnumerator iterator = parameters.GetEnumerator();
            int benchmarkIndex             = 0;
            int hitCount = 0;

            // Return value needs to be treated specially since ReceiveParametersContent does not have return value on the OM.
            bool targetHasReturnValue = isResponse && targetMessageBody.ReturnValue != null && targetMessageBody.ReturnValue.Type != TypeHelper.VoidType;

            if (targetHasReturnValue)
            {
                if (iterator.MoveNext() && (string)iterator.Key == targetMessageBody.ReturnValue.Name)
                {
                    Argument argument = (Argument)iterator.Value;
                    if (argument != null && argument.ArgumentType != targetMessageBody.ReturnValue.Type)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.FirstParameterDoesnotMatchTheReturnValue(argument.ArgumentType.FullName, targetMessageBody.ReturnValue.Type.FullName, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                    }
                    hitCount++;
                }
                else if (parameters.Contains(targetMessageBody.ReturnValue.Name))
                {
                    Constraint.AddValidationError(context, new ValidationError(SR2.ParameterPositionMismatch(targetMessageBody.ReturnValue.Name, targetOperation.Name, targetOperation.DeclaringContract.Name, "0")));
                    hitCount++;
                }
                else
                {
                    Constraint.AddValidationError(context, new ValidationError(SR2.ReturnValueMissing(targetMessageBody.ReturnValue.Type.FullName, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                }

                benchmarkIndex++;
            }

            foreach (MessagePartDescription targetPart in targetMessageBody.Parts)
            {
                if (iterator.MoveNext() && (string)iterator.Key == targetPart.Name)
                {
                    Argument argument = (Argument)iterator.Value;
                    if (argument != null && argument.ArgumentType != targetPart.Type)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.ParameterTypeMismatch(targetPart.Name, targetPart.Type.FullName, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                    }
                    hitCount++;
                }
                else if (parameters.Contains(targetPart.Name))
                {
                    Constraint.AddValidationError(context, new ValidationError(SR2.ParameterPositionMismatch(targetPart.Name, targetOperation.Name, targetOperation.DeclaringContract.Name, benchmarkIndex)));
                    hitCount++;
                }
                else
                {
                    Constraint.AddValidationError(context, new ValidationError(SR2.MissingParameter(targetPart.Name, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                }

                benchmarkIndex++;
            }

            if (hitCount != parameters.Count)
            {
                foreach (string name in parameters.Keys)
                {
                    XmlQualifiedName qName = new XmlQualifiedName(name, targetOperation.DeclaringContract.Namespace);
                    if (!targetMessageBody.Parts.Contains(qName))
                    {
                        if (!targetHasReturnValue || targetHasReturnValue && name != targetMessageBody.ReturnValue.Name)
                        {
                            Constraint.AddValidationError(context, new ValidationError(SR2.ExtraParameter(name, targetOperation.Name, targetOperation.DeclaringContract.Name)));
                        }
                    }
                }
            }
        }
        public static void ValidateMessageContent(NativeActivityContext context, MessageDescription targetMessage, Type declaredMessageType,
                                                  SerializerOption serializerOption, OperationDescription operation, bool isResponse)
        {
            // MessageContract is allowed only if the WCF contract interface specifies the same message contract type.
            if (MessageBuilder.IsMessageContract(declaredMessageType))
            {
                // if it is a typed message contract, we just validate the type of the message matches
                if (targetMessage.MessageType != null)
                {
                    if (declaredMessageType != targetMessage.MessageType)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(declaredMessageType.ToString(), "type", targetMessage.MessageType.ToString(), operation.Name, operation.DeclaringContract.Name)));
                    }
                }
                else
                {
                    Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(declaredMessageType.ToString(), "type", "null", operation.Name, operation.DeclaringContract.Name)));
                }
                return;
            }
            else if (declaredMessageType != null && declaredMessageType.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
            {
                //This is an untyped message contract
                if (targetMessage.Body == null)
                {
                    Constraint.AddValidationError(context, new ValidationError(SR2.BodyCannotBeNull));
                }
                else
                {
                    if (isResponse)
                    {
                        if (targetMessage.Body.ReturnValue == null)
                        {
                            Constraint.AddValidationError(context, new ValidationError(SR2.ExtraReturnValue));
                        }
                        else if (!targetMessage.Body.ReturnValue.Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                        {
                            Constraint.AddValidationError(context, new ValidationError(SR2.FirstParameterDoesnotMatchTheReturnValue(declaredMessageType.FullName, targetMessage.Body.ReturnValue.Type.Name, operation.Name, operation.DeclaringContract.Name)));
                        }
                    }
                    else
                    {
                        if (targetMessage.Body.Parts.Count == 0)
                        {
                            Constraint.AddValidationError(context, new ValidationError(SR2.ParameterNumberMismatch(declaredMessageType.FullName, operation.Name, operation.DeclaringContract.Name)));
                        }
                        else if (targetMessage.Body.Parts.Count > 1)
                        {
                            Constraint.AddValidationError(context, new ValidationError(SR2.MessageContentCannotHaveMoreThanOneParameter(operation.Name, operation.DeclaringContract.Name)));
                        }
                        else
                        {
                            if (!targetMessage.Body.Parts[0].Type.IsAssignableFrom(typeof(System.ServiceModel.Channels.Message)))
                            {
                                Constraint.AddValidationError(context, new ValidationError(SR2.MessageTypeMismatch(targetMessage.Body.Parts[0].Type.FullName, operation.Name, operation.DeclaringContract.Name)));
                            }
                        }
                    }
                }

                return;
            }

            // In case the WCF contract is a typed message, and the Receive activity also uses ReceiveMessageContent to infer a typed message, the contract needs to be matched
            Fx.Assert(targetMessage.Body != null, "MessageDescription.Body is never null!");

            // MessageDescription: Headers, Properties, ProtectionLevel
            // MessageBodyDescription: ReturnValue, WrapperName, WrapperNamespace
            // MessagePartDescription: Name, Namespace, Type, ProtectionLevel, Multiple, Index
            if (targetMessage.Headers.Count > 0)
            {
                Constraint.AddValidationError(context, new ValidationError(SR2.MessageHeaderNotSupported(operation.Name, operation.DeclaringContract.Name)));
            }
            if (targetMessage.Properties.Count > 0)
            {
                Constraint.AddValidationError(context, new ValidationError(SR2.MessagePropertyIsNotSupported(operation.Name, operation.DeclaringContract.Name)));
            }
            if (targetMessage.HasProtectionLevel)
            {
                Constraint.AddValidationError(context, new ValidationError(SR2.ProtectionLevelIsNotSupported(operation.Name, operation.DeclaringContract.Name)));
            }

            if (declaredMessageType == null || declaredMessageType == TypeHelper.VoidType)
            {
                if (!targetMessage.IsVoid)
                {
                    Constraint.AddValidationError(context, new ValidationError(SR2.MessageCannotBeEmpty(operation.Name, operation.DeclaringContract.Name)));
                }
            }
            else
            {
                string partName;
                string partNamespace;

                if (serializerOption == SerializerOption.DataContractSerializer)
                {
                    XmlQualifiedName xmlQualifiedName = MessageBuilder.XsdDataContractExporter.GetRootElementName(declaredMessageType);
                    if (xmlQualifiedName == null)
                    {
                        xmlQualifiedName = MessageBuilder.XsdDataContractExporter.GetSchemaTypeName(declaredMessageType);
                    }

                    if (!xmlQualifiedName.IsEmpty)
                    {
                        partName      = xmlQualifiedName.Name;
                        partNamespace = xmlQualifiedName.Namespace;
                    }
                    else
                    {
                        // For anonymous type, we assign CLR type name and contract namespace to MessagePartDescription
                        partName      = declaredMessageType.Name;
                        partNamespace = operation.DeclaringContract.Namespace;
                    }
                }
                else
                {
                    XmlTypeMapping xmlTypeMapping = MessageBuilder.XmlReflectionImporter.ImportTypeMapping(declaredMessageType);
                    partName      = xmlTypeMapping.ElementName;
                    partNamespace = xmlTypeMapping.Namespace;
                }

                MessagePartDescription targetPart = null;

                if (isResponse && targetMessage.Body.ReturnValue != null && targetMessage.Body.ReturnValue.Type != TypeHelper.VoidType)
                {
                    if (targetMessage.Body.Parts.Count > 0)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.NotSupportMoreThanOneParametersInMessageContract(operation.Name, operation.DeclaringContract.Name)));
                    }
                    targetPart = targetMessage.Body.ReturnValue;
                }
                else if (!isResponse)
                {
                    if (targetMessage.Body.WrapperName != null && targetMessage.Body.WrapperName != String.Empty)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.WrapperNotSupportedInMessageContract(operation.Name, operation.DeclaringContract.Name)));
                    }

                    if (targetMessage.Body.WrapperNamespace != null && targetMessage.Body.WrapperNamespace != String.Empty)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.WrapperNotSupportedInMessageContract(operation.Name, operation.DeclaringContract.Name)));
                    }

                    if (targetMessage.Body.Parts.Count == 0)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.ParameterNumberMismatch(declaredMessageType.FullName, operation.Name, operation.DeclaringContract.Name)));
                    }
                    else if (targetMessage.Body.Parts.Count > 1)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.MessageContentCannotHaveMoreThanOneParameter(operation.Name, operation.DeclaringContract.Name)));
                    }
                    else
                    {
                        targetPart = targetMessage.Body.Parts[0];
                    }
                }

                if (targetPart != null)
                {
                    if (partName != targetPart.Name)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(partName, "parameter name", targetPart.Name, operation.Name, operation.DeclaringContract.Name)));
                    }
                    if (partNamespace != targetPart.Namespace)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.PropertyMismatch(partNamespace, "parameter namespace", targetPart.Namespace, operation.Name, operation.DeclaringContract.Name)));
                    }
                    if (declaredMessageType != targetPart.Type)
                    {
                        if (declaredMessageType != null)
                        {
                            Constraint.AddValidationError(context, new ValidationError(SR2.ParameterTypeMismatch(declaredMessageType.FullName, targetPart.Type.FullName, operation.Name, operation.DeclaringContract.Name)));
                        }
                        else
                        {
                            Constraint.AddValidationError(context, new ValidationError(SR2.ParameterTypeMismatch(TypeHelper.VoidType.FullName, targetPart.Type.FullName, operation.Name, operation.DeclaringContract.Name)));
                        }
                    }
                    if (targetPart.HasProtectionLevel)
                    {
                        Constraint.AddValidationError(context, new ValidationError(SR2.ProtectionLevelIsNotSupported(operation.Name, operation.DeclaringContract.Name)));
                    }

                    // Multiple and Index do not need to be validate because there is only one part in the message.
                }
            }
        }