コード例 #1
0
        /// <summary>
        /// Gets the EDM model for the given type and request.
        /// </summary>
        /// <param name="elementClrType">The CLR type to retrieve a model for.</param>
        /// <param name="request">The request message to retrieve a model for.</param>
        /// <param name="actionDescriptor">The action descriptor for the action being queried on.</param>
        /// <returns>The EDM model for the given type and request.</returns>
        /// <remarks>
        /// Override this method to customize the EDM model used for querying.
        /// </remarks>
        public virtual IEdmModel GetModel(Type elementClrType, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)
        {
            // Get model for the request
            IEdmModel model = request.GetEdmModel();

            if (model == null || model.GetEdmType(elementClrType) == null)
            {
                // user has not configured anything or has registered a model without the element type
                // let's create one just for this type and cache it in the action descriptor
                model = actionDescriptor.GetEdmModel(elementClrType);
            }

            Contract.Assert(model != null);
            return(model);
        }
コード例 #2
0
            public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
            {
                if (actionContext == null)
                {
                    throw Error.ArgumentNull("actionContext");
                }

                HttpRequestMessage request = actionContext.Request;

                if (request == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveRequest);
                }

                HttpActionDescriptor actionDescriptor = actionContext.ActionDescriptor;

                if (actionDescriptor == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveDescriptor);
                }

                HttpConfiguration configuration = request.GetConfiguration();

                if (configuration == null)
                {
                    throw Error.Argument("actionContext", SRResources.RequestMustContainConfiguration);
                }

                // Get the entity type from the parameter type if it is ODataQueryOptions<T>.
                // Fall back to the return type if not. Also, note that the entity type from the return type and ODataQueryOptions<T>
                // can be different (example implementing $select or $expand).
                Type entityClrType = GetEntityClrTypeFromParameterType(Descriptor) ?? GetEntityClrTypeFromActionReturnType(actionDescriptor);

                IEdmModel         model            = configuration.GetEdmModel() ?? actionDescriptor.GetEdmModel(entityClrType);
                ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType);

                Func <ODataQueryContext, HttpRequestMessage, ODataQueryOptions> createODataQueryOptions =
                    (Func <ODataQueryContext, HttpRequestMessage, ODataQueryOptions>)Descriptor.Properties.GetOrAdd(CreateODataQueryOptionsCtorKey, _ =>
                {
                    return(Delegate.CreateDelegate(typeof(Func <ODataQueryContext, HttpRequestMessage, ODataQueryOptions>), _createODataQueryOptions.MakeGenericMethod(entityClrType)));
                });

                ODataQueryOptions parameterValue = createODataQueryOptions(entitySetContext, request);

                SetValue(actionContext, parameterValue);

                return(TaskHelpers.FromResult(0));
            }
コード例 #3
0
        private static ODataQueryContext CreateQueryContext(Type entityClrType, HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
        {
            // Primitive types do not construct an EDM model and deal only with the CLR Type
            if (TypeHelper.IsQueryPrimitiveType(entityClrType))
            {
                return(new ODataQueryContext(entityClrType));
            }
            else
            {
                // Get model for the entire app
                IEdmModel model = configuration.GetEdmModel();

                if (model == null)
                {
                    // user has not configured anything, now let's create one just for this type
                    // and cache it in the action descriptor
                    model = actionDescriptor.GetEdmModel(entityClrType);
                    Contract.Assert(model != null);
                }

                // parses the query from request uri
                return(new ODataQueryContext(model, entityClrType));
            }
        }
コード例 #4
0
            public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
            {
                if (actionContext == null)
                {
                    throw Error.ArgumentNull("actionContext");
                }

                HttpRequestMessage request = actionContext.Request;

                if (request == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveRequest);
                }

                HttpActionDescriptor actionDescriptor = actionContext.ActionDescriptor;

                if (actionDescriptor == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveDescriptor);
                }

                HttpConfiguration configuration = request.GetConfiguration();

                if (configuration == null)
                {
                    throw Error.Argument("actionContext", SRResources.RequestMustContainConfiguration);
                }

                IEdmModel model = configuration.GetEdmModel();

                if (actionDescriptor.ReturnType == null)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.InternalServerError,
                                                                                Error.Format(SRResources.FailedToBuildEdmModelBecauseReturnTypeIsNull,
                                                                                             actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName)));
                }

                Type entityClrType = TypeHelper.GetImplementedIEnumerableType(actionDescriptor.ReturnType);

                if (entityClrType == null)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.InternalServerError,
                                                                                Error.Format(SRResources.FailedToRetrieveTypeToBuildEdmModel, actionDescriptor.ReturnType.FullName,
                                                                                             actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName)));
                }

                if (model == null)
                {
                    model = actionDescriptor.GetEdmModel(entityClrType);
                }

                ODataQueryOptions parameterValue   = null;
                ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType);

                try
                {
                    parameterValue = new ODataQueryOptions(entitySetContext, request);
                    SetValue(actionContext, parameterValue);
                }
                catch (ODataException exception)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.BadRequest, exception));
                }

                return(TaskHelpers.FromResult(0));
            }
コード例 #5
0
        /// <summary>
        /// Gets the EDM model for the given type and request. Override this method to customize the EDM model used for
        /// querying.
        /// </summary>
        /// <param name="elementClrType">The CLR type to retrieve a model for.</param>
        /// <param name="request">The request message to retrieve a model for.</param>
        /// <param name="actionDescriptor">The action descriptor for the action being queried on.</param>
        /// <returns>The EDM model for the given type and request.</returns>
        public virtual IEdmModel GetModel(Type elementClrType, HttpRequestMessage request,
            HttpActionDescriptor actionDescriptor)
        {
            // Get model for the request
            IEdmModel model = request.ODataProperties().Model;

            if (model == null || model.GetEdmType(elementClrType) == null)
            {
                // user has not configured anything or has registered a model without the element type
                // let's create one just for this type and cache it in the action descriptor
                model = actionDescriptor.GetEdmModel(elementClrType);
            }

            Contract.Assert(model != null);
            return model;
        }
コード例 #6
0
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext == null)
            {
                throw Error.ArgumentNull("actionExecutedContext");
            }

            HttpRequestMessage request = actionExecutedContext.Request;

            if (request == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.ActionExecutedContextMustHaveRequest);
            }

            HttpConfiguration configuration = request.GetConfiguration();

            if (configuration == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.RequestMustContainConfiguration);
            }

            if (actionExecutedContext.ActionContext == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.ActionExecutedContextMustHaveActionContext);
            }

            HttpActionDescriptor actionDescriptor = actionExecutedContext.ActionContext.ActionDescriptor;

            if (actionDescriptor == null)
            {
                throw Error.Argument("actionExecutedContext", SRResources.ActionContextMustHaveDescriptor);
            }

            HttpResponseMessage response = actionExecutedContext.Response;

            IEnumerable query;
            IQueryable  queryable = null;

            if (response != null && response.IsSuccessStatusCode && response.TryGetContentValue(out query))
            {
                if (request.RequestUri != null && !String.IsNullOrWhiteSpace(request.RequestUri.Query))
                {
                    ValidateQuery(request);

                    try
                    {
                        ODataQueryContext queryContext;

                        Type originalQueryType = query.GetType();
                        Type entityClrType     = TypeHelper.GetImplementedIEnumerableType(originalQueryType);

                        // Primitive types do not construct an EDM model and deal only with the CLR Type
                        if (TypeHelper.IsQueryPrimitiveType(entityClrType))
                        {
                            queryContext = new ODataQueryContext(entityClrType);
                        }
                        else
                        {
                            // Get model for the entire app
                            IEdmModel model = configuration.GetEdmModel();

                            if (entityClrType == null)
                            {
                                // The actual type is not IEnumerable or IQueryable
                                actionExecutedContext.Response = request.CreateErrorResponse(
                                    HttpStatusCode.InternalServerError,
                                    Error.Format(SRResources.FailedToRetrieveTypeToBuildEdmModel, originalQueryType.FullName,
                                                 actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName));
                                return;
                            }

                            if (model == null)
                            {
                                // user has not configured anything, now let's create one just for this type
                                // and cache it in the action descriptor
                                model = actionDescriptor.GetEdmModel(entityClrType);
                            }

                            if (model == null)
                            {
                                // we need to send 500 if we can't create a model
                                actionExecutedContext.Response = request.CreateErrorResponse(
                                    HttpStatusCode.InternalServerError,
                                    Error.Format(SRResources.FailedToBuildEdmModel, entityClrType.FullName,
                                                 actionDescriptor.ActionName, actionDescriptor.ControllerDescriptor.ControllerName));
                                return;
                            }

                            // parses the query from request uri
                            queryContext = new ODataQueryContext(model, entityClrType);
                        }

                        ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, request);

                        // Filter and OrderBy require entity sets.  Top and Skip may accept primitives.
                        if (queryContext.IsPrimitiveClrType && (queryOptions.Filter != null || queryOptions.OrderBy != null))
                        {
                            // An attempt to use a query option not allowed for primitive types
                            // generates a BadRequest with a general message that avoids information disclosure.
                            actionExecutedContext.Response = request.CreateErrorResponse(
                                HttpStatusCode.BadRequest,
                                SRResources.OnlySkipAndTopSupported);
                            return;
                        }

                        // apply the query
                        queryable = query as IQueryable;
                        if (queryable == null)
                        {
                            queryable = query.AsQueryable();
                        }

                        if (_handleNullPropagation != null)
                        {
                            queryable = queryOptions.ApplyTo(queryable, _handleNullPropagation.Value);
                        }
                        else
                        {
                            queryable = queryOptions.ApplyTo(queryable);
                        }

                        Contract.Assert(queryable != null);

                        // we don't support shape changing query composition
                        ((ObjectContent)response.Content).Value = queryable;
                    }
                    catch (ODataException e)
                    {
                        actionExecutedContext.Response = request.CreateErrorResponse(
                            HttpStatusCode.BadRequest,
                            SRResources.UriQueryStringInvalid,
                            e);
                        return;
                    }
                }
            }
        }
コード例 #7
0
        private static ODataQueryContext CreateQueryContext(Type entityClrType, HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
        {
            // Primitive types do not construct an EDM model and deal only with the CLR Type
            if (TypeHelper.IsQueryPrimitiveType(entityClrType))
            {
                return new ODataQueryContext(entityClrType);
            }
            else
            {
                // Get model for the entire app
                IEdmModel model = configuration.GetEdmModel();

                if (model == null)
                {
                    // user has not configured anything, now let's create one just for this type
                    // and cache it in the action descriptor
                    model = actionDescriptor.GetEdmModel(entityClrType);
                    Contract.Assert(model != null);
                }

                // parses the query from request uri
                return new ODataQueryContext(model, entityClrType);
            }
        }
コード例 #8
0
            public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
            {
                if (actionContext == null)
                {
                    throw Error.ArgumentNull("actionContext");
                }

                HttpRequestMessage request = actionContext.Request;

                if (request == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveRequest);
                }

                HttpActionDescriptor actionDescriptor = actionContext.ActionDescriptor;

                if (actionDescriptor == null)
                {
                    throw Error.Argument("actionContext", SRResources.ActionContextMustHaveDescriptor);
                }

                HttpConfiguration configuration = request.GetConfiguration();

                if (configuration == null)
                {
                    throw Error.Argument("actionContext", SRResources.RequestMustContainConfiguration);
                }

                IEdmModel model = configuration.GetEdmModel();

                // It is a developer programming error to use this binding attribute
                // on actions that return void.
                if (actionDescriptor.ReturnType == null)
                {
                    throw Error.InvalidOperation(
                              SRResources.FailedToBuildEdmModelBecauseReturnTypeIsNull,
                              this.GetType().Name,
                              actionDescriptor.ActionName,
                              actionDescriptor.ControllerDescriptor.ControllerName);
                }

                Type entityClrType = TypeHelper.GetImplementedIEnumerableType(actionDescriptor.ReturnType);

                if (entityClrType == null)
                {
                    // It is a developer programming error to use this binding attribute
                    // on actions that return a collection whose element type cannot be
                    // determined, such as a non-generic IQueryable or IEnumerable.
                    throw Error.InvalidOperation(
                              SRResources.FailedToRetrieveTypeToBuildEdmModel,
                              this.GetType().Name,
                              actionDescriptor.ActionName,
                              actionDescriptor.ControllerDescriptor.ControllerName,
                              actionDescriptor.ReturnType.FullName);
                }

                if (model == null)
                {
                    model = actionDescriptor.GetEdmModel(entityClrType);
                }

                ODataQueryOptions parameterValue   = null;
                ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType);

                try
                {
                    parameterValue = new ODataQueryOptions(entitySetContext, request);
                    SetValue(actionContext, parameterValue);
                }
                catch (ODataException exception)
                {
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.BadRequest, exception));
                }

                return(TaskHelpers.FromResult(0));
            }