ValidationHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx35 / System.WorkflowServices / System / Workflow / Activities / ValidationHelper.cs / 1305376 / ValidationHelper.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Workflow.Activities 
{
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Reflection;
    using System.ServiceModel; 
    using System.ServiceModel.Description;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Compiler;
    using System.Workflow.ComponentModel.Design; 
    using System.Globalization;
 
    static class ValidationHelper 
    {
        internal static bool IsValidTypeNameOrIdentifier(string value, bool isTypeName) 
        {
            bool nextMustBeStartChar = true;
            bool previousWasNamespaceSeparatorChar = false;
 
            if (value.Length == 0)
            { 
                return false; 
            }
 
            // each char must be Lu, Ll, Lt, Lm, Lo, Nd, Mn, Mc, Pc
            //
            for (int i = 0; i < value.Length; i++)
            { 
                char ch = value[i];
                UnicodeCategory uc = Char.GetUnicodeCategory(ch); 
                switch (uc) 
                {
                    case UnicodeCategory.UppercaseLetter: // Lu 
                    case UnicodeCategory.LowercaseLetter: // Ll
                    case UnicodeCategory.TitlecaseLetter: // Lt
                    case UnicodeCategory.ModifierLetter: // Lm
                    case UnicodeCategory.LetterNumber: // Lm 
                    case UnicodeCategory.OtherLetter: // Lo
                        { 
                            nextMustBeStartChar = false; 
                            previousWasNamespaceSeparatorChar = false;
                            break; 
                        }

                    case UnicodeCategory.NonSpacingMark: // Mn
                    case UnicodeCategory.SpacingCombiningMark: // Mc 
                    case UnicodeCategory.ConnectorPunctuation: // Pc
                    case UnicodeCategory.DecimalDigitNumber: // Nd 
                        { 
                            // Underscore is a valid starting character, even though it is a ConnectorPunctuation.
                            if (nextMustBeStartChar && ch != '_') 
                            {
                                return false;
                            }
 
                            nextMustBeStartChar = false;
                            previousWasNamespaceSeparatorChar = false; 
                            break; 
                        }
 
                    default:
                        {
                            // We only check the special Type chars for type names.
                            if (isTypeName && !nextMustBeStartChar && !previousWasNamespaceSeparatorChar && IsNamespaceSeparatorChar(ch, ref nextMustBeStartChar)) 
                            {
                                previousWasNamespaceSeparatorChar = true; 
                                break; 
                            }
 
                            return false;
                        }
                }
            } 

            if (isTypeName && previousWasNamespaceSeparatorChar && nextMustBeStartChar) 
            { 
                return false;
            } 

            return true;
        }
 
        internal static ValidationErrorCollection ValidateAllServiceOperationsImplemented(
            ValidationManager manager, 
            Activity rootActivity) 
        {
            if (manager == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("manager");
            }
 
            if (rootActivity == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rootActivity"); 
            }
 
            ValidationErrorCollection validationErrors = new ValidationErrorCollection();

            WorkflowServiceAttributes serviceAttributes = (WorkflowServiceAttributes) ReceiveActivity.GetWorkflowServiceAttributes(rootActivity);
            if (serviceAttributes != null) 
            {
                if (serviceAttributes.MaxItemsInObjectGraph < 0) 
                { 
                    validationErrors.Add(new ValidationError(
                        SR2.GetString( 
                        SR2.Error_Validation_InvalidMaxItemsInObjectGraph),
                        WorkflowServicesErrorNumbers.Error_InvalidMaxItemsInObjectGraph,
                        false,
                        "WorkflowServiceAttributes")); 
                }
            } 
 
            // verifying that we do not have two contract with the same full name
            // one contract first 
            // one workflow first
            //

            Dictionary implementedTypedContracts = new Dictionary(); 
            Dictionary implementedInferredContracts = new Dictionary();
 
            foreach (ReceiveActivity receiveActivity in GetActivities(rootActivity)) 
            {
                if (receiveActivity.ServiceOperationInfo == null) 
                {
                    continue;
                }
 
                TypedOperationInfo typedServiceOperation =
                    receiveActivity.ServiceOperationInfo as TypedOperationInfo; 
                OperationInfo inferredServiceOperation = 
                    receiveActivity.ServiceOperationInfo as OperationInfo;
 
                string typeName = string.Empty;

                Dictionary toAddTo = implementedInferredContracts;
                Dictionary toVerify = implementedTypedContracts; 

                if (typedServiceOperation != null) 
                { 
                    if (typedServiceOperation.ContractType != null)
                    { 
                        typeName = typedServiceOperation.ContractType.FullName;

                        toAddTo = implementedTypedContracts;
                        toVerify = implementedInferredContracts; 
                    }
                } 
                else 
                {
                    typeName = inferredServiceOperation.ContractName; 
                }

                if (string.IsNullOrEmpty(typeName))
                { 
                    continue;
                } 
 
                if (toVerify.ContainsKey(typeName) && !toAddTo.ContainsKey(typeName))
                { 
                    validationErrors.Add(new ValidationError(
                        SR2.GetString(SR2.Error_Validation_ContractNameDuplicate, typeName),
                        WorkflowServicesErrorNumbers.Error_ContractNameDuplicate, false));
                } 

                if (!toAddTo.ContainsKey(typeName)) 
                { 
                    toAddTo.Add(typeName, typeName);
                } 
            }

            // collect operations that are implemented
            // 

            Dictionary implementedServiceOperations = new Dictionary(); 
            foreach (ReceiveActivity receiveActivity in GetActivities(rootActivity)) 
            {
                OperationInfoBase serviceOperation = receiveActivity.ServiceOperationInfo; 
                if (serviceOperation != null)
                {
                    Type contractType = serviceOperation.GetContractType(manager);
 
                    if (contractType == null)
                    { 
                        continue; 
                    }
 
                    if (!implementedServiceOperations.ContainsKey(contractType))
                    {
                        Hashtable serviceOperationHashTable = new Hashtable();
                        implementedServiceOperations.Add(contractType, serviceOperationHashTable); 
                    }
 
                    MethodInfo methodInfo = serviceOperation.GetMethodInfo(manager); 
                    if (methodInfo == null)
                    { 
                        continue;
                    }

                    contractType = methodInfo.DeclaringType; 

                    if (!implementedServiceOperations.ContainsKey(contractType)) 
                    { 
                        Hashtable serviceOperationHashTable = new Hashtable();
                        serviceOperationHashTable.Add(serviceOperation.Name, methodInfo); 
                        implementedServiceOperations.Add(contractType, serviceOperationHashTable);
                    }
                    else
                    { 
                        if (!implementedServiceOperations[contractType].ContainsKey(serviceOperation.Name))
                        { 
                            implementedServiceOperations[contractType].Add( 
                                serviceOperation.Name,
                                methodInfo); 
                        }
                    }
                }
            } 

            // verifying that we do not have one two methods defining the same operation 
            // verify which operatinos are not implemented and give warnings for each 
            //
 
            Dictionary checkedContracts = new Dictionary();
            Dictionary notImplementedServiceOperations = new Dictionary();

            foreach (Type contractType in implementedServiceOperations.Keys) 
            {
                Queue interfacesQueue = new Queue(); 
                List contractList = new List(); 

                interfacesQueue.Enqueue(contractType); 

                while (interfacesQueue.Count > 0)
                {
                    Type currentInterfaceType = interfacesQueue.Dequeue(); 
                    if (!contractList.Contains(currentInterfaceType) &&
                        currentInterfaceType.IsDefined(typeof(ServiceContractAttribute), false)) 
                    { 
                        contractList.Add(currentInterfaceType);
                    } 

                    foreach (Type baseInteface in currentInterfaceType.GetInterfaces())
                    {
                        if (!contractList.Contains(baseInteface)) 
                        {
                            interfacesQueue.Enqueue(baseInteface); 
                        } 
                    }
                } 

                foreach (Type currentContractType in contractList)
                {
                    if (checkedContracts.ContainsKey(currentContractType)) 
                    {
                        continue; 
                    } 

                    foreach (MethodInfo methodInfo in currentContractType.GetMethods()) 
                    {
                        if (methodInfo.DeclaringType != currentContractType)
                        {
                            continue; 
                        }
                        if (!ServiceOperationHelpers.IsValidServiceOperation(methodInfo)) 
                        { 
                            continue;
                        } 

                        string operationName = ServiceOperationHelpers.GetOperationName(manager, methodInfo);

                        if (!implementedServiceOperations.ContainsKey(currentContractType)) 
                        {
                            validationErrors.Add(new ValidationError( 
                                SR2.GetString( 
                                SR2.Error_OperationNotImplemented,
                                operationName, 
                                currentContractType.FullName),
                                WorkflowServicesErrorNumbers.Error_OperationNotImplemented,
                                true));
 
                            if (!notImplementedServiceOperations.ContainsKey(currentContractType))
                            { 
                                Hashtable serviceOperationHashTable = new Hashtable(); 
                                serviceOperationHashTable.Add(operationName, methodInfo);
                                notImplementedServiceOperations.Add(currentContractType, serviceOperationHashTable); 
                            }
                            else if (notImplementedServiceOperations[currentContractType].ContainsKey(operationName))
                            {
                                validationErrors.Add(new ValidationError( 
                                    SR2.GetString(
                                    SR2.Error_DuplicatedOperationName, 
                                    methodInfo.Name, 
                                    ((MethodInfo) notImplementedServiceOperations[currentContractType][operationName]).Name,
                                    currentContractType.FullName), 
                                    WorkflowServicesErrorNumbers.Error_DuplicatedOperationName,
                                    false));
                            }
                            else 
                            {
                                notImplementedServiceOperations[currentContractType].Add( 
                                    operationName, 
                                    methodInfo);
                            } 
                        }
                        else if (!implementedServiceOperations[currentContractType].ContainsKey(operationName))
                        {
                            validationErrors.Add(new ValidationError( 
                                SR2.GetString(
                                SR2.Error_OperationNotImplemented, 
                                operationName, 
                                currentContractType.FullName),
                                WorkflowServicesErrorNumbers.Error_OperationNotImplemented, 
                                true));

                            if (!notImplementedServiceOperations.ContainsKey(currentContractType))
                            { 
                                Hashtable serviceOperationHashTable = new Hashtable();
                                serviceOperationHashTable.Add(operationName, methodInfo); 
                                notImplementedServiceOperations.Add(currentContractType, serviceOperationHashTable); 
                            }
                            else if (notImplementedServiceOperations[currentContractType].ContainsKey(operationName)) 
                            {
                                validationErrors.Add(new ValidationError(
                                    SR2.GetString(
                                    SR2.Error_DuplicatedOperationName, 
                                    methodInfo.Name,
                                    ((MethodInfo) notImplementedServiceOperations[currentContractType][operationName]).Name, 
                                    currentContractType.FullName), 
                                    WorkflowServicesErrorNumbers.Error_DuplicatedOperationName,
                                    false)); 
                            }
                            else
                            {
                                notImplementedServiceOperations[currentContractType].Add( 
                                    operationName,
                                    methodInfo); 
                            } 
                        }
                        else if (implementedServiceOperations[currentContractType][operationName] != (object)methodInfo) 
                        {
                            validationErrors.Add(new ValidationError(
                                SR2.GetString(
                                SR2.Error_DuplicatedOperationName, 
                                methodInfo.Name,
                                ((MethodInfo) implementedServiceOperations[currentContractType][operationName]).Name, 
                                currentContractType.FullName), 
                                WorkflowServicesErrorNumbers.Error_DuplicatedOperationName,
                                false)); 
                        }
                    }

                    checkedContracts.Add(currentContractType, true); 
                }
 
                if (validationErrors.Count != 0) 
                {
                    break; 
                }
            }

            if (manager.Context[typeof(ServiceOperationsImplementedValidationMarker)] == null) 
            {
                manager.Context.Append(new ServiceOperationsImplementedValidationMarker()); 
            } 

            return validationErrors; 
        }

        internal static ValidationErrorCollection ValidateChannelToken(
            SendActivity activity, 
            ValidationManager manager)
        { 
            if (activity == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); 
            }
            if (manager == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("manager"); 
            }
 
            ValidationErrorCollection validationErrors = new ValidationErrorCollection(); 

            // validation rules: 
            //
            // endpoint cannot be null
            //
            // Name: !(null ||empty) 
            // OwnerActivityName: any
            // ConfigurationName: !(null ||empty) || bound 
            // 

            ChannelToken endpoint = activity.ChannelToken; 

            if (endpoint == null)
            {
                validationErrors.Add( 
                    new ValidationError(SR2.GetString(SR2.Error_Validation_ChannelTokenNotSpecified, activity.Name),
                    WorkflowServicesErrorNumbers.Error_ChannelTokenNotSpecified, 
                    false, 
                    "ChannelToken"));
            } 
            else
            {
                if (string.IsNullOrEmpty(endpoint.Name))
                { 
                    validationErrors.Add(
                        new ValidationError(SR2.GetString(SR2.Error_Validation_ChannelTokenNameNotSpecified, activity.Name), 
                        WorkflowServicesErrorNumbers.Error_ChannelTokenNameNotSpecified, 
                        false,
                        "ChannelToken")); 
                }

                if (string.IsNullOrEmpty(endpoint.EndpointName) &&
                    !endpoint.IsBindingSet(ChannelToken.EndpointNameProperty)) 
                {
                    validationErrors.Add( 
                        new ValidationError(SR2.GetString(SR2.Error_Validation_ChannelTokenConfigurationNameNotSpecified, activity.Name), 
                        WorkflowServicesErrorNumbers.Error_ChannelTokenConfigurationNameNotSpecified,
                        false, 
                        "ChannelToken"));
                }

                if (!string.IsNullOrEmpty(endpoint.OwnerActivityName)) 
                {
                    string qualifiedOwnerName = null; 
                    Activity sourceActivity = activity.GetActivityByName(endpoint.OwnerActivityName); 
                    if (sourceActivity == null)
                    { 
                        sourceActivity = Helpers.ParseActivityForBind(activity, endpoint.OwnerActivityName);
                    }
                    if (sourceActivity != null)
                    { 
                        qualifiedOwnerName = sourceActivity.QualifiedName;
                    } 
 
                    Activity replicatorParent = null;
                    Activity parent = activity; 
                    bool ownerIsParentOrItself = false;
                    while (parent != null)
                    {
                        // We hardcode Replicator here, not MultiInstance | Concurrent. 
                        if (parent is ReplicatorActivity && replicatorParent == null)
                        { 
                            replicatorParent = parent; 
                        }
 
                        if (qualifiedOwnerName == parent.QualifiedName)
                        {
                            ownerIsParentOrItself = true;
                        } 

                        parent = parent.Parent; 
 
                    }
 
                    if (!ownerIsParentOrItself)
                    {
                        validationErrors.Add(
                            new ValidationError(SR2.GetString(SR2.Error_Validation_OwnerActivityNameNotFound, endpoint.OwnerActivityName, activity.Name), 
                            WorkflowServicesErrorNumbers.Error_OwnerActivityNameNotFound,
                            false, 
                            "ChannelToken")); 
                    }
                } 
            }

            return validationErrors;
        } 

        internal static ValidationErrorCollection ValidateContextToken( 
            Activity activity, 
            ContextToken contextToken,
            ValidationManager manager) 
        {
            if (activity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); 
            }
            if (manager == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("manager");
            } 

            ValidationErrorCollection validationErrors = new ValidationErrorCollection();

            // having no context token is valid 
            // this means "use RootContext" which is the implicit one.
            // 
            if (contextToken == null) 
            {
                return validationErrors; 
            }

            // validation rules:
            // 
            // root context:
            //  Name: (RootContext) 
            //  OwnerActivityName: null || emtpy 
            //
            // non root context: 
            //  Name: !(RootContext) && !(null ||empty)
            //  OwnerActivityName: any
            //
 
            if (string.IsNullOrEmpty(contextToken.Name))
            { 
                validationErrors.Add( 
                    new ValidationError(SR2.GetString(SR2.Error_Validation_ContextTokenNameNotSpecified, activity.Name),
                    WorkflowServicesErrorNumbers.Error_ContextTokenNameNotSpecified, 
                    false,
                    "ContextToken"));
            }
 
            if (string.Compare(contextToken.Name, ContextToken.RootContextName, StringComparison.Ordinal) == 0)
            { 
                if (!string.IsNullOrEmpty(contextToken.OwnerActivityName)) 
                {
                    validationErrors.Add( 
                        new ValidationError(SR2.GetString(SR2.Error_Validation_RootContextScope, activity.Name),
                        WorkflowServicesErrorNumbers.Error_RootContextScope,
                        false,
                        "ContextToken")); 
                }
            } 
            else if (!string.IsNullOrEmpty(contextToken.OwnerActivityName)) 
            {
                string qualifiedOwnerName = null; 
                Activity sourceActivity = activity.GetActivityByName(contextToken.OwnerActivityName);
                if (sourceActivity == null)
                {
                    sourceActivity = Helpers.ParseActivityForBind(activity, contextToken.OwnerActivityName); 
                }
                if (sourceActivity != null) 
                { 
                    qualifiedOwnerName = sourceActivity.QualifiedName;
                } 

                Activity replicatorParent = null;
                Activity parent = activity;
                bool ownerIsParent = false; 
                while (parent != null)
                { 
                    // We hardcode Replicator here, not MultiInstance | Concurrent. 
                    if (parent is ReplicatorActivity && replicatorParent == null)
                    { 
                        replicatorParent = parent;
                    }

                    if (qualifiedOwnerName == parent.QualifiedName) 
                    {
                        ownerIsParent = true; 
                    } 

                    parent = parent.Parent; 

                }

                if (!ownerIsParent) 
                {
                    validationErrors.Add( 
                        new ValidationError(SR2.GetString(SR2.Error_Validation_OwnerActivityNameNotFound, contextToken.OwnerActivityName, activity.Name), 
                        WorkflowServicesErrorNumbers.Error_OwnerActivityNameNotFound,
                        false, 
                        "ContextToken"));
                }
            }
 
            return validationErrors;
        } 
 
        internal static ValidationErrorCollection ValidateOperationInfo(
            Activity activity, 
            OperationInfoBase operationInfo,
            ValidationManager manager)
        {
            if (activity == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); 
            } 
            if (operationInfo == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationInfo");
            }
            if (manager == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("manager");
            } 
 
            ITypeProvider typeProvider = manager.GetService(typeof(ITypeProvider)) as ITypeProvider;
            if (typeProvider == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(SR2.GetString(SR2.General_MissingService, typeof(ITypeProvider).Name)));
            } 

            ValidationErrorCollection validationErrors = new ValidationErrorCollection(); 
 
            if (string.IsNullOrEmpty(operationInfo.Name))
            { 
                validationErrors.Add(
                    new ValidationError(SR2.GetString(SR2.Error_Validation_OperationNameNotSpecified, activity.Name),
                    WorkflowServicesErrorNumbers.Error_OperationNameNotSpecified, false, "ServiceOperationInfo"));
            } 

            if (operationInfo is OperationInfo) 
            { 
                OperationInfo currentOperationInfo = operationInfo as OperationInfo;
 
                if (!string.IsNullOrEmpty(currentOperationInfo.Name) &&
                    !IsValidTypeNameOrIdentifier(currentOperationInfo.Name, false))
                {
                    validationErrors.Add( 
                        new ValidationError(SR2.GetString(SR2.Error_Validation_OperationNameInvalid, activity.Name),
                        WorkflowServicesErrorNumbers.Error_OperationNameInvalid, false, "ServiceOperationInfo")); 
                } 

                if (string.IsNullOrEmpty(currentOperationInfo.ContractName)) 
                {
                    validationErrors.Add(
                        new ValidationError(SR2.GetString(SR2.Error_Validation_ContractNameNotSpecified, activity.Name),
                        WorkflowServicesErrorNumbers.Error_ContractNameNotSpecified, 
                        false,
                        "ServiceOperationInfo")); 
                } 
                else if (!IsValidTypeNameOrIdentifier(currentOperationInfo.ContractName, true))
                { 
                    validationErrors.Add(
                        new ValidationError(SR2.GetString(SR2.Error_Validation_ContractNameInvalid, activity.Name),
                        WorkflowServicesErrorNumbers.Error_ContractNameInvalid,
                        false, 
                        "ServiceOperationInfo"));
                } 
 
                bool hasReturnValue = false;
                foreach (OperationParameterInfo operationParameterInfo in currentOperationInfo.Parameters) 
                {
                    if (operationParameterInfo.Position == -1)
                    {
                        hasReturnValue = true; 
                        break;
                    } 
                } 

                int maxPosition = currentOperationInfo.Parameters.Count - (hasReturnValue ? 2 : 1); 
                List parameterIndexs = new List();
                List parameterNames = new List();

                foreach (OperationParameterInfo operationParameterInfo in currentOperationInfo.Parameters) 
                {
                    if (operationParameterInfo.Position != -1 && operationParameterInfo.Position > maxPosition) 
                    { 
                        validationErrors.Add(
                            new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterPosition, 
                            operationParameterInfo.Name, currentOperationInfo.Name, currentOperationInfo.ContractName),
                            WorkflowServicesErrorNumbers.Error_OperationParameterPosition,
                            false,
                            "ServiceOperationInfo")); 
                    }
 
                    if (parameterIndexs.Contains(operationParameterInfo.Position)) 
                    {
                        validationErrors.Add( 
                            new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterPositionDuplicate,
                            operationParameterInfo.Name, currentOperationInfo.Name, currentOperationInfo.ContractName),
                            WorkflowServicesErrorNumbers.Error_OperationParameterPositionDuplicate,
                            false, 
                            "ServiceOperationInfo"));
                    } 
                    else 
                    {
                        parameterIndexs.Add(operationParameterInfo.Position); 
                    }

                    if (operationParameterInfo.Position != -1 && !IsValidTypeNameOrIdentifier(operationParameterInfo.Name, false))
                    { 
                        validationErrors.Add(
                            new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterNameInvalid, 
                            operationParameterInfo.Name, currentOperationInfo.Name, currentOperationInfo.ContractName), 
                            WorkflowServicesErrorNumbers.Error_OperationParameterNameInvalid,
                            false, 
                            "ServiceOperationInfo"));
                    }

                    if (parameterNames.Contains(operationParameterInfo.Name)) 
                    {
                        validationErrors.Add( 
                            new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterNameDuplicate, 
                            operationParameterInfo.Name, currentOperationInfo.Name, currentOperationInfo.ContractName),
                            WorkflowServicesErrorNumbers.Error_OperationParameterNameDuplicate, 
                            false,
                            "ServiceOperationInfo"));
                    }
                    else 
                    {
                        parameterNames.Add(operationParameterInfo.Name); 
                    } 

                    if (operationParameterInfo.Position != -1 && operationParameterInfo.ParameterType == typeof(void)) 
                    {
                        validationErrors.Add(
                            new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterType,
                            operationParameterInfo.Name, currentOperationInfo.Name, currentOperationInfo.ContractName), 
                            WorkflowServicesErrorNumbers.Error_OperationParameterType,
                            false, 
                            "ServiceOperationInfo")); 
                    }
                } 
            }
            else
            {
                TypedOperationInfo currentOperationInfo = operationInfo as TypedOperationInfo; 
                if (currentOperationInfo.ContractType == null)
                { 
                    validationErrors.Add( 
                        new ValidationError(SR2.GetString(SR2.Error_Validation_ContractTypeNotSpecified, activity.Name),
                        WorkflowServicesErrorNumbers.Error_ContractTypeNotSpecified, 
                        false,
                        "ServiceOperationInfo"));
                }
            } 

            // no point validating further as we will not be able to get to the contract type or operation 
            // 
            if (validationErrors.Count > 0)
            { 
                return validationErrors;
            }

            Type contractType = operationInfo.GetContractType(manager); 
            if (contractType == null)
            { 
                validationErrors.Add( 
                    new ValidationError(SR2.GetString(SR2.Error_Validation_ContractTypeNotFound, activity.Name),
                    WorkflowServicesErrorNumbers.Error_ContractTypeNotFound, 
                    false,
                    "ServiceOperationInfo"));
            }
            else if (!contractType.IsInterface) 
            {
                validationErrors.Add( 
                    new ValidationError(SR2.GetString(SR2.Error_Validation_ContractTypeNotInterface, contractType.FullName, activity.Name), 
                    WorkflowServicesErrorNumbers.Error_ContractTypeNotInterface,
                    false, 
                    "ServiceOperationInfo"));
            }
            else if (!ServiceOperationHelpers.IsValidServiceContract(contractType))
            { 
                validationErrors.Add(
                    new ValidationError(SR2.GetString(SR2.Error_ServiceContractAttributeMissing, contractType.FullName), 
                    WorkflowServicesErrorNumbers.Error_ServiceContractAttributeMissing, 
                    false,
                    "ServiceOperationInfo")); 
            }
            else
            {
                MethodInfo methodInfo = operationInfo.GetMethodInfo(manager); 
                if (methodInfo == null)
                { 
                    validationErrors.Add( 
                        new ValidationError(SR2.GetString(SR2.Error_Validation_OperationNotInContract, operationInfo.Name, contractType.FullName),
                        WorkflowServicesErrorNumbers.Error_OperationNotInContract, 
                        false,
                        "ServiceOperationInfo"));
                }
                else if (ServiceOperationHelpers.IsAsyncOperation(manager, methodInfo)) 
                {
                    validationErrors.Add( 
                        new ValidationError(SR2.GetString(SR2.Error_Validation_AsyncPatternOperationNotSupported, operationInfo.Name), 
                        WorkflowServicesErrorNumbers.Error_AsyncPatternOperationNotSupported,
                        false, 
                        "ServiceOperationInfo"));
                }
                else
                { 
                    List parameterIndexs = new List();
                    List parameterNames = new List(); 
 
                    bool isOneWay = operationInfo.GetIsOneWay(manager);
 
                    if (isOneWay && methodInfo.ReturnType != typeof(void))
                    {
                        validationErrors.Add(
                            new ValidationError(SR2.GetString(SR2.Error_Validation_ReturnTypeInOneWayOperation, 
                            operationInfo.Name, contractType.FullName),
                            WorkflowServicesErrorNumbers.Error_ReturnTypeInOneWayOperation, 
                            false, 
                            "ServiceOperationInfo"));
                    } 

                    foreach (ParameterInfo parameter in methodInfo.GetParameters())
                    {
                        if (parameter.Position >= methodInfo.GetParameters().Length || 
                            parameter.Position < 0)
                        { 
                            validationErrors.Add( 
                                new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterPosition,
                                parameter.Name, operationInfo.Name, contractType.FullName), 
                                WorkflowServicesErrorNumbers.Error_OperationParameterPosition,
                                false,
                                "ServiceOperationInfo"));
                        } 

                        if (parameterIndexs.Contains(parameter.Position)) 
                        { 
                            validationErrors.Add(
                                new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterPositionDuplicate, 
                                parameter.Name, operationInfo.Name, contractType.FullName),
                                WorkflowServicesErrorNumbers.Error_OperationParameterPositionDuplicate,
                                false,
                                "ServiceOperationInfo")); 
                        }
 
                        if (!IsValidTypeNameOrIdentifier(parameter.Name, false)) 
                        {
                            validationErrors.Add( 
                                new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterNameInvalid,
                                parameter.Name, operationInfo.Name, contractType.FullName),
                                WorkflowServicesErrorNumbers.Error_OperationParameterNameInvalid,
                                false, 
                                "ServiceOperationInfo"));
                        } 
 
                        if (parameterNames.Contains(parameter.Name))
                        { 
                            validationErrors.Add(
                                new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterNameDuplicate,
                                parameter.Name, operationInfo.Name, contractType.FullName),
                                WorkflowServicesErrorNumbers.Error_OperationParameterNameDuplicate, 
                                false,
                                "ServiceOperationInfo")); 
                        } 

                        if (isOneWay && ((parameter.Attributes & ParameterAttributes.Out) > 0 || parameter.ParameterType.IsByRef)) 
                        {
                            validationErrors.Add(
                                new ValidationError(SR2.GetString(SR2.Error_Validation_OperationParameterDirectionInOneWayOperation,
                                parameter.Name, operationInfo.Name, contractType.FullName), 
                                WorkflowServicesErrorNumbers.Error_OperationParameterDirectionInOneWayOperation,
                                false, 
                                "ServiceOperationInfo")); 
                        }
 
                        parameterIndexs.Add(parameter.Position);
                        parameterNames.Add(parameter.Name);
                    }
 
                    validationErrors.AddRange(
                        ValidationHelper.ValidateServiceModelAttributes(activity, contractType, methodInfo, manager)); 
                } 

 
            }

            return validationErrors;
        } 

        internal static IEnumerable ValidateParameterBindings( 
            Activity ownerActivity, 
            OperationInfoBase operationInfo,
            WorkflowParameterBindingCollection parameterBindings, 
            ValidationManager manager)
        {
            ValidationErrorCollection validationErrors = new ValidationErrorCollection();
 
            if (ownerActivity == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ownerActivity"); 
            }
            if (operationInfo == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationInfo");
            }
            if (parameterBindings == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameterBindings"); 
            } 
            if (manager == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("manager");
            }

            MethodInfo methodInfo = operationInfo.GetMethodInfo(manager); 
            if (methodInfo == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("operationInfo", 
                    SR2.GetString(SR2.Error_MethodInfoNotAvailable, ownerActivity.Name));
            } 

            bool isOneWayOperation = operationInfo.GetIsOneWay(manager);

            foreach (ParameterInfo parameter in GetParameterInfo(methodInfo)) 
            {
                if (!(parameter.IsOut || parameter.Position == -1) || !isOneWayOperation) 
                { 
                    string parameterName = (parameter.Position == -1) ? "(ReturnValue)" : parameter.Name;
                    object parameterValue = null; 

                    if (parameterBindings.Contains(parameterName))
                    {
                        if (parameterBindings[parameterName].IsBindingSet(WorkflowParameterBinding.ValueProperty)) 
                        {
                            parameterValue = parameterBindings[parameterName].GetBinding( 
                                WorkflowParameterBinding.ValueProperty); 
                        }
                        else 
                        {
                            parameterValue = parameterBindings[parameterName].GetValue(
                                WorkflowParameterBinding.ValueProperty);
                        } 

                        if (parameterValue != null) 
                        { 
                            // Check for access type of the binding.
                            AccessTypes requiredAccess = AccessTypes.Read; 
                            if (parameter.IsOut ||
                                parameter.ParameterType.IsByRef ||
                                parameter.Position == -1)
                            { 
                                requiredAccess |= AccessTypes.Write;
                            } 
 
                            PropertyValidationContext propertyValidationContext =
                                new PropertyValidationContext(parameterBindings[parameterName], 
                                null,
                                parameterName);
                            BindValidationContext bindValidationContext = new BindValidationContext(
                                parameter.ParameterType.IsByRef ? parameter.ParameterType.GetElementType() : parameter.ParameterType, 
                                requiredAccess);
 
                            validationErrors.AddRange(ValidationHelpers.ValidateProperty( 
                                manager,
                                ownerActivity, 
                                parameterValue,
                                propertyValidationContext,
                                bindValidationContext));
                        } 
                    }
 
                    if (!parameterBindings.Contains(parameterName) || 
                        parameterValue == null)
                    { 
                        if (ownerActivity is SendActivity)
                        {
                            if (parameter.Position != -1)
                            { 
                                validationErrors.Add(new ValidationError(SR2.GetString(
                                    SR2.Warning_SendActivityParameterBindingMissing, 
                                    parameterName), 
                                    WorkflowServicesErrorNumbers.Warning_SendActivityParameterBindingMissing,
                                    true, 
                                    parameterName));
                            }
                        }
                        else if (ownerActivity is ReceiveActivity) 
                        {
                            if (parameter.Position == -1) 
                            { 
                                validationErrors.Add(new ValidationError(SR2.GetString(
                                    SR2.Warning_ReceiveActivityReturnValueBindingMissing, 
                                    parameterName),
                                    WorkflowServicesErrorNumbers.Warning_ReceiveActivityReturnValueBindingMissing,
                                    true,
                                    parameterName)); 
                            }
                            else 
                            { 
                                validationErrors.Add(new ValidationError(SR2.GetString(
                                    SR2.Warning_ReceiveActivityParameterBindingMissing, 
                                    parameterName),
                                    WorkflowServicesErrorNumbers.Warning_ReceiveActivityParameterBindingMissing,
                                    true,
                                    parameterName)); 
                            }
                        } 
                    } 
                }
            } 
            return validationErrors;

        }
 
        internal static IEnumerable ValidateServiceModelAttributes(
            Activity activity, 
            Type contractType, 
            MethodInfo methodInfo,
            ValidationManager manager) 
        {
            if (activity == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); 
            }
 
            if (contractType == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); 
            }

            if (methodInfo == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("methodInfo");
            } 
 
            if (manager == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("manager");
            }

            ValidationErrorCollection validationErrors = new ValidationErrorCollection(); 
            object[] serviceContractAttributes = contractType.GetCustomAttributes(typeof(ServiceContractAttribute), true);
            if (serviceContractAttributes == null || serviceContractAttributes.Length == 0) 
            { 
                validationErrors.Add(new ValidationError(SR2.GetString(SR2.Error_ServiceContractAttributeMissing, contractType.FullName), WorkflowServicesErrorNumbers.Error_ServiceContractAttributeMissing, false, "ServiceOperationInfo"));
            } 
            else
            {
                if (!methodInfo.ReflectedType.IsAssignableFrom(contractType))
                { 
                    validationErrors.Add(new ValidationError(SR2.GetString(SR2.Error_OperationNotInContract, methodInfo.Name, contractType.FullName), WorkflowServicesErrorNumbers.Error_OperationNotInContract, false, "ServiceOperationInfo"));
                } 
                else 
                {
                    object[] operationContractAttrributes = methodInfo.GetCustomAttributes(typeof(OperationContractAttribute), true); 
                    if (operationContractAttrributes == null || operationContractAttrributes.Length == 0)
                    {
                        validationErrors.Add(new ValidationError(SR2.GetString(SR2.Error_OperationContractAttributeMissing, methodInfo.Name), WorkflowServicesErrorNumbers.Error_OperationContractAttributeMissing, false, "ServiceOperationInfo"));
                    } 
                    else if (activity is ReceiveActivity)
                    { 
                        ReceiveActivity receiveActivity = activity as ReceiveActivity; 

                        SessionMode contractSessionMode = SessionMode.Allowed; 
                        if (serviceContractAttributes[0] is ServiceContractAttribute)
                        {
                            contractSessionMode = ((ServiceContractAttribute) serviceContractAttributes[0]).SessionMode;
                        } 
                        else if (serviceContractAttributes[0] is AttributeInfoAttribute)
                        { 
                            AttributeInfoAttribute attribInfoAttrib = serviceContractAttributes[0] as AttributeInfoAttribute; 
                            if (typeof(ServiceContractAttribute).IsAssignableFrom(attribInfoAttrib.AttributeInfo.AttributeType))
                            { 
                                contractSessionMode = ServiceOperationHelpers.GetContractSessionMode(manager, attribInfoAttrib.AttributeInfo);
                            }
                        }
 
                        if (receiveActivity.CanCreateInstance == true &&
                            receiveActivity.ServiceOperationInfo.GetIsOneWay(manager) && 
                            contractSessionMode != SessionMode.NotAllowed) 
                        {
                            validationErrors.Add(new ValidationError(SR2.GetString(SR2.Error_Validation_OperationIsOneWay, methodInfo.Name), WorkflowServicesErrorNumbers.Error_OperationIsOneWay, false, "CanCreateInstance")); 
                        }
                        if (receiveActivity.CanCreateInstance == true && !ServiceOperationHelpers.IsInitiatingOperation(manager, methodInfo))
                        {
                            validationErrors.Add(new ValidationError(SR2.GetString(SR2.Error_OperationNotInitiating, methodInfo.Name), WorkflowServicesErrorNumbers.Error_OperationNotInitiating, false, "CanCreateInstance")); 
                        }
                    } 
                } 
            }
            return validationErrors; 
        }

        private static IEnumerable GetActivities(Activity rootActivity)
        { 
            if (rootActivity == null || !rootActivity.Enabled)
            { 
                yield break; 
            }
 
            if (rootActivity is CompositeActivity)
            {
                foreach (Activity activity in ((CompositeActivity) rootActivity).Activities)
                { 
                    if (!activity.Enabled)
                    { 
                        continue; 
                    }
 
                    if (activity.GetType() == typeof(T))
                    {
                        yield return activity;
                    } 

                    if (activity is CompositeActivity) 
                    { 
                        foreach (T requestedType in GetActivities(activity))
                        { 
                            yield return requestedType;
                        }
                    }
                } 
            }
            else 
            { 
                if (rootActivity.GetType() == typeof(T))
                { 
                    yield return rootActivity;
                }
            }
            yield break; 
        }
 
        private static List GetParameterInfo(MethodInfo methodInfo) 
        {
            List parametersInfo = new List(); 
            parametersInfo.AddRange(methodInfo.GetParameters());

            if (methodInfo.ReturnParameter != null && methodInfo.ReturnType != typeof(void))
            { 
                parametersInfo.Add(methodInfo.ReturnParameter);
            } 
 
            return parametersInfo;
        } 

        private static bool IsNamespaceSeparatorChar(char ch, ref bool nextMustBeStartChar)
        {
            switch (ch) 
            {
                case '.': 
                    nextMustBeStartChar = true; 
                    return true;
            } 
            return false;
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK