示例#1
0
        /// <summary>
        /// Creates the wrapper from the given service operation.
        /// </summary>
        /// <param name="serviceOperation">Service operation instance whose wrapper needs to get created.</param>
        /// <param name="resourceSetValidator">Resource set validator.</param>
        /// <param name="resourceTypeValidator">Resource type validator.</param>
        /// <returns>Wrapper for the given service operation.</returns>
        internal static ServiceOperationWrapper CreateServiceOperationWrapper(
            ServiceOperation serviceOperation,
            Func <ResourceSet, ResourceSetWrapper> resourceSetValidator,
            Func <ResourceType, ResourceType> resourceTypeValidator)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(serviceOperation != null, "serviceOperation != null");
            Debug.Assert(serviceOperation.IsReadOnly, "The serviceOperation must be read-only by now.");
            Debug.Assert(resourceSetValidator != null, "resourceSetValidator != null");
            Debug.Assert(resourceTypeValidator != null, "resourceTypeValidator != null");

            ServiceOperationWrapper serviceOperationWrapper = new ServiceOperationWrapper(serviceOperation);

#if DEBUG
            serviceOperationWrapper.isReadOnly = true;
#endif

            serviceOperationWrapper.resourceSet = resourceSetValidator(serviceOperation.ResourceSet);
            ResourceType resultType = serviceOperation.ResultType;
            if (resultType == null || resultType.ResourceTypeKind == ResourceTypeKind.Primitive)
            {
                // No need to validate primitive resource types
                serviceOperationWrapper.resultType = resultType;
            }
            else
            {
                // Validate the resource type of the result
                serviceOperationWrapper.resultType = resourceTypeValidator(resultType);
            }

            return(serviceOperationWrapper);
        }
        public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
        {
            var method = (MethodInfo)serviceOperation.CustomState;
            var currentDataContext = ((TypedDataSource)CurrentDataSource).DataContext;

            return method.Invoke(currentDataContext, parameters);
        }
 /// <summary>
 /// Throws if <paramref name="serviceOperation"/> is not sealed.
 /// </summary>
 /// <param name="serviceOperation">Service operation to inspect.</param>
 private static void ValidateServiceOperationReadOnly(ServiceOperation serviceOperation)
 {
     Debug.Assert(serviceOperation != null, "serviceOperation != null");
     if (!serviceOperation.IsReadOnly)
     {
         throw new ODataException(Strings.DataServiceMetadataProviderWrapper_ServiceOperationNotReadonly(serviceOperation.Name));
     }
 }
 /// <summary>
 /// Invoke the given service operation instance.
 /// </summary>
 /// <param name="serviceOperation">metadata for the service operation to invoke.</param>
 /// <param name="parameters">list of parameters to pass to the service operation.</param>
 /// <returns>returns the result by the service operation instance.</returns>
 public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
 {
     return(((MethodInfo)serviceOperation.CustomState).Invoke(
                this.dataServiceInstance,
                BindingFlags.Instance | BindingFlags.Instance | BindingFlags.FlattenHierarchy,
                null,
                parameters,
                Globalization.CultureInfo.InvariantCulture));
 }
示例#5
0
        /// <summary>
        /// Initializes a new <see cref="ServiceOperationWrapper"/> instance.
        /// </summary>
        /// <param name="serviceOperation">ServiceOperation instance to be wrapped.</param>
        public ServiceOperationWrapper(ServiceOperation serviceOperation)
        {
            Debug.Assert(serviceOperation != null, "serviceOperation != null");
            if (!serviceOperation.IsReadOnly)
            {
                throw new DataServiceException(500, Strings.DataServiceProviderWrapper_ServiceOperationNotReadonly(serviceOperation.Name));
            }

            this.serviceOperation = serviceOperation;
        }
        /// <summary>
        /// Initializes a new <see cref="ServiceOperationWrapper"/> instance.
        /// </summary>
        /// <param name="serviceOperation">ServiceOperation instance to be wrapped.</param>
        public ServiceOperationWrapper(ServiceOperation serviceOperation)
        {
            Debug.Assert(serviceOperation != null, "serviceOperation != null");
            if (!serviceOperation.IsReadOnly)
            {
                throw new DataServiceException(500, Strings.DataServiceProviderWrapper_ServiceOperationNotReadonly(serviceOperation.Name));
            }

            this.serviceOperation = serviceOperation;
        }
示例#7
0
        public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
        {
            object obj2;

            WebUtil.CheckArgumentNull <ServiceOperation>(serviceOperation, "serviceOperation");
            try
            {
                obj2 = ((MethodInfo)serviceOperation.CustomState).Invoke(this.dataServiceInstance, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance, null, parameters, CultureInfo.InvariantCulture);
            }
            catch (TargetInvocationException exception)
            {
                ErrorHandler.HandleTargetInvocationException(exception);
                throw;
            }
            return(obj2);
        }
        /// <summary>
        /// Validates if the service operation should be visible and is read only. If the service operation
        /// rights are set to None the service operation should not be visible.
        /// </summary>
        /// <param name="serviceOperation">Service operation to be validated.</param>
        /// <returns>Validated service operation, null if the service operation is not supposed to be visible.</returns>
        internal ServiceOperationWrapper ValidateServiceOperation(ServiceOperation serviceOperation)
        {
            DebugUtils.CheckNoExternalCallers();

            ServiceOperationWrapper serviceOperationWrapper = null;

            if (serviceOperation != null)
            {
                // For IDSP, we want to make sure the metadata object instance stay the same within
                // a request because we do reference comparisons.  Note the provider can return
                // different metadata instances within the same request.  The the Validate*() methods
                // will make sure to return the first cached instance.
                if (!this.serviceOperationCache.TryGetValue(serviceOperation.Name, out serviceOperationWrapper))
                {
                    ValidateServiceOperationReadOnly(serviceOperation);
                    serviceOperationWrapper = ServiceOperationWrapper.CreateServiceOperationWrapper(serviceOperation, this.ValidateResourceSet, this.ValidateResourceType);
                    this.serviceOperationCache[serviceOperation.Name] = serviceOperationWrapper;
                }
            }

            return(serviceOperationWrapper);
        }
示例#9
0
 /// <summary>Returns a service operation specified by its name.</summary>
 /// <param name="name">The name of the service operation to find.</param>
 /// <param name="serviceOperation">The service operation instance found.</param>
 /// <returns>true if the service operation was found or false otherwise.</returns>
 /// <remarks>The implementation of this method should be very fast as it will get called for many requests. It should also be fast
 /// for non-existing service operations to avoid possible DoS attacks on the service.</remarks>
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     bool found;
     readerWriterLock.EnterReadLock();
     try
     {
         found = this.serviceOperations.TryGetValue(name, out serviceOperation);
     }
     finally
     {
         readerWriterLock.ExitReadLock();
     }
     return found;
 }
 /// <summary>Invokes the specified service operation.</summary>
 /// <param name="serviceOperation">The service operation to invoke.</param>
 /// <param name="parameters">The parameters for the service operation. Their types will match the types of the declared parameters for the service operation.</param>
 /// <returns>The result of the service operation.
 /// If the service operation is declared to return void, this method should return null.
 /// Otherwise the method should return object of the type declared as the return type for the service operation.</returns>
 public virtual object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
 {
     throw new NotSupportedException("Service operations are not yet supported.");
 }
示例#11
0
        /// <summary>
        /// Adds a new <see cref="ServiceOperation"/> based on the specified <paramref name="method"/>
        /// instance.
        /// </summary>
        /// <param name="method">Method to expose as a service operation.</param>
        /// <param name="protocolMethod">Protocol (for example HTTP) method the service operation responds to.</param>
        private void AddServiceOperation(MethodInfo method, string protocolMethod)
        {
            Debug.Assert(method != null, "method != null");
            Debug.Assert(!method.IsAbstract, "!method.IsAbstract - if method is abstract, the type is abstract - already checked");

            // This method is only called for V1 providers, since in case of custom providers,
            // they are suppose to load the metadata themselves.
            if (this.metadata.ServiceOperations.ContainsKey(method.Name))
            {
                throw new InvalidOperationException(Strings.BaseServiceProvider_OverloadingNotSupported(this.Type, method));
            }

            bool hasSingleResult = SingleResultAttribute.MethodHasSingleResult(method);
            ServiceOperationResultKind resultKind;
            ResourceType resourceType = null;
            if (method.ReturnType == typeof(void))
            {
                resultKind = ServiceOperationResultKind.Void;
                this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1);
            }
            else
            {
                // Load the metadata of the resource type on the fly.
                // For Edm provider, it might not mean anything, but for reflection service provider, we need to
                // load the metadata of the type if its used only in service operation case
                Type resultType = null;
                if (WebUtil.IsPrimitiveType(method.ReturnType))
                {
                    resultKind = ServiceOperationResultKind.DirectValue;
                    resultType = method.ReturnType;
                    resourceType = ResourceType.GetPrimitiveResourceType(resultType);
                }
                else
                {
                    Type queryableElement = GetGenericInterfaceElementType(method.ReturnType, IQueryableTypeFilter);
                    if (queryableElement != null)
                    {
                        resultKind = hasSingleResult ?
                            ServiceOperationResultKind.QueryWithSingleResult :
                            ServiceOperationResultKind.QueryWithMultipleResults;
                        resultType = queryableElement;
                    }
                    else
                    {
                        Type enumerableElement = GetIEnumerableElement(method.ReturnType);
                        if (enumerableElement != null)
                        {
                            resultKind = ServiceOperationResultKind.Enumeration;
                            resultType = enumerableElement;
                        }
                        else
                        {
                            resultType = method.ReturnType;
                            resultKind = ServiceOperationResultKind.DirectValue;
                            this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1);
                        }
                    }

                    Debug.Assert(resultType != null, "resultType != null");
                    resourceType = ResourceType.GetPrimitiveResourceType(resultType);
                    if (resourceType == null)
                    {
                        resourceType = this.PopulateMetadataForType(resultType, this.TypeCache, this.ChildTypesCache, this.EntitySets.Values);
                    }
                }

                if (resourceType == null)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType));
                }

                if (resultKind == ServiceOperationResultKind.Enumeration && hasSingleResult)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(this.Type, method));
                }

                if (hasSingleResult ||
                    (!hasSingleResult &&
                    (resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType ||
                     resourceType.ResourceTypeKind == ResourceTypeKind.Primitive)))
                {
                    this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1);
                }
            }

            ParameterInfo[] parametersInfo = method.GetParameters();
            ServiceOperationParameter[] parameters = new ServiceOperationParameter[parametersInfo.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo = parametersInfo[i];
                if (parameterInfo.IsOut || parameterInfo.IsRetval)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_ParameterNotIn(method, parameterInfo));
                }

                ResourceType parameterType = ResourceType.GetPrimitiveResourceType(parameterInfo.ParameterType);
                if (parameterType == null)
                {
                    throw new InvalidOperationException(
                        Strings.BaseServiceProvider_ParameterTypeNotSupported(method, parameterInfo, parameterInfo.ParameterType));
                }

                string parameterName = parameterInfo.Name ?? "p" + i.ToString(CultureInfo.InvariantCulture);
                parameters[i] = new ServiceOperationParameter(parameterName, parameterType);
            }

            ResourceSet container = null;
            if (resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType)
            {
                if (!this.TryFindAnyContainerForType(resourceType, out container))
                {
                    throw new InvalidOperationException(
                        Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, resourceType.FullName));
                }
            }

            ServiceOperation operation = new ServiceOperation(method.Name, resultKind, resourceType, container, protocolMethod, parameters);
            operation.CustomState = method;
            MimeTypeAttribute attribute = MimeTypeAttribute.GetMimeTypeAttribute(method);
            if (attribute != null)
            {
                operation.MimeType = attribute.MimeType;
            }

            this.metadata.ServiceOperations.Add(method.Name, operation);
        }
示例#12
0
 /// <summary>
 /// Invoke the given service operation instance.
 /// </summary>
 /// <param name="serviceOperation">metadata for the service operation to invoke.</param>
 /// <param name="parameters">list of parameters to pass to the service operation.</param>
 /// <returns>returns the result by the service operation instance.</returns>
 public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
 {
     return ((MethodInfo)serviceOperation.CustomState).Invoke(
             this.dataServiceInstance,
             BindingFlags.Instance | BindingFlags.Instance | BindingFlags.FlattenHierarchy,
             null,
             parameters,
             Globalization.CultureInfo.InvariantCulture);
 }
示例#13
0
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     return this.metadata.ServiceOperations.TryGetValue(name, out serviceOperation);
 }
示例#14
0
 internal ServiceOperationRights GetServiceOperationRights(ServiceOperation serviceOperation)
 {
     ServiceOperationRights rightsForUnspecifiedServiceOperation;
     if (!this.serviceOperationRights.TryGetValue(serviceOperation.Name, out rightsForUnspecifiedServiceOperation))
     {
         rightsForUnspecifiedServiceOperation = this.rightsForUnspecifiedServiceOperation;
     }
     return rightsForUnspecifiedServiceOperation;
 }
        /// <summary>
        /// Adds a new <see cref="ServiceOperation"/> based on the specified <paramref name="method"/>
        /// instance.
        /// </summary>
        /// <param name="method">Method to expose as a service operation.</param>
        /// <param name="protocolMethod">Protocol (for example HTTP) method the service operation responds to.</param>
        private void AddServiceOperation(MethodInfo method, string protocolMethod)
        {
            Debug.Assert(method != null, "method != null");
            Debug.Assert(!method.IsAbstract, "!method.IsAbstract - if method is abstract, the type is abstract - already checked");

            // This method is only called for V1 providers, since in case of custom providers,
            // they are suppose to load the metadata themselves.
            if (this.metadata.ServiceOperations.ContainsKey(method.Name))
            {
                throw new InvalidOperationException(Strings.BaseServiceProvider_OverloadingNotSupported(this.Type, method));
            }

            bool hasSingleResult = SingleResultAttribute.MethodHasSingleResult(method);
            ServiceOperationResultKind resultKind;
            ResourceType resourceType = null;

            if (method.ReturnType == typeof(void))
            {
                resultKind = ServiceOperationResultKind.Void;
                this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1);
            }
            else
            {
                // Load the metadata of the resource type on the fly.
                // For Edm provider, it might not mean anything, but for reflection service provider, we need to
                // load the metadata of the type if its used only in service operation case
                Type resultType = null;
                if (WebUtil.IsPrimitiveType(method.ReturnType))
                {
                    resultKind   = ServiceOperationResultKind.DirectValue;
                    resultType   = method.ReturnType;
                    resourceType = ResourceType.GetPrimitiveResourceType(resultType);
                }
                else
                {
                    Type queryableElement = GetGenericInterfaceElementType(method.ReturnType, IQueryableTypeFilter);
                    if (queryableElement != null)
                    {
                        resultKind = hasSingleResult ?
                                     ServiceOperationResultKind.QueryWithSingleResult :
                                     ServiceOperationResultKind.QueryWithMultipleResults;
                        resultType = queryableElement;
                    }
                    else
                    {
                        Type enumerableElement = GetIEnumerableElement(method.ReturnType);
                        if (enumerableElement != null)
                        {
                            resultKind = ServiceOperationResultKind.Enumeration;
                            resultType = enumerableElement;
                        }
                        else
                        {
                            resultType = method.ReturnType;
                            resultKind = ServiceOperationResultKind.DirectValue;
                            this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1);
                        }
                    }

                    Debug.Assert(resultType != null, "resultType != null");
                    resourceType = ResourceType.GetPrimitiveResourceType(resultType);
                    if (resourceType == null)
                    {
                        resourceType = this.PopulateMetadataForType(resultType, this.TypeCache, this.ChildTypesCache, this.EntitySets.Values);
                    }
                }

                if (resourceType == null)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType));
                }

                if (resultKind == ServiceOperationResultKind.Enumeration && hasSingleResult)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(this.Type, method));
                }

                if (hasSingleResult ||
                    (!hasSingleResult &&
                     (resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType ||
                      resourceType.ResourceTypeKind == ResourceTypeKind.Primitive)))
                {
                    this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1);
                }
            }

            ParameterInfo[]             parametersInfo = method.GetParameters();
            ServiceOperationParameter[] parameters     = new ServiceOperationParameter[parametersInfo.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo = parametersInfo[i];
                if (parameterInfo.IsOut || parameterInfo.IsRetval)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_ParameterNotIn(method, parameterInfo));
                }

                ResourceType parameterType = ResourceType.GetPrimitiveResourceType(parameterInfo.ParameterType);
                if (parameterType == null)
                {
                    throw new InvalidOperationException(
                              Strings.BaseServiceProvider_ParameterTypeNotSupported(method, parameterInfo, parameterInfo.ParameterType));
                }

                string parameterName = parameterInfo.Name ?? "p" + i.ToString(CultureInfo.InvariantCulture);
                parameters[i] = new ServiceOperationParameter(parameterName, parameterType);
            }

            ResourceSet container = null;

            if (resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType)
            {
                if (!this.TryFindAnyContainerForType(resourceType, out container))
                {
                    throw new InvalidOperationException(
                              Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, resourceType.FullName));
                }
            }

            ServiceOperation operation = new ServiceOperation(method.Name, resultKind, resourceType, container, protocolMethod, parameters);

            operation.CustomState = method;
            MimeTypeAttribute attribute = MimeTypeAttribute.GetMimeTypeAttribute(method);

            if (attribute != null)
            {
                operation.MimeType = attribute.MimeType;
            }

            this.metadata.ServiceOperations.Add(method.Name, operation);
        }
 /// <summary>Given the specified name, tries to find a service operation.</summary>
 /// <param name="name">Name of the service operation to resolve.</param>
 /// <param name="serviceOperation">Returns the resolved service operation, null if no service operation was found for the given name.</param>
 /// <returns>True if we found the service operation for the given name, false otherwise.</returns>
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     Debug.Assert(!string.IsNullOrEmpty(name), "!string.IsNullOrEmpty(name)");
     return(this.metadata.ServiceOperations.TryGetValue(name, out serviceOperation));
 }
		/// <summary>
		/// Initializes a new <see cref="ServiceOperationWrapper"/> instance.
		/// </summary>
		/// <param name="serviceOperation">ServiceOperation instance to be wrapped.</param>
		private ServiceOperationWrapper(ServiceOperation serviceOperation)
		{
			Debug.Assert(serviceOperation != null, "serviceOperation != null");

			this.serviceOperation = serviceOperation;
		}
        /// <summary>
        /// Validates if the service operation should be visible and is read only. If the service operation
        /// rights are set to None the service operation should not be visible.
        /// </summary>
        /// <param name="serviceOperation">Service operation to be validated.</param>
        /// <returns>Validated service operation, null if the service operation is not supposed to be visible.</returns>
        public ServiceOperationWrapper ValidateServiceOperation(ServiceOperation serviceOperation)
        {
            DebugUtils.CheckNoExternalCallers();

            ServiceOperationWrapper serviceOperationWrapper = null;
            if (serviceOperation != null)
            {
                // For IDSP, we want to make sure the metadata object instance stay the same within
                // a request because we do reference comparisons.  Note the provider can return
                // different metadata instances within the same request.  The the Validate*() methods
                // will make sure to return the first cached instance.
                if (!this.serviceOperationCache.TryGetValue(serviceOperation.Name, out serviceOperationWrapper))
                {
                    ValidateServiceOperationReadOnly(serviceOperation);
                    serviceOperationWrapper = ServiceOperationWrapper.CreateServiceOperationWrapper(serviceOperation, this.ValidateResourceSet, this.ValidateResourceType);
                    this.serviceOperationCache[serviceOperation.Name] = serviceOperationWrapper;
                }
            }

            return serviceOperationWrapper;
        }
 /// <summary>
 /// Throws if <paramref name="serviceOperation"/> is not sealed.
 /// </summary>
 /// <param name="serviceOperation">Service operation to inspect.</param>
 public static void ValidateServiceOperationReadOnly(ServiceOperation serviceOperation)
 {
     Debug.Assert(serviceOperation != null, "serviceOperation != null");
     if (!serviceOperation.IsReadOnly)
     {
         throw new ODataException(Strings.DataServiceMetadataProviderWrapper_ServiceOperationNotReadonly(serviceOperation.Name));
     }
 }
示例#20
0
        private void AddServiceOperation(MethodInfo method, string protocolMethod)
        {
            ServiceOperationResultKind @void;

            if (this.metadata.ServiceOperations.ContainsKey(method.Name))
            {
                throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_OverloadingNotSupported(this.Type, method));
            }
            bool         flag      = SingleResultAttribute.MethodHasSingleResult(method);
            ResourceType primitive = null;

            if (method.ReturnType == typeof(void))
            {
                @void = ServiceOperationResultKind.Void;
            }
            else
            {
                System.Type returnType;
                if (WebUtil.IsPrimitiveType(method.ReturnType))
                {
                    @void      = ServiceOperationResultKind.DirectValue;
                    returnType = method.ReturnType;
                    primitive  = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(returnType);
                }
                else
                {
                    System.Type genericInterfaceElementType = GetGenericInterfaceElementType(method.ReturnType, new TypeFilter(BaseServiceProvider.IQueryableTypeFilter));
                    if (genericInterfaceElementType != null)
                    {
                        @void      = flag ? ServiceOperationResultKind.QueryWithSingleResult : ServiceOperationResultKind.QueryWithMultipleResults;
                        returnType = genericInterfaceElementType;
                    }
                    else
                    {
                        System.Type iEnumerableElement = GetIEnumerableElement(method.ReturnType);
                        if (iEnumerableElement != null)
                        {
                            @void      = ServiceOperationResultKind.Enumeration;
                            returnType = iEnumerableElement;
                        }
                        else
                        {
                            returnType = method.ReturnType;
                            @void      = ServiceOperationResultKind.DirectValue;
                        }
                    }
                    primitive = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(returnType);
                    if (primitive == null)
                    {
                        primitive = this.PopulateMetadataForType(returnType, this.TypeCache, this.ChildTypesCache, this.EntitySets.Values);
                    }
                }
                if (primitive == null)
                {
                    throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType));
                }
                if ((@void == ServiceOperationResultKind.Enumeration) && flag)
                {
                    throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(this.Type, method));
                }
            }
            ParameterInfo[]             parameters     = method.GetParameters();
            ServiceOperationParameter[] parameterArray = new ServiceOperationParameter[parameters.Length];
            for (int i = 0; i < parameterArray.Length; i++)
            {
                ParameterInfo info = parameters[i];
                if (info.IsOut || info.IsRetval)
                {
                    throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ParameterNotIn(method, info));
                }
                ResourceType parameterType = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(info.ParameterType);
                if (parameterType == null)
                {
                    throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ParameterTypeNotSupported(method, info, info.ParameterType));
                }
                string name = info.Name ?? ("p" + i.ToString(CultureInfo.InvariantCulture));
                parameterArray[i] = new ServiceOperationParameter(name, parameterType);
            }
            ResourceSet container = null;

            if (((primitive != null) && (primitive.ResourceTypeKind == ResourceTypeKind.EntityType)) && !this.TryFindAnyContainerForType(primitive, out container))
            {
                throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, primitive.FullName));
            }
            ServiceOperation operation = new ServiceOperation(method.Name, @void, primitive, container, protocolMethod, parameterArray)
            {
                CustomState = method
            };
            MimeTypeAttribute mimeTypeAttribute = MimeTypeAttribute.GetMimeTypeAttribute(method);

            if (mimeTypeAttribute != null)
            {
                operation.MimeType = mimeTypeAttribute.MimeType;
            }
            this.metadata.ServiceOperations.Add(method.Name, operation);
        }
示例#21
0
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     return(this.metadata.ServiceOperations.TryGetValue(name, out serviceOperation));
 }
        /// <summary>Invokes the specified service operation.</summary>
        /// <param name="serviceOperation">The service operation to invoke.</param>
        /// <param name="parameters">The parameters for the service operation. Their types will match the types of the declared parameters for the service operation.</param>
        /// <returns>The result of the service operation.
        /// If the service operation is declared to return void, this method should return null.
        /// Otherwise the method should return object of the type declared as the return type for the service operation.</returns>
        public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
        {
            if (invokeServiceOperationDel != null)
                return invokeServiceOperationDel(serviceOperation, parameters);

            throw new NotSupportedException("No service operation handler has been registered.");
        }
示例#23
0
        /// <summary>Gets the effective rights on the specified operation.</summary>
        /// <param name="serviceOperation">Operation to get rights for.</param>
        /// <returns>The effective rights as per this configuration.</returns>
        internal ServiceOperationRights GetServiceOperationRights(ServiceOperation serviceOperation)
        {
            Debug.Assert(serviceOperation != null, "operation != null");
            Debug.Assert(this.serviceRights != null, "this.serviceRights != null");

            ServiceOperationRights result;
            if (!this.serviceRights.TryGetValue(serviceOperation.Name, out result))
            {
                result = this.rightsForUnspecifiedServiceOperation;
            }

            return result;
        }
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     return _serviceOperations.TryGetValue(name, out serviceOperation);
 }
示例#25
0
 public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
 {
     object obj2;
     WebUtil.CheckArgumentNull<ServiceOperation>(serviceOperation, "serviceOperation");
     try
     {
         obj2 = ((MethodInfo) serviceOperation.CustomState).Invoke(this.dataServiceInstance, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance, null, parameters, CultureInfo.InvariantCulture);
     }
     catch (TargetInvocationException exception)
     {
         ErrorHandler.HandleTargetInvocationException(exception);
         throw;
     }
     return obj2;
 }
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     serviceOperation = null;
     return false;
 }
示例#27
0
 private void AddServiceOperation(MethodInfo method, string protocolMethod)
 {
     ServiceOperationResultKind @void;
     if (this.metadata.ServiceOperations.ContainsKey(method.Name))
     {
         throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_OverloadingNotSupported(this.Type, method));
     }
     bool flag = SingleResultAttribute.MethodHasSingleResult(method);
     ResourceType primitive = null;
     if (method.ReturnType == typeof(void))
     {
         @void = ServiceOperationResultKind.Void;
     }
     else
     {
         System.Type returnType;
         if (WebUtil.IsPrimitiveType(method.ReturnType))
         {
             @void = ServiceOperationResultKind.DirectValue;
             returnType = method.ReturnType;
             primitive = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(returnType);
         }
         else
         {
             System.Type genericInterfaceElementType = GetGenericInterfaceElementType(method.ReturnType, new TypeFilter(BaseServiceProvider.IQueryableTypeFilter));
             if (genericInterfaceElementType != null)
             {
                 @void = flag ? ServiceOperationResultKind.QueryWithSingleResult : ServiceOperationResultKind.QueryWithMultipleResults;
                 returnType = genericInterfaceElementType;
             }
             else
             {
                 System.Type iEnumerableElement = GetIEnumerableElement(method.ReturnType);
                 if (iEnumerableElement != null)
                 {
                     @void = ServiceOperationResultKind.Enumeration;
                     returnType = iEnumerableElement;
                 }
                 else
                 {
                     returnType = method.ReturnType;
                     @void = ServiceOperationResultKind.DirectValue;
                 }
             }
             primitive = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(returnType);
             if (primitive == null)
             {
                 primitive = this.PopulateMetadataForType(returnType, this.TypeCache, this.ChildTypesCache, this.EntitySets.Values);
             }
         }
         if (primitive == null)
         {
             throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType));
         }
         if ((@void == ServiceOperationResultKind.Enumeration) && flag)
         {
             throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(this.Type, method));
         }
     }
     ParameterInfo[] parameters = method.GetParameters();
     ServiceOperationParameter[] parameterArray = new ServiceOperationParameter[parameters.Length];
     for (int i = 0; i < parameterArray.Length; i++)
     {
         ParameterInfo info = parameters[i];
         if (info.IsOut || info.IsRetval)
         {
             throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ParameterNotIn(method, info));
         }
         ResourceType parameterType = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(info.ParameterType);
         if (parameterType == null)
         {
             throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ParameterTypeNotSupported(method, info, info.ParameterType));
         }
         string name = info.Name ?? ("p" + i.ToString(CultureInfo.InvariantCulture));
         parameterArray[i] = new ServiceOperationParameter(name, parameterType);
     }
     ResourceSet container = null;
     if (((primitive != null) && (primitive.ResourceTypeKind == ResourceTypeKind.EntityType)) && !this.TryFindAnyContainerForType(primitive, out container))
     {
         throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, primitive.FullName));
     }
     ServiceOperation operation = new ServiceOperation(method.Name, @void, primitive, container, protocolMethod, parameterArray) {
         CustomState = method
     };
     MimeTypeAttribute mimeTypeAttribute = MimeTypeAttribute.GetMimeTypeAttribute(method);
     if (mimeTypeAttribute != null)
     {
         operation.MimeType = mimeTypeAttribute.MimeType;
     }
     this.metadata.ServiceOperations.Add(method.Name, operation);
 }
        /// <summary>
        /// Invoke the given service operation and returns the results.
        /// </summary>
        /// <param name="serviceOperation">service operation to invoke.</param>
        /// <param name="parameters">value of parameters to pass to the service operation.</param>
        /// <returns>returns the result of the service operation. If the service operation returns void, then this should return null.</returns>
        public object InvokeServiceOperation(ServiceOperation serviceOperation, object[] parameters)
        {
            // Find the corresponding entry in metadata.
            DomainDataServiceMetadata.DomainDataServiceOperation op = this.metadata
                                                                          .ServiceOperations
                                                                          .Single(e => e.Key == serviceOperation.Name)
                                                                          .Value;

            // Since query operations always return sequence of values even if there is a singleton result, we need
            // to extract the value out of the single element comtaining sequence and hand that over to the data
            // service runtime.
            if (this.Result != null &&
                op.OperationKind == DomainOperation.Query &&
                op.ResultKind == ServiceOperationResultKind.DirectValue && 
                op.ResourceSet != null)
            {
                return (this.Result as IEnumerable<object>).Single();
            }

            return this.Result;
        }
示例#29
0
 /// <summary>Given the specified name, tries to find a service operation.</summary>
 /// <param name="name">Name of the service operation to resolve.</param>
 /// <param name="serviceOperation">Returns the resolved service operation, null if no service operation was found for the given name.</param>
 /// <returns>True if we found the service operation for the given name, false otherwise.</returns>
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     Debug.Assert(!string.IsNullOrEmpty(name), "!string.IsNullOrEmpty(name)");
     return this.metadata.ServiceOperations.TryGetValue(name, out serviceOperation);
 }
		/// <summary>
		/// Creates the wrapper from the given service operation.
		/// </summary>
		/// <param name="serviceOperation">Service operation instance whose wrapper needs to get created.</param>
		/// <param name="resourceSetValidator">Resource set validator.</param>
		/// <param name="resourceTypeValidator">Resource type validator.</param>
		/// <returns>Wrapper for the given service operation.</returns>
		public static ServiceOperationWrapper CreateServiceOperationWrapper(
			ServiceOperation serviceOperation,
			Func<ResourceSet, ResourceSetWrapper> resourceSetValidator,
			Func<ResourceType, ResourceType> resourceTypeValidator)
		{
			DebugUtils.CheckNoExternalCallers();
			Debug.Assert(serviceOperation != null, "serviceOperation != null");
			Debug.Assert(serviceOperation.IsReadOnly, "The serviceOperation must be read-only by now.");
			Debug.Assert(resourceSetValidator != null, "resourceSetValidator != null");
			Debug.Assert(resourceTypeValidator != null, "resourceTypeValidator != null");

			ServiceOperationWrapper serviceOperationWrapper = new ServiceOperationWrapper(serviceOperation);
#if DEBUG
			serviceOperationWrapper.isReadOnly = true;
#endif

			serviceOperationWrapper.resourceSet = resourceSetValidator(serviceOperation.ResourceSet);
			ResourceType resultType = serviceOperation.ResultType;
			if (resultType == null || resultType.ResourceTypeKind == ResourceTypeKind.Primitive)
			{
				// No need to validate primitive resource types
				serviceOperationWrapper.resultType = resultType;
			}
			else
			{
				// Validate the resource type of the result
				serviceOperationWrapper.resultType = resourceTypeValidator(resultType);
			}

			return serviceOperationWrapper;
		}
示例#31
0
 /// <summary>Returns a service operation specified by its name.</summary>
 /// <param name="name">The name of the service operation to find.</param>
 /// <param name="serviceOperation">The service operation instance found.</param>
 /// <returns>true if the service operation was found or false otherwise.</returns>
 /// <remarks>The implementation of this method should be very fast as it will get called for many requests. It should also be fast
 /// for non-existing service operations to avoid possible DoS attacks on the service.</remarks>
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     // No service operations are supported yet
     serviceOperation = null;
     return false;
 }
示例#32
0
 /// <summary>
 /// Adds a new service operation.
 /// </summary>
 /// <param name="name">The name of the service operation.</param>
 /// <param name="resultKind">The kind of service operation.</param>
 /// <param name="resultType">The type of service operation.</param>
 /// <param name="resultSet">Information about the resource.</param>
 /// <param name="method">The method of the service operation.</param>
 /// <param name="parameters">Parameters for the service operation.</param>
 /// <returns>The newly added service operation.</returns>
 public ServiceOperation AddServiceOperation(string name, ServiceOperationResultKind resultKind, ResourceType resultType, ResourceSet resultSet,
     string method, IEnumerable<ServiceOperationParameter> parameters)
 {
     ServiceOperation serviceOperation = new ServiceOperation(name, resultKind, resultType, resultSet, method, parameters);
     serviceOperation.SetReadOnly();
     readerWriterLock.EnterWriteLock();
     try
     {
         this.serviceOperations.Add(name, serviceOperation);
     }
     finally
     {
         readerWriterLock.ExitWriteLock();
     }
     return serviceOperation;
 }
 /// <summary>Given the specified name, tries to find a service operation.</summary>
 /// <param name="name">Name of the service operation to resolve.</param>
 /// <param name="serviceOperation">Returns the resolved service operation, null if no service operation was found for the given name.</param>
 /// <returns>True if we found the service operation for the given name, false otherwise.</returns>
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     DomainDataServiceMetadata.DomainDataServiceOperation op;
     bool result = this.metadata.ServiceOperations.TryGetValue(name, out op);
     serviceOperation = op;
     return result;
 }
示例#34
0
        /// <summary>
        /// Initializes a new <see cref="ServiceOperationWrapper"/> instance.
        /// </summary>
        /// <param name="serviceOperation">ServiceOperation instance to be wrapped.</param>
        private ServiceOperationWrapper(ServiceOperation serviceOperation)
        {
            Debug.Assert(serviceOperation != null, "serviceOperation != null");

            this.serviceOperation = serviceOperation;
        }