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