private void Initialize(IEdmFunctionImport action)
        {
            IEdmTypeReference returnType = action.ReturnType;
            EdmType = returnType == null ? null : returnType.Definition;

            IEdmEntitySet functionEntitySet = null;
            if (action.TryGetStaticEntitySet(out functionEntitySet))
            {
                EntitySet = functionEntitySet;
            }
            Action = action;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ActionPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        /// <param name="action">The action being invoked.</param>
        public ActionPathSegment(ODataPathSegment previous, IEdmFunctionImport action)
            : base(previous)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            IEdmTypeReference returnType = action.ReturnType;
            EdmType = returnType == null ? null : returnType.Definition;

            IEdmEntitySet functionEntitySet = null;
            if (action.TryGetStaticEntitySet(out functionEntitySet))
            {
                EntitySet = functionEntitySet;
            }
            Action = action;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ActionPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        /// <param name="action">The action being invoked.</param>
        public ActionPathSegment(ODataPathSegment previous, IEdmFunctionImport action)
            : base(previous)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            IEdmTypeReference returnType = action.ReturnType;

            EdmType = returnType == null ? null : returnType.Definition;

            IEdmEntitySet functionEntitySet = null;

            if (action.TryGetStaticEntitySet(out functionEntitySet))
            {
                EntitySet = functionEntitySet;
            }
            Action = action;
        }
示例#4
0
        /// <summary>
        /// Gets the target entity set for the given function import.
        /// </summary>
        /// <param name="functionImport">The function import.</param>
        /// <param name="sourceEntitySet">The source entity set.</param>
        /// <param name="model">The model.</param>
        /// <returns>The target entity set of the function import or null if it could not be determined.</returns>
        internal static IEdmEntitySet GetTargetEntitySet(this IEdmFunctionImport functionImport, IEdmEntitySet sourceEntitySet, IEdmModel model)
        {
            DebugUtils.CheckNoExternalCallers();
            IEdmEntitySet targetEntitySet;

            if (functionImport.TryGetStaticEntitySet(out targetEntitySet))
            {
                return(targetEntitySet);
            }

            if (sourceEntitySet == null)
            {
                return(null);
            }

            if (functionImport.IsBindable && functionImport.Parameters.Any())
            {
                IEdmFunctionParameter parameter;
                IEnumerable <IEdmNavigationProperty> path;
                if (functionImport.TryGetRelativeEntitySetPath(model, out parameter, out path))
                {
                    // TODO: throw better exception
                    ExceptionUtil.ThrowSyntaxErrorIfNotValid(parameter == functionImport.Parameters.First());
                    targetEntitySet = sourceEntitySet;
                    foreach (var navigation in path)
                    {
                        targetEntitySet = targetEntitySet.FindNavigationTarget(navigation);
                        if (targetEntitySet == null)
                        {
                            return(null);
                        }
                    }

                    return(targetEntitySet);
                }
            }

            return(null);
        }
示例#5
0
        /// <inheritdoc />
        public virtual bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            ActionModel action = context.Action;
            IEdmModel   model  = context.Model;

            // By convention, we use the operation import name as the action name in the controller
            string actionMethodName = action.ActionName;

            var edmOperationImports = model.ResolveOperationImports(actionMethodName, enableCaseInsensitive: true);

            if (!edmOperationImports.Any())
            {
                return(true);
            }

            (var actionImports, var functionImports) = edmOperationImports.SplitOperationImports();

            // It's not allowed to have an action import and function import with the same name.
            if (actionImports.Count > 0 && functionImports.Count > 0)
            {
                throw new ODataException(Error.Format(SRResources.OperationMustBeUniqueInEntitySetContainer, actionMethodName));
            }
            else if (actionImports.Count > 0 && context.Action.Attributes.Any(a => a is HttpPostAttribute))
            {
                if (actionImports.Count != 1)
                {
                    throw new ODataException(Error.Format(SRResources.MultipleActionImportFound, actionMethodName));
                }

                IEdmActionImport actionImport = actionImports[0];

                IEdmEntitySetBase targetEntitySet;
                actionImport.TryGetStaticEntitySet(model, out targetEntitySet);

                // TODO:
                // 1. shall we check the [HttpPost] attribute, or does the ASP.NET Core have the default?
                // 2) shall we check the action has "ODataActionParameters" parameter type?
                ODataPathTemplate template = new ODataPathTemplate(new ActionImportSegmentTemplate(actionImport, targetEntitySet));
                action.AddSelector("Post", context.Prefix, context.Model, template, context.Options?.RouteOptions);
                return(true);
            }
            else if (functionImports.Count > 0 && context.Action.Attributes.Any(a => a is HttpGetAttribute))
            {
                IEdmFunctionImport functionImport = FindFunctionImport(functionImports, action);
                if (functionImport == null)
                {
                    return(false);
                }

                IEdmEntitySetBase targetSet;
                functionImport.TryGetStaticEntitySet(model, out targetSet);

                // TODO:
                // 1) shall we check the [HttpGet] attribute, or does the ASP.NET Core have the default?
                ODataPathTemplate template = new ODataPathTemplate(new FunctionImportSegmentTemplate(functionImport, targetSet));
                action.AddSelector("Get", context.Prefix, context.Model, template, context.Options?.RouteOptions);
                return(true);
            }
            else
            {
                // doesn't find an operation, return true means to skip the remaining conventions.
                return(false);
            }
        }
        /// <summary>
        /// Tries to get entity set.
        /// </summary>
        /// <param name="uri">The URI.</param>
        /// <param name="model">The model.</param>
        /// <param name="entitySet">The entity set.</param>
        /// <returns>
        /// True  if it gets and entitySet or false if it can't
        /// </returns>
        public static bool TryGetEntitySetAndEntityType(Uri uri, IEdmModel model, out IEdmEntitySet entitySet)
        {
            IEdmEntitySet currentEntitySet = null;

            entitySet = null;
            foreach (string segment in uri.Segments)
            {
                string segmentValue = segment.Replace("/", String.Empty);

                if (segmentValue.Length == 0)
                {
                    continue;
                }

                // lopping off key pieces as we don't care
                int i = segment.IndexOf('(');
                if (i > -1)
                {
                    segmentValue = segment.Remove(i);
                }

                IEdmEntityContainer container = model.EntityContainers().First();
                // If there is no entitySet we need to find out which one it is
                if (currentEntitySet == null)
                {
                    IEdmEntitySet foundEntitySet = container.FindEntitySet(segmentValue);
                    if (foundEntitySet != null)
                    {
                        currentEntitySet = foundEntitySet;
                    }
                    else
                    {
                        // check to see if there the current segment is a service operation
                        IEdmFunctionImport functionImport = container.FunctionImports().SingleOrDefault(fi => fi.Name == segmentValue);
                        if (functionImport != null)
                        {
                            IEdmEntitySet functionEntitySet = null;
                            if (functionImport.TryGetStaticEntitySet(out functionEntitySet))
                            {
                                currentEntitySet = functionEntitySet;
                            }
                        }
                    }
                }
                else
                {
                    IEdmNavigationProperty navigationProperty = currentEntitySet.ElementType.NavigationProperties().SingleOrDefault(np => np.Name == segmentValue);
                    if (navigationProperty != null)
                    {
                        currentEntitySet = currentEntitySet.FindNavigationTarget(navigationProperty);
                    }
                    else
                    {
                        // Need to update this a little so it works for Actions/Functions
                        IEdmFunctionImport functionImport = container.FunctionImports().SingleOrDefault(fi => fi.IsBindable == true && fi.Name == segmentValue);
                        if (functionImport != null)
                        {
                            IEdmEntitySet functionEntitySet = null;
                            if (functionImport.TryGetStaticEntitySet(out functionEntitySet))
                            {
                                currentEntitySet = functionEntitySet;
                            }
                        }
                    }
                }
            }

            if (currentEntitySet != null)
            {
                entitySet = currentEntitySet;
                return(true);
            }

            entitySet = null;

            return(false);
        }