public void GetEdmModel_ThrowsArgumentNull_ActionDescriptor()
        {
            // Arrange & Act & Assert
            ActionDescriptor actionDescriptor = null;

            ExceptionAssert.ThrowsArgumentNull(() => actionDescriptor.GetEdmModel(null, null), "actionDescriptor");
        }
        public void GetEdmModel_Returns_CachedModel()
        {
            // Arrange
            IEdmModel        model            = new Mock <IEdmModel>().Object;
            ActionDescriptor actionDescriptor = new ActionDescriptor();
            string           key = "Microsoft.AspNetCore.OData.Model+" + typeof(ActionCustomer).FullName;

            actionDescriptor.Properties.Add(key, model);
            HttpRequest request = new Mock <HttpRequest>().Object;

            // Act
            IEdmModel actual = actionDescriptor.GetEdmModel(request, typeof(ActionCustomer));

            // Assert
            Assert.Same(model, actual);
        }
Пример #3
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 static IEdmModel GetModel(
            Type elementClrType,
            HttpRequest request,
            ActionDescriptor actionDescriptor)
        {
            // Get model for the request
            IEdmModel model = request.GetModel();

            if (model == EdmCoreModel.Instance || 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(request, elementClrType);
            }

            Contract.Assert(model != null);
            return(model);
        }
        public void GetEdmModel_Returns_BuiltEdmModel()
        {
            // Arrange
            string           key = "Microsoft.AspNetCore.OData.Model+" + typeof(ActionCustomer).FullName;
            ActionDescriptor actionDescriptor = new ActionDescriptor();

            Assert.False(actionDescriptor.Properties.TryGetValue(key, out _)); // Guard

            HttpContext        context  = new DefaultHttpContext();
            HttpRequest        request  = context.Request;
            IServiceCollection services = new ServiceCollection();

            context.RequestServices = services.BuildServiceProvider();

            // Act
            IEdmModel actual = actionDescriptor.GetEdmModel(request, typeof(ActionCustomer));

            // Assert
            Assert.NotNull(actual);
            actionDescriptor.Properties.TryGetValue(key, out object cachedModel);

            Assert.Same(cachedModel, actual);
        }
Пример #5
0
            public Task BindModelAsync(ModelBindingContext bindingContext)
            {
                if (bindingContext == null)
                {
                    throw Error.ArgumentNull(nameof(bindingContext));
                }

                HttpRequest request = bindingContext.HttpContext.Request;

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

                ActionDescriptor actionDescriptor = bindingContext.ActionContext.ActionDescriptor;

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

                // Get the parameter description of the parameter to bind.
                ParameterDescriptor paramDescriptor = bindingContext.ActionContext.ActionDescriptor.Parameters
                                                      .Where(p => p.Name == bindingContext.FieldName)
                                                      .FirstOrDefault();

                // Now make sure parameter type is ODataQueryOptions or ODataQueryOptions<T>.
                Type parameterType = paramDescriptor?.ParameterType;

                if (IsODataQueryOptions(parameterType))
                {
                    // 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 = null;
                    if (paramDescriptor != null)
                    {
                        entityClrType = GetEntityClrTypeFromParameterType(parameterType);
                    }

                    if (entityClrType == null)
                    {
                        entityClrType = GetEntityClrTypeFromActionReturnType(actionDescriptor);
                    }

                    // In 7.x, GetModel() from request will return "EdmCoreModel.Instance" for non-model scenario
                    // In 8.x, GetModel() return null.
                    IEdmModel         userModel        = request.GetModel();
                    IEdmModel         model            = userModel ?? actionDescriptor.GetEdmModel(request, entityClrType);
                    ODataQueryContext entitySetContext = new ODataQueryContext(model, entityClrType, request.ODataFeature().Path);

                    Func <ODataQueryContext, HttpRequest, ODataQueryOptions> createODataQueryOptions;
                    object constructorAsObject = null;
                    if (actionDescriptor.Properties.TryGetValue(CreateODataQueryOptionsCtorKey, out constructorAsObject))
                    {
                        createODataQueryOptions = (Func <ODataQueryContext, HttpRequest, ODataQueryOptions>)constructorAsObject;
                    }
                    else
                    {
                        createODataQueryOptions = (Func <ODataQueryContext, HttpRequest, ODataQueryOptions>)
                                                  Delegate.CreateDelegate(typeof(Func <ODataQueryContext, HttpRequest, ODataQueryOptions>),
                                                                          _createODataQueryOptions.MakeGenericMethod(entityClrType));
                    };

                    ODataQueryOptions parameterValue = createODataQueryOptions(entitySetContext, request);
                    bindingContext.Result = ModelBindingResult.Success(parameterValue);
                }

                return(Task.CompletedTask);
            }