Example #1
0
        /// <summary>
        /// Determines if an operationParameterBindingKind
        /// </summary>
        /// <param name="operationParameterBindingKind">Operation Parameter Binding Kind</param>
        /// <returns>Whether its bound or not</returns>
        public static bool IsBound(this OperationParameterBindingKind operationParameterBindingKind)
        {
            if (operationParameterBindingKind != OperationParameterBindingKind.Never)
            {
                return(true);
            }

            return(false);
        }
Example #2
0
		private ServiceAction(string name, ResourceType returnType, ResourceSet resultSet, ResourceSetPathExpression resultSetPathExpression, IEnumerable<ServiceActionParameter> parameters, OperationParameterBindingKind operationParameterBindingKind) : base(name, Operation.GetResultKindFromReturnType(returnType, false), returnType, resultSet, resultSetPathExpression, "POST", parameters, operationParameterBindingKind, OperationKind.Action)
        {
            if (base.OperationParameters == OperationParameter.EmptyOperationParameterCollection)
            {
                this.parameters = ServiceActionParameter.EmptyServiceActionParameterCollection;
            }
            else
            {
                this.parameters = new ReadOnlyCollection<ServiceActionParameter>(base.OperationParameters.Cast<ServiceActionParameter>().ToList<ServiceActionParameter>());
            }
        }
Example #3
0
        /// <summary>
        /// Initializes a new <see cref="ServiceAction"/> instance.
        /// </summary>
        /// <param name="name">name of the action.</param>
        /// <param name="returnType">Return type of the action.</param>
        /// <param name="resultSet">EntitySet of the result expected from this action.</param>
        /// <param name="parameters">In-order parameters for this action.</param>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="instance">The instance on which to invoke the operation.</param>
        /// <param name="method">The methodInfo for the operation.</param>
        public ServiceAction AddAction(
            string name,
            ResourceType returnType,
            ResourceSet resultSet,
            IEnumerable <ServiceActionParameter> parameters,
            OperationParameterBindingKind operationParameterBindingKind,
            object instance   = null,
            MethodInfo method = null)
        {
            ServiceAction action = new ServiceAction(name, returnType, resultSet, operationParameterBindingKind, parameters);

            return(this.AddServiceAction(action, method, instance));
        }
Example #4
0
        /// <summary>
        /// Initializes a new <see cref="ServiceAction"/> instance.
        /// </summary>
        /// <param name="name">name of the action.</param>
        /// <param name="returnType">Return type of the action.</param>
        /// <param name="pathExpression">Path expression to calculate the result resource set of the function if the action returns an entity or a collection of entity; null otherwise.</param>
        /// <param name="parameters">In-order parameters for this action.</param>
        /// <param name="instance">The instance on which to invoke the operation.</param>
        /// <param name="method">The methodInfo for the operation.</param>
        public ServiceAction AddAction(string name, ResourceType returnType, ResourceSetPathExpression pathExpression, IEnumerable <ServiceActionParameter> parameters, object instance = null, MethodInfo method = null)
        {
            OperationParameterBindingKind kind = OperationParameterBindingKind.Sometimes;

            if (instance != null)
            {
                Enum.TryParse(instance.ToString(), true, out kind);
            }

            ServiceAction action = new ServiceAction(name, returnType, kind, parameters, pathExpression);

            return(this.AddServiceAction(action, method, instance));
        }
Example #5
0
        /// <summary>
        /// Validates the input parameters and convert it to a read only collection of parameters.
        /// </summary>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="parameters">In-order parameters for this operation.</param>
        /// <returns>A read only collection of parameters.</returns>
        private static ReadOnlyCollection <OperationParameter> ValidateParameters(OperationParameterBindingKind operationParameterBindingKind, IEnumerable <OperationParameter> parameters)
        {
            Debug.Assert(
                operationParameterBindingKind == OperationParameterBindingKind.Never ||
                operationParameterBindingKind == OperationParameterBindingKind.Always ||
                operationParameterBindingKind == OperationParameterBindingKind.Sometimes,
                "Unexpected value of OperationParameterBindingKind.");

            ReadOnlyCollection <OperationParameter> resultParameters;

            if (parameters == null)
            {
                resultParameters = OperationParameter.EmptyOperationParameterCollection;
            }
            else
            {
                resultParameters = new ReadOnlyCollection <OperationParameter>(new List <OperationParameter>(parameters));
                HashSet <string> paramNames = new HashSet <string>(StringComparer.Ordinal);

                int bindingParameterIndex = operationParameterBindingKind != OperationParameterBindingKind.Never ? 0 : -1;
                for (int idx = 0; idx < resultParameters.Count; idx++)
                {
                    OperationParameter parameter = resultParameters[idx];
                    if (!paramNames.Add(parameter.Name))
                    {
                        throw new ArgumentException(Strings.ServiceOperation_DuplicateParameterName(parameter.Name), "parameters");
                    }

                    if (idx > bindingParameterIndex)
                    {
                        ResourceTypeKind parameterTypeKind = parameter.ParameterType.ResourceTypeKind;
                        if (parameterTypeKind == ResourceTypeKind.EntityType || parameterTypeKind == ResourceTypeKind.EntityCollection)
                        {
                            throw new ArgumentException(Strings.ServiceOperation_NonBindingParametersCannotBeEntityorEntityCollection(parameter.Name, parameterTypeKind));
                        }
                    }
                }
            }

            return(resultParameters);
        }
    public ActionInfo(MethodInfo actionMethod, OperationParameterBindingKind bindable, string availabilityMethodName)
    {
        ActionMethod = actionMethod;
        Binding      = bindable;

        if ((Binding == OperationParameterBindingKind.Sometimes))
        {
            AvailabilityCheckMethod = GetAvailabilityMethod(availabilityMethodName);
            if (AvailabilityCheckMethod.GetCustomAttributes(typeof(SkipCheckForFeeds), true).Length != 0)
            {
                SkipAvailabilityCheckForFeeds = true;
            }
        }
        else
        {
            if (availabilityMethodName != null)
            {
                throw new Exception("Unexpected availabilityMethodName provided.");
            }
        }
    }
Example #7
0
 /// <summary>
 /// Initializes a new <see cref="ServiceAction"/> instance.
 /// </summary>
 /// <param name="name">Name of the action.</param>
 /// <param name="returnType">Return type of the action.</param>
 /// <param name="resultSet">Result resource set of the action if the action returns an entity or a collection of entity; null otherwise.</param>
 /// <param name="resultSetPathExpression">Path expression to calculate the result resource set of the function if the action returns an entity or a collection of entity; null otherwise.</param>
 /// <param name="parameters">In-order parameters for this action; the first parameter is the binding parameter.</param>
 /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
 /// <remarks>The value of <paramref name="operationParameterBindingKind"/> must be set to <see cref="OperationParameterBindingKind.Sometimes"/> or 
 /// <see cref="OperationParameterBindingKind.Always"/> if the first parameter in <paramref name="parameters"/> is the binding parameter 
 /// or <see cref="OperationParameterBindingKind.Never"/> if the first parameter is not a binding parameter. If the value of <paramref name="operationParameterBindingKind"/> 
 /// is set to <see cref="OperationParameterBindingKind.Always"/> then the IDataServiceActionProvider.AdvertiseServiceAction method will not be called for the action
 /// and the action will be always advertised by the default convention.</remarks>
 private ServiceAction(string name, ResourceType returnType, ResourceSet resultSet, ResourceSetPathExpression resultSetPathExpression, IEnumerable<ServiceActionParameter> parameters, OperationParameterBindingKind operationParameterBindingKind)
     : base(
     name,
     Operation.GetResultKindFromReturnType(returnType, isComposable: false),
     returnType,
     resultSet,
     resultSetPathExpression,
     XmlConstants.HttpMethodPost,
     parameters,
     operationParameterBindingKind,
     OperationKind.Action)
 {
     Debug.Assert(this.OperationParameters != null, "this.OperationParameters != null");
     if (this.OperationParameters == OperationParameter.EmptyOperationParameterCollection)
     {
         this.parameters = ServiceActionParameter.EmptyServiceActionParameterCollection;
     }
     else
     {
         this.parameters = new ReadOnlyCollection<ServiceActionParameter>(this.OperationParameters.Cast<ServiceActionParameter>().ToList());
     }
 }
Example #8
0
        /// <summary>
        /// Validates arguments to the constructor.
        /// </summary>
        /// <param name="operationName">Name of the operation.</param>
        /// <param name="returnType">Return type of the operation.</param>
        /// <param name="resultSet">EntitySet of the result expected from this operation, must be null if <paramref name="resultSetPathExpression"/> is not null.</param>
        /// <param name="resultSetPathExpression">Path expression to calculate the result set of the operation, must be null if <paramref name="resultSet"/> is not null.</param>
        /// <param name="method">Protocol (for example HTTP) method the service operation responds to.</param>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="kind">The kind of the current service operation.</param>
        private static void ValidateConstructorArguments(
            string operationName,
            ResourceType returnType,
            ResourceSet resultSet,
            ResourceSetPathExpression resultSetPathExpression,
            string method,
            OperationParameterBindingKind operationParameterBindingKind,
            OperationKind kind)
        {
            if (returnType != null && (returnType.ResourceTypeKind == ResourceTypeKind.EntityType || returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
            {
                ResourceType resultType = returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection ? ((EntityCollectionResourceType)returnType).ItemType : returnType;
                if (resultSet == null && resultSetPathExpression == null || resultSet != null && !resultSet.ResourceType.IsAssignableFrom(resultType))
                {
                    if (kind == OperationKind.ServiceOperation)
                    {
                        throw new ArgumentException(Strings.ServiceOperation_ResultTypeAndResultSetMustMatch("resultType", "resultSet"));
                    }

                    throw new ArgumentException(Strings.ServiceOperation_ReturnTypeAndResultSetMustMatch("returnType", "resultSetPathExpression", "resultSet"));
                }
            }
            else
            {
                if (resultSet != null || resultSetPathExpression != null)
                {
                    string setParameterName = resultSet != null ? "resultSet" : "resultSetPathExpression";
                    if (kind == OperationKind.ServiceOperation)
                    {
                        throw new ArgumentException(Strings.ServiceOperation_ResultSetMustBeNullForGivenResultType(setParameterName, "resultType"));
                    }

                    throw new ArgumentException(Strings.ServiceOperation_ResultSetMustBeNullForGivenReturnType(setParameterName, "returnType"));
                }
            }

            if (returnType != null && returnType == ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)))
            {
                string parameterName;
                string errorMessage;
                if (kind == OperationKind.ServiceOperation)
                {
                    parameterName = "resultType";
                    errorMessage  = Strings.ServiceOperation_InvalidResultType(returnType.FullName);
                }
                else
                {
                    parameterName = "returnType";
                    errorMessage  = Strings.ServiceOperation_InvalidReturnType(returnType.FullName);
                }

                throw new ArgumentException(errorMessage, parameterName);
            }

            if (string.CompareOrdinal(XmlConstants.HttpMethodGet, method) != 0 &&
                string.CompareOrdinal(XmlConstants.HttpMethodPost, method) != 0)
            {
                throw new ArgumentException(Strings.ServiceOperation_NotSupportedProtocolMethod(method, operationName), "method");
            }

            if (resultSetPathExpression != null && operationParameterBindingKind == OperationParameterBindingKind.Never)
            {
                // If the operation is not bindable, we want users to call the constructor that uses resultSet.
                throw new ArgumentException(Strings.ServiceOperation_MustBeBindableToUsePathExpression("resultSetPathExpression"), "resultSetPathExpression");
            }
        }
Example #9
0
        /// <summary>
        /// Initializes a new <see cref="Operation"/> instance.
        /// </summary>
        /// <param name="name">name of the operation.</param>
        /// <param name="resultKind">Kind of result expected from this operation.</param>
        /// <param name="returnType">Return type of the operation.</param>
        /// <param name="resultSet">EntitySet of the result expected from this operation, must be null if <paramref name="resultSetPathExpression"/> is not null.</param>
        /// <param name="resultSetPathExpression">Path expression to calculate the result set of the operation, must be null if <paramref name="resultSet"/> is not null.</param>
        /// <param name="method">Protocol (for example HTTP) method the service operation responds to.</param>
        /// <param name="parameters">In-order parameters for this operation.</param>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="kind">The kind of the current service operation.</param>
        internal Operation(
            string name,
            ServiceOperationResultKind resultKind,
            ResourceType returnType,
            ResourceSet resultSet,
            ResourceSetPathExpression resultSetPathExpression,
            string method,
            IEnumerable<OperationParameter> parameters,
            OperationParameterBindingKind operationParameterBindingKind,
            OperationKind kind)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
            WebUtil.CheckServiceOperationResultKind(resultKind, "resultKind");
            WebUtil.CheckStringArgumentNullOrEmpty(method, "method");

            Debug.Assert(
                this.GetType() == typeof(ServiceOperation) && kind == OperationKind.ServiceOperation ||
                this.GetType() == typeof(ServiceAction) && kind == OperationKind.Action,
                "OperationKind and the current type doesn't match.");

            ValidateConstructorArguments(name, returnType, resultSet, resultSetPathExpression, method, operationParameterBindingKind, kind);
            this.name = name;
            this.resultKind = resultKind;
            this.returnType = returnType;
            this.resourceSet = resultSet;
            this.resultSetPathExpression = resultSetPathExpression;
            this.method = method;
            this.kind = kind;
            this.operationParameterBindingKind = operationParameterBindingKind;
            this.operationParameters = Operation.ValidateParameters(this.operationParameterBindingKind, parameters);

            if (this.operationParameterBindingKind != OperationParameterBindingKind.Never)
            {
                Debug.Assert(
                    this.operationParameterBindingKind == OperationParameterBindingKind.Always || this.operationParameterBindingKind == OperationParameterBindingKind.Sometimes,
                    "Value of operationParameterBindingKind was expected to be 'always' or 'sometimes'.");

                Debug.Assert(this.kind != OperationKind.ServiceOperation, "ServiceOperations should never be bindable.");
                this.bindingParameter = this.operationParameters.FirstOrDefault();
                if (this.bindingParameter == null)
                {
                    throw new ArgumentException(Strings.ServiceOperation_BindableOperationMustHaveAtLeastOneParameter, "operationParameterBindingKind");
                }

                if (resourceSet != null)
                {
                    throw new ArgumentException(Strings.Opereration_BoundOperationsMustNotSpecifyEntitySetOnlyEntitySetPath(this.name), "resourceSet");
                }

                if (resultSetPathExpression != null &&
                    this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType &&
                    this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    throw new ArgumentException(Strings.ServiceOperation_BindingParameterMustBeEntityToUsePathExpression("resultSetPathExpression"));
                }

                if (this.kind == OperationKind.Action &&
                    !(this.bindingParameter.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType ||
                    this.bindingParameter.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
                {
                    throw new ArgumentException(Strings.ServiceOperation_ActionBindingMustBeEntityOrEntityCollection, "parameters");
                }

                if (this.resultSetPathExpression != null)
                {
                    this.resultSetPathExpression.SetBindingParameter(this.bindingParameter);
                }
            }

            Debug.Assert(this.kind != OperationKind.Action || string.CompareOrdinal(XmlConstants.HttpMethodPost, this.method) == 0, "HttpMethod must be POST for Actions.");
            Debug.Assert(this.resourceSet == null || this.resultSetPathExpression == null, "'resultSet' and 'resultSetPathExpression' cannot be both set by the constructor.");
        }
Example #10
0
        /// <summary>
        /// Validates the input parameters and convert it to a read only collection of parameters.
        /// </summary>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="parameters">In-order parameters for this operation.</param>
        /// <returns>A read only collection of parameters.</returns>
        private static ReadOnlyCollection<OperationParameter> ValidateParameters(OperationParameterBindingKind operationParameterBindingKind, IEnumerable<OperationParameter> parameters)
        {
            Debug.Assert(
                operationParameterBindingKind == OperationParameterBindingKind.Never || 
                operationParameterBindingKind == OperationParameterBindingKind.Always || 
                operationParameterBindingKind == OperationParameterBindingKind.Sometimes, 
                "Unexpected value of OperationParameterBindingKind.");

            ReadOnlyCollection<OperationParameter> resultParameters;
            if (parameters == null)
            {
                resultParameters = OperationParameter.EmptyOperationParameterCollection;
            }
            else
            {
                resultParameters = new ReadOnlyCollection<OperationParameter>(new List<OperationParameter>(parameters));
                HashSet<string> paramNames = new HashSet<string>(StringComparer.Ordinal);

                int bindingParameterIndex = operationParameterBindingKind != OperationParameterBindingKind.Never ? 0 : -1;
                for (int idx = 0; idx < resultParameters.Count; idx++)
                {
                    OperationParameter parameter = resultParameters[idx];
                    if (!paramNames.Add(parameter.Name))
                    {
                        throw new ArgumentException(Strings.ServiceOperation_DuplicateParameterName(parameter.Name), "parameters");
                    }

                    if (idx > bindingParameterIndex)
                    {
                        ResourceTypeKind parameterTypeKind = parameter.ParameterType.ResourceTypeKind;
                        if (parameterTypeKind == ResourceTypeKind.EntityType || parameterTypeKind == ResourceTypeKind.EntityCollection)
                        {
                            throw new ArgumentException(Strings.ServiceOperation_NonBindingParametersCannotBeEntityorEntityCollection(parameter.Name, parameterTypeKind));
                        }
                    }
                }
            }

            return resultParameters;
        }
Example #11
0
 private ServiceAction(string name, ResourceType returnType, ResourceSet resultSet, ResourceSetPathExpression resultSetPathExpression, IEnumerable <ServiceActionParameter> parameters, OperationParameterBindingKind operationParameterBindingKind) : base(name, Operation.GetResultKindFromReturnType(returnType, false), returnType, resultSet, resultSetPathExpression, "POST", parameters, operationParameterBindingKind, OperationKind.Action)
 {
     if (base.OperationParameters == OperationParameter.EmptyOperationParameterCollection)
     {
         this.parameters = ServiceActionParameter.EmptyServiceActionParameterCollection;
     }
     else
     {
         this.parameters = new ReadOnlyCollection <ServiceActionParameter>(base.OperationParameters.Cast <ServiceActionParameter>().ToList <ServiceActionParameter>());
     }
 }
Example #12
0
 /// <summary>
 /// Initializes a new <see cref="ServiceAction"/> instance.
 /// </summary>
 /// <param name="name">Name of the action.</param>
 /// <param name="returnType">Return type of the action.</param>
 /// <param name="resultSet">Result resource set of the action if the action returns an entity or a collection of entity; null otherwise.</param>
 /// <param name="resultSetPathExpression">Path expression to calculate the result resource set of the function if the action returns an entity or a collection of entity; null otherwise.</param>
 /// <param name="parameters">In-order parameters for this action; the first parameter is the binding parameter.</param>
 /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
 /// <remarks>The value of <paramref name="operationParameterBindingKind"/> must be set to <see cref="OperationParameterBindingKind.Sometimes"/> or
 /// <see cref="OperationParameterBindingKind.Always"/> if the first parameter in <paramref name="parameters"/> is the binding parameter
 /// or <see cref="OperationParameterBindingKind.Never"/> if the first parameter is not a binding parameter. If the value of <paramref name="operationParameterBindingKind"/>
 /// is set to <see cref="OperationParameterBindingKind.Always"/> then the IDataServiceActionProvider.AdvertiseServiceAction method will not be called for the action
 /// and the action will be always advertised by the default convention.</remarks>
 private ServiceAction(string name, ResourceType returnType, ResourceSet resultSet, ResourceSetPathExpression resultSetPathExpression, IEnumerable <ServiceActionParameter> parameters, OperationParameterBindingKind operationParameterBindingKind)
     : base(
         name,
         Operation.GetResultKindFromReturnType(returnType, isComposable: false),
         returnType,
         resultSet,
         resultSetPathExpression,
         XmlConstants.HttpMethodPost,
         parameters,
         operationParameterBindingKind,
         OperationKind.Action)
 {
     Debug.Assert(this.OperationParameters != null, "this.OperationParameters != null");
     if (this.OperationParameters == OperationParameter.EmptyOperationParameterCollection)
     {
         this.parameters = ServiceActionParameter.EmptyServiceActionParameterCollection;
     }
     else
     {
         this.parameters = new ReadOnlyCollection <ServiceActionParameter>(this.OperationParameters.Cast <ServiceActionParameter>().ToList());
     }
 }
Example #13
0
        public ServiceAction(string name, ResourceType returnType, ResourceSet resultSet, OperationParameterBindingKind operationParameterBindingKind, IEnumerable<ServiceActionParameter> parameters) : this(name, returnType, resultSet, null, parameters, operationParameterBindingKind)
        {

        }
Example #14
0
 /// <summary>Initializes a new <see cref="T:Microsoft.OData.Service.Providers.ServiceAction" /> instance.</summary>
 /// <param name="name">Name of the action.</param>
 /// <param name="returnType">Return type of the action.</param>
 /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
 /// <param name="parameters">In-order parameters for this action; the first parameter is the binding parameter.</param>
 /// <param name="resultSetPathExpression">Path expression to calculate the result resource set of the function if the action returns an entity or a collection of entity; null otherwise.</param>
 /// <remarks>The value of <paramref name="operationParameterBindingKind"/> must be set to <see cref="OperationParameterBindingKind.Sometimes"/> or
 /// <see cref="OperationParameterBindingKind.Always"/> if the first parameter in <paramref name="parameters"/> is the binding parameter
 /// or <see cref="OperationParameterBindingKind.Never"/> if the first parameter is not a binding parameter. If the value of <paramref name="operationParameterBindingKind"/>
 /// is set to <see cref="OperationParameterBindingKind.Always"/> then the IDataServiceActionProvider.AdvertiseServiceAction method will not be called for the action
 /// and the action will be always advertised by the default convention.</remarks>
 public ServiceAction(string name, ResourceType returnType, OperationParameterBindingKind operationParameterBindingKind, IEnumerable<ServiceActionParameter> parameters, ResourceSetPathExpression resultSetPathExpression)
     : this(name, returnType, null /*resultSet*/, resultSetPathExpression, parameters, operationParameterBindingKind)
 {
 }
Example #15
0
 /// <summary>
 /// Constructs a new instance of the attribute.
 /// </summary>
 /// <param name="isBindable">true if the first parameter to the method is the binding parameter; false otherwise.</param>
 public DSPActionAttribute(OperationParameterBindingKind operationParameterBindingKind)
 {
     this.OperationParameterBindingKind = operationParameterBindingKind;
     this.ParameterTypeNames            = DSPActionAttribute.EmptyStringArray;
 }
Example #16
0
        public void ServiceActionConstructorTests()
        {
            ResourceProperty id           = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceType     customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "Customer", false);

            customerType.AddProperty(id);
            customerType.SetReadOnly();
            ResourceSet  customerSet = new ResourceSet("Customers", customerType);
            ResourceType orderType   = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "Order", false);

            orderType.AddProperty(id);
            orderType.SetReadOnly();

            ResourceType complexType           = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "foo", "Address", false);
            ResourceType collectionOfPrimitive = ResourceType.GetCollectionResourceType(ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceType collectionOfComplex   = ResourceType.GetCollectionResourceType(complexType);
            ResourceType collectionOfCustomer  = ResourceType.GetEntityCollectionResourceType(customerType);
            ResourceType collectionOfOrder     = ResourceType.GetEntityCollectionResourceType(orderType);

            var types = ResourceTypeUtils.GetPrimitiveResourceTypes().Concat(new ResourceType[] { null, customerType, orderType, complexType, collectionOfPrimitive, collectionOfComplex, collectionOfCustomer, collectionOfOrder });
            var resultSetsOrPathExpressions = new object[] { null, customerSet, new ResourceSetPathExpression("p1/Foo") };
            var parameters = types.Except(new[] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)) }).Select(t => t != null ? new ServiceActionParameter[] { new ServiceActionParameter("p1", t) } : new ServiceActionParameter[0]);

            parameters = parameters.Concat(types.Except(new[] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)), null }).ToList().Combinations(2).Select(tt => new ServiceActionParameter[] { new ServiceActionParameter("p1", tt[0]), new ServiceActionParameter("p2", tt[1]) }));
            var operationParameterBindings = new OperationParameterBindingKind[] { OperationParameterBindingKind.Never, OperationParameterBindingKind.Sometimes, OperationParameterBindingKind.Always };

            AstoriaTestNS.TestUtil.RunCombinations(
                types, resultSetsOrPathExpressions, parameters, operationParameterBindings,
                (returnType, resultSetOrPathExpression, paramList, operationParameterBindingKind) =>
            {
                ServiceAction action    = null;
                ResourceSet resourceSet = resultSetOrPathExpression as ResourceSet;
                ResourceSetPathExpression pathExpression = resultSetOrPathExpression as ResourceSetPathExpression;
                bool bindable = (operationParameterBindingKind == OperationParameterBindingKind.Always || operationParameterBindingKind == OperationParameterBindingKind.Sometimes);
                Exception e   = null;

                try
                {
                    if (pathExpression != null)
                    {
                        bindable = true;
                        action   = new ServiceAction("foo", returnType, OperationParameterBindingKind.Sometimes, paramList, pathExpression);
                    }
                    else
                    {
                        action = new ServiceAction("foo", returnType, resourceSet, operationParameterBindingKind, paramList);
                    }
                }
                catch (Exception ex)
                {
                    e = ex;
                }
                if (resourceSet != null && operationParameterBindingKind != OperationParameterBindingKind.Never)
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "When 'returnType' is an entity type or an entity collection type, 'resultSetPathExpression' and 'resultSet' cannot be both null and the resource type of the result set must be assignable from 'returnType'.");
                }
                else if (returnType != null && (returnType.ResourceTypeKind == ResourceTypeKind.EntityType || returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection) &&
                         (resourceSet == null && pathExpression == null ||
                          resourceSet != null && returnType.ResourceTypeKind == ResourceTypeKind.EntityType && resourceSet.ResourceType != returnType ||
                          resourceSet != null && returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection && resourceSet.ResourceType != ((EntityCollectionResourceType)returnType).ItemType))
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "When 'returnType' is an entity type or an entity collection type, 'resultSetPathExpression' and 'resultSet' cannot be both null and the resource type of the result set must be assignable from 'returnType'.");
                }
                else if ((returnType == null || returnType.ResourceTypeKind != ResourceTypeKind.EntityCollection && returnType.ResourceTypeKind != ResourceTypeKind.EntityType) && resourceSet != null)
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "'resultSet' must be null when 'returnType' is null, not an entity type or not an entity collection type.");
                }
                else if ((returnType == null || returnType.ResourceTypeKind != ResourceTypeKind.EntityCollection && returnType.ResourceTypeKind != ResourceTypeKind.EntityType) && pathExpression != null)
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "'resultSetPathExpression' must be null when 'returnType' is null, not an entity type or not an entity collection type.");
                }
                else if (returnType == ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)))
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "The resource type 'Edm.Stream' is not a type that can be returned by a function or action. A function or action can only return values of an entity type, an entity collection type, a complex type, a collection type or any primitive type, other than the stream type.\r\nParameter name: returnType");
                }
                else if (paramList.Length > 0 && paramList.Skip(bindable ? 1 : 0).Any(p => p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType || p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
                {
                    var param             = paramList.Skip(bindable ? 1 : 0).First(p => p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType || p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection);
                    var parameterTypeKind = param.ParameterType.ResourceTypeKind;
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, string.Format("The '{0}' parameter is of resource type kind '{1}' and it is not the binding parameter. Parameter of type kind '{1}' is only supported for the binding parameter.", param.Name, parameterTypeKind));
                }
                else if (pathExpression != null && !bindable)
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "The binding parameter type must be an entity type or an entity collection type when 'resultSetPathExpression' is not null.");
                }
                else if (bindable && paramList.Length == 0)
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "Bindable actions or functions must have at least one parameter, where the first parameter is the binding parameter.\r\nParameter name: operationParameterBindingKind");
                }
                else if (pathExpression != null && bindable && paramList.First().ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType && paramList.First().ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "The binding parameter type must be an entity type or an entity collection type when 'resultSetPathExpression' is not null.");
                }
                else if (paramList.Length > 0 && bindable && paramList[0].ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType && paramList[0].ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    ExceptionUtils.IsExpectedException <ArgumentException>(e, "An action's binding parameter must be of type Entity or EntityCollection.\r\nParameter name: parameters");
                }
                else
                {
                    Assert.IsNull(e, "Received exception but expected none. Exception message: {0}", e == null ? string.Empty : e.Message);
                    Assert.IsNotNull(action, "Action should be constructed.");

                    Assert.AreEqual("foo", action.Name, "unexpected name");
                    Assert.AreEqual(returnType, action.ReturnType, "unexpected return type");
                    Assert.AreEqual(resourceSet, action.ResourceSet, "unexpected result set");
                    Assert.AreEqual(pathExpression, action.ResultSetPathExpression, "unexpected path expression");
                    Assert.IsTrue(!bindable || action.BindingParameter == action.Parameters.First(), "unexpected binding parameter");
                    Assert.IsTrue(action.Method == "POST", "HttpMethod must be POST for ServiceActions.");
                    Assert.IsTrue(action.ResourceSet == null || action.ResultSetPathExpression == null, "'resultSet' and 'resultSetPathExpression' cannot be both set by the constructor.");
                }
            });
        }
Example #17
0
        /// <summary>
        /// Initializes a new <see cref="Operation"/> instance.
        /// </summary>
        /// <param name="name">name of the operation.</param>
        /// <param name="resultKind">Kind of result expected from this operation.</param>
        /// <param name="returnType">Return type of the operation.</param>
        /// <param name="resultSet">EntitySet of the result expected from this operation, must be null if <paramref name="resultSetPathExpression"/> is not null.</param>
        /// <param name="resultSetPathExpression">Path expression to calculate the result set of the operation, must be null if <paramref name="resultSet"/> is not null.</param>
        /// <param name="method">Protocol (for example HTTP) method the service operation responds to.</param>
        /// <param name="parameters">In-order parameters for this operation.</param>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="kind">The kind of the current service operation.</param>
        internal Operation(
            string name,
            ServiceOperationResultKind resultKind,
            ResourceType returnType,
            ResourceSet resultSet,
            ResourceSetPathExpression resultSetPathExpression,
            string method,
            IEnumerable <OperationParameter> parameters,
            OperationParameterBindingKind operationParameterBindingKind,
            OperationKind kind)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
            WebUtil.CheckServiceOperationResultKind(resultKind, "resultKind");
            WebUtil.CheckStringArgumentNullOrEmpty(method, "method");

            Debug.Assert(
                this.GetType() == typeof(ServiceOperation) && kind == OperationKind.ServiceOperation ||
                this.GetType() == typeof(ServiceAction) && kind == OperationKind.Action,
                "OperationKind and the current type doesn't match.");

            ValidateConstructorArguments(name, returnType, resultSet, resultSetPathExpression, method, operationParameterBindingKind, kind);
            this.name                          = name;
            this.resultKind                    = resultKind;
            this.returnType                    = returnType;
            this.resourceSet                   = resultSet;
            this.resultSetPathExpression       = resultSetPathExpression;
            this.method                        = method;
            this.kind                          = kind;
            this.operationParameterBindingKind = operationParameterBindingKind;
            this.operationParameters           = Operation.ValidateParameters(this.operationParameterBindingKind, parameters);

            if (this.operationParameterBindingKind != OperationParameterBindingKind.Never)
            {
                Debug.Assert(
                    this.operationParameterBindingKind == OperationParameterBindingKind.Always || this.operationParameterBindingKind == OperationParameterBindingKind.Sometimes,
                    "Value of operationParameterBindingKind was expected to be 'always' or 'sometimes'.");

                Debug.Assert(this.kind != OperationKind.ServiceOperation, "ServiceOperations should never be bindable.");
                this.bindingParameter = this.operationParameters.FirstOrDefault();
                if (this.bindingParameter == null)
                {
                    throw new ArgumentException(Strings.ServiceOperation_BindableOperationMustHaveAtLeastOneParameter, "operationParameterBindingKind");
                }

                if (resourceSet != null)
                {
                    throw new ArgumentException(Strings.Opereration_BoundOperationsMustNotSpecifyEntitySetOnlyEntitySetPath(this.name), "resourceSet");
                }

                if (resultSetPathExpression != null &&
                    this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType &&
                    this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    throw new ArgumentException(Strings.ServiceOperation_BindingParameterMustBeEntityToUsePathExpression("resultSetPathExpression"));
                }

                if (this.kind == OperationKind.Action &&
                    !(this.bindingParameter.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType ||
                      this.bindingParameter.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
                {
                    throw new ArgumentException(Strings.ServiceOperation_ActionBindingMustBeEntityOrEntityCollection, "parameters");
                }

                if (this.resultSetPathExpression != null)
                {
                    this.resultSetPathExpression.SetBindingParameter(this.bindingParameter);
                }
            }

            Debug.Assert(this.kind != OperationKind.Action || string.CompareOrdinal(XmlConstants.HttpMethodPost, this.method) == 0, "HttpMethod must be POST for Actions.");
            Debug.Assert(this.resourceSet == null || this.resultSetPathExpression == null, "'resultSet' and 'resultSetPathExpression' cannot be both set by the constructor.");
        }
        public void ServiceActionConstructorTests()
        {
            ResourceProperty id = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceType customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "Customer", false);
            customerType.AddProperty(id);
            customerType.SetReadOnly();
            ResourceSet customerSet = new ResourceSet("Customers", customerType);
            ResourceType orderType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "Order", false);
            orderType.AddProperty(id);
            orderType.SetReadOnly();

            ResourceType complexType = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "foo", "Address", false);
            ResourceType collectionOfPrimitive = ResourceType.GetCollectionResourceType(ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceType collectionOfComplex = ResourceType.GetCollectionResourceType(complexType);
            ResourceType collectionOfCustomer = ResourceType.GetEntityCollectionResourceType(customerType);
            ResourceType collectionOfOrder = ResourceType.GetEntityCollectionResourceType(orderType);

            var types = ResourceTypeUtils.GetPrimitiveResourceTypes().Concat(new ResourceType[] { null, customerType, orderType, complexType, collectionOfPrimitive, collectionOfComplex, collectionOfCustomer, collectionOfOrder });
            var resultSetsOrPathExpressions = new object[] { null, customerSet, new ResourceSetPathExpression("p1/Foo") };
            var parameters = types.Except(new[] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)) }).Select(t => t != null ? new ServiceActionParameter[] { new ServiceActionParameter("p1", t) } : new ServiceActionParameter[0]);
            parameters = parameters.Concat(types.Except(new[] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)), null }).ToList().Combinations(2).Select(tt => new ServiceActionParameter[] { new ServiceActionParameter("p1", tt[0]), new ServiceActionParameter("p2", tt[1]) }));
            var operationParameterBindings = new OperationParameterBindingKind[] { OperationParameterBindingKind.Never, OperationParameterBindingKind.Sometimes, OperationParameterBindingKind.Always };

            AstoriaTestNS.TestUtil.RunCombinations(
                types, resultSetsOrPathExpressions, parameters, operationParameterBindings,
                (returnType, resultSetOrPathExpression, paramList, operationParameterBindingKind) =>
            {
                ServiceAction action = null;
                ResourceSet resourceSet = resultSetOrPathExpression as ResourceSet;
                ResourceSetPathExpression pathExpression = resultSetOrPathExpression as ResourceSetPathExpression;
                bool bindable = (operationParameterBindingKind == OperationParameterBindingKind.Always || operationParameterBindingKind == OperationParameterBindingKind.Sometimes);
                Exception e = null;

                try
                {
                    if (pathExpression != null)
                    {
                        bindable = true;
                        action = new ServiceAction("foo", returnType, OperationParameterBindingKind.Sometimes, paramList, pathExpression);
                    }
                    else
                    {
                        action = new ServiceAction("foo", returnType, resourceSet, operationParameterBindingKind, paramList);
                    }
                }
                catch (Exception ex)
                {
                    e = ex;
                }
                if (resourceSet != null && operationParameterBindingKind != OperationParameterBindingKind.Never)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "When 'returnType' is an entity type or an entity collection type, 'resultSetPathExpression' and 'resultSet' cannot be both null and the resource type of the result set must be assignable from 'returnType'.");
                }
                else if (returnType != null && (returnType.ResourceTypeKind == ResourceTypeKind.EntityType || returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection) &&
                    (resourceSet == null && pathExpression == null ||
                    resourceSet != null && returnType.ResourceTypeKind == ResourceTypeKind.EntityType && resourceSet.ResourceType != returnType ||
                    resourceSet != null && returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection && resourceSet.ResourceType != ((EntityCollectionResourceType)returnType).ItemType))
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "When 'returnType' is an entity type or an entity collection type, 'resultSetPathExpression' and 'resultSet' cannot be both null and the resource type of the result set must be assignable from 'returnType'.");
                }
                else if ((returnType == null || returnType.ResourceTypeKind != ResourceTypeKind.EntityCollection && returnType.ResourceTypeKind != ResourceTypeKind.EntityType) && resourceSet != null)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "'resultSet' must be null when 'returnType' is null, not an entity type or not an entity collection type.");
                }
                else if ((returnType == null || returnType.ResourceTypeKind != ResourceTypeKind.EntityCollection && returnType.ResourceTypeKind != ResourceTypeKind.EntityType) && pathExpression != null)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "'resultSetPathExpression' must be null when 'returnType' is null, not an entity type or not an entity collection type.");
                }
                else if (returnType == ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)))
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "The resource type 'Edm.Stream' is not a type that can be returned by a function or action. A function or action can only return values of an entity type, an entity collection type, a complex type, a collection type or any primitive type, other than the stream type.\r\nParameter name: returnType");
                }
                else if (paramList.Length > 0 && paramList.Skip(bindable ? 1 : 0).Any(p => p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType || p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
                {
                    var param = paramList.Skip(bindable ? 1 : 0).First(p => p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType || p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection);
                    var parameterTypeKind = param.ParameterType.ResourceTypeKind;
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, string.Format("The '{0}' parameter is of resource type kind '{1}' and it is not the binding parameter. Parameter of type kind '{1}' is only supported for the binding parameter.", param.Name, parameterTypeKind));
                }
                else if (pathExpression != null && !bindable)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "The binding parameter type must be an entity type or an entity collection type when 'resultSetPathExpression' is not null.");
                }
                else if (bindable && paramList.Length == 0)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "Bindable actions or functions must have at least one parameter, where the first parameter is the binding parameter.\r\nParameter name: operationParameterBindingKind");
                }
                else if (pathExpression != null && bindable && paramList.First().ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType && paramList.First().ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "The binding parameter type must be an entity type or an entity collection type when 'resultSetPathExpression' is not null.");
                }
                else if (paramList.Length > 0 && bindable && paramList[0].ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType && paramList[0].ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "An action's binding parameter must be of type Entity or EntityCollection.\r\nParameter name: parameters");
                }
                else
                {
                    Assert.IsNull(e, "Received exception but expected none. Exception message: {0}", e == null ? string.Empty : e.Message);
                    Assert.IsNotNull(action, "Action should be constructed.");

                    Assert.AreEqual("foo", action.Name, "unexpected name");
                    Assert.AreEqual(returnType, action.ReturnType, "unexpected return type");
                    Assert.AreEqual(resourceSet, action.ResourceSet, "unexpected result set");
                    Assert.AreEqual(pathExpression, action.ResultSetPathExpression, "unexpected path expression");
                    Assert.IsTrue(!bindable || action.BindingParameter == action.Parameters.First(), "unexpected binding parameter");
                    Assert.IsTrue(action.Method == "POST", "HttpMethod must be POST for ServiceActions.");
                    Assert.IsTrue(action.ResourceSet == null || action.ResultSetPathExpression == null, "'resultSet' and 'resultSetPathExpression' cannot be both set by the constructor.");
                }
            });
        }
Example #19
0
 /// <summary>Initializes a new <see cref="T:Microsoft.OData.Service.Providers.ServiceAction" /> instance.</summary>
 /// <param name="name">Name of the action.</param>
 /// <param name="returnType">Return type of the action.</param>
 /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
 /// <param name="parameters">In-order parameters for this action; the first parameter is the binding parameter.</param>
 /// <param name="resultSetPathExpression">Path expression to calculate the result resource set of the function if the action returns an entity or a collection of entity; null otherwise.</param>
 /// <remarks>The value of <paramref name="operationParameterBindingKind"/> must be set to <see cref="OperationParameterBindingKind.Sometimes"/> or
 /// <see cref="OperationParameterBindingKind.Always"/> if the first parameter in <paramref name="parameters"/> is the binding parameter
 /// or <see cref="OperationParameterBindingKind.Never"/> if the first parameter is not a binding parameter. If the value of <paramref name="operationParameterBindingKind"/>
 /// is set to <see cref="OperationParameterBindingKind.Always"/> then the IDataServiceActionProvider.AdvertiseServiceAction method will not be called for the action
 /// and the action will be always advertised by the default convention.</remarks>
 public ServiceAction(string name, ResourceType returnType, OperationParameterBindingKind operationParameterBindingKind, IEnumerable <ServiceActionParameter> parameters, ResourceSetPathExpression resultSetPathExpression)
     : this(name, returnType, null /*resultSet*/, resultSetPathExpression, parameters, operationParameterBindingKind)
 {
 }
Example #20
0
        /// <summary>
        /// Validates arguments to the constructor.
        /// </summary>
        /// <param name="operationName">Name of the operation.</param>
        /// <param name="returnType">Return type of the operation.</param>
        /// <param name="resultSet">EntitySet of the result expected from this operation, must be null if <paramref name="resultSetPathExpression"/> is not null.</param>
        /// <param name="resultSetPathExpression">Path expression to calculate the result set of the operation, must be null if <paramref name="resultSet"/> is not null.</param>
        /// <param name="method">Protocol (for example HTTP) method the service operation responds to.</param>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="kind">The kind of the current service operation.</param>
        private static void ValidateConstructorArguments(
            string operationName, 
            ResourceType returnType, 
            ResourceSet resultSet, 
            ResourceSetPathExpression resultSetPathExpression, 
            string method, 
            OperationParameterBindingKind operationParameterBindingKind, 
            OperationKind kind)
        {
            if (returnType != null && (returnType.ResourceTypeKind == ResourceTypeKind.EntityType || returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
            {
                ResourceType resultType = returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection ? ((EntityCollectionResourceType)returnType).ItemType : returnType;
                if (resultSet == null && resultSetPathExpression == null || resultSet != null && !resultSet.ResourceType.IsAssignableFrom(resultType))
                {
                    if (kind == OperationKind.ServiceOperation)
                    {
                        throw new ArgumentException(Strings.ServiceOperation_ResultTypeAndResultSetMustMatch("resultType", "resultSet"));
                    }

                    throw new ArgumentException(Strings.ServiceOperation_ReturnTypeAndResultSetMustMatch("returnType", "resultSetPathExpression", "resultSet"));
                }
            }
            else
            {
                if (resultSet != null || resultSetPathExpression != null)
                {
                    string setParameterName = resultSet != null ? "resultSet" : "resultSetPathExpression";
                    if (kind == OperationKind.ServiceOperation)
                    {
                        throw new ArgumentException(Strings.ServiceOperation_ResultSetMustBeNullForGivenResultType(setParameterName, "resultType"));
                    }

                    throw new ArgumentException(Strings.ServiceOperation_ResultSetMustBeNullForGivenReturnType(setParameterName, "returnType"));
                }
            }

            if (returnType != null && returnType == ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)))
            {
                string parameterName;
                string errorMessage;
                if (kind == OperationKind.ServiceOperation)
                {
                    parameterName = "resultType";
                    errorMessage = Strings.ServiceOperation_InvalidResultType(returnType.FullName);
                }
                else
                {
                    parameterName = "returnType";
                    errorMessage = Strings.ServiceOperation_InvalidReturnType(returnType.FullName);
                }

                throw new ArgumentException(errorMessage, parameterName);
            }

            if (string.CompareOrdinal(XmlConstants.HttpMethodGet, method) != 0 && 
                string.CompareOrdinal(XmlConstants.HttpMethodPost, method) != 0)
            {
                throw new ArgumentException(Strings.ServiceOperation_NotSupportedProtocolMethod(method, operationName), "method");
            }

            if (resultSetPathExpression != null && operationParameterBindingKind == OperationParameterBindingKind.Never)
            {
                // If the operation is not bindable, we want users to call the constructor that uses resultSet.
                throw new ArgumentException(Strings.ServiceOperation_MustBeBindableToUsePathExpression("resultSetPathExpression"), "resultSetPathExpression");
            }
        }
Example #21
0
 /// <summary>
 /// Constructs a new instance of the attribute.
 /// </summary>
 /// <param name="isBindable">true if the first parameter to the method is the binding parameter; false otherwise.</param>
 public DSPActionAttribute(OperationParameterBindingKind operationParameterBindingKind)
 {
     this.OperationParameterBindingKind = operationParameterBindingKind;
     this.ParameterTypeNames = DSPActionAttribute.EmptyStringArray;
 }
Example #22
0
 public ServiceAction(string name, ResourceType returnType, ResourceSet resultSet, OperationParameterBindingKind operationParameterBindingKind, IEnumerable <ServiceActionParameter> parameters) : this(name, returnType, resultSet, null, parameters, operationParameterBindingKind)
 {
 }