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)));
     }
 }
        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 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.
                }
            }
        }