Example #1
0
        /// <summary>
        /// Handles a POST request to create an entity.
        /// </summary>
        /// <param name="edmEntityObject">The entity object to create.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task object that contains the creation result.</returns>
        public async Task <IActionResult> Post(EdmEntityObject edmEntityObject, CancellationToken cancellationToken)
        {
            if (edmEntityObject == null)
            {
                throw new ArgumentNullException(nameof(edmEntityObject));
            }

            EnsureInitialized();

            CheckModelState();
            var path = GetPath();

            if (!(path.NavigationSource is IEdmEntitySet entitySet))
            {
                throw new NotImplementedException(Resources.InsertOnlySupportedOnEntitySet);
            }

            // In case of type inheritance, the actual type will be different from entity type
            var expectedEntityType = path.EdmType;
            var actualEntityType   = path.EdmType as IEdmStructuredType;

            if (edmEntityObject.ActualEdmType != null)
            {
                expectedEntityType = edmEntityObject.ExpectedEdmType;
                actualEntityType   = edmEntityObject.ActualEdmType;
            }

            var model = api.GetModel();

            var postItem = new DataModificationItem(
                entitySet.Name,
                expectedEntityType.GetClrType(model),
                actualEntityType.GetClrType(model),
                RestierEntitySetOperation.Insert,
                null,
                null,
                edmEntityObject.CreatePropertyDictionary(actualEntityType, api, true));

            var changeSetProperty = HttpContext.GetChangeSet();

            if (changeSetProperty == null)
            {
                var changeSet = new ChangeSet();
                changeSet.Entries.Add(postItem);

                var result = await api.SubmitAsync(changeSet, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                changeSetProperty.ChangeSet.Entries.Add(postItem);

                await changeSetProperty.OnChangeSetCompleted().ConfigureAwait(false);
            }

            return(CreateCreatedODataResult(postItem.Resource));
        }
Example #2
0
        /// <summary>
        /// Gets all the attributes for all properties on an Edm type.
        /// </summary>
        /// <param name="edmType">The Edm type.</param>
        /// <param name="api">The api.</param>
        /// <returns>A dictionary of property attributes.</returns>
        public static IDictionary <string, PropertyAttributes> RetrievePropertiesAttributes(
            IEdmStructuredType edmType, ApiBase api)
        {
            if (TypePropertiesAttributes.TryGetValue(edmType, out var propertiesAttributes))
            {
                return(propertiesAttributes);
            }

            var model = api.GetModel();

            foreach (var property in edmType.DeclaredProperties)
            {
                var annotations = model.FindVocabularyAnnotations(property);
                var attributes  = PropertyAttributes.None;
                foreach (var annotation in annotations)
                {
                    if (!(annotation is EdmVocabularyAnnotation valueAnnotation))
                    {
                        continue;
                    }

                    if (valueAnnotation.Term.IsSameTerm(CoreVocabularyModel.ImmutableTerm))
                    {
                        if (valueAnnotation.Value is EdmBooleanConstant value && value.Value)
                        {
                            attributes |= PropertyAttributes.IgnoreForUpdate;
                        }
                    }

                    if (valueAnnotation.Term.IsSameTerm(CoreVocabularyModel.ComputedTerm))
                    {
                        if (valueAnnotation.Value is EdmBooleanConstant value && value.Value)
                        {
                            attributes |= PropertyAttributes.IgnoreForUpdate;
                            attributes |= PropertyAttributes.IgnoreForCreation;
                        }
                    }

                    // TODO add permission annotation check
                    // CoreVocabularyModel has no permission yet, will add with #480
                }

                // Add property attributes to the dictionary
                if (attributes != PropertyAttributes.None)
                {
                    if (propertiesAttributes == null)
                    {
                        propertiesAttributes = new Dictionary <string, PropertyAttributes>();
                        TypePropertiesAttributes[edmType] = propertiesAttributes;
                    }

                    propertiesAttributes.Add(property.Name, attributes);
                }
            }

            return(propertiesAttributes);
        }
Example #3
0
        /// <summary>
        /// An extension method that generates a Markdown table of all of the possible Restier methods for the given API in the first column, and a boolean
        /// indicating whether or not the method was found in the second column.
        /// </summary>
        /// <param name="api">The <see cref="ApiBase"/> instance to process, typically inheriting from <see cref="EntityFrameworkApi{T}"/>.</param>
        /// <returns>A string containing the Markdown table of results.</returns>
        public static string GenerateVisibilityMatrix(this ApiBase api)
        {
            if (api == null)
            {
                throw new ArgumentNullException(nameof(api));
            }

            var sb      = new StringBuilder();
            var model   = (EdmModel)api.GetModel();
            var apiType = api.GetType();

            var conventions     = model.GenerateConventionDefinitions();
            var entitySetMatrix = conventions.OfType <RestierConventionEntitySetDefinition>().ToDictionary(c => c, c => false);
            var methodMatrix    = conventions.OfType <RestierConventionMethodDefinition>().ToDictionary(c => c, c => false);

            foreach (var definition in entitySetMatrix.ToList())
            {
                var value = false;
                switch (definition.Key.PipelineState)
                {
                case RestierPipelineState.Authorization:
                    value = IsAuthorizerMethodAccessible(apiType, definition.Key.Name);
                    break;

                default:
                    if (definition.Key.EntitySetOperation == RestierEntitySetOperation.Filter)
                    {
                        value = IsFilterMethodAccessible(apiType, definition.Key.Name);
                    }
                    else
                    {
                        value = IsInterceptorMethodAccessible(apiType, definition.Key.Name);
                    }
                    break;
                }
                entitySetMatrix[definition.Key] = value;
            }

            foreach (var definition in methodMatrix.ToList())
            {
                var value = false;
                switch (definition.Key.PipelineState)
                {
                case RestierPipelineState.Authorization:
                    value = IsAuthorizerMethodAccessible(apiType, definition.Key.Name);
                    break;

                default:
                    value = IsInterceptorMethodAccessible(apiType, definition.Key.Name);
                    break;
                }
                methodMatrix[definition.Key] = value;
            }

            sb.AppendLine(separator);
            sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0,-50} | {1,7}", "Function Name", "Found?"));
            sb.AppendLine(separator);
            foreach (var result in entitySetMatrix)
            {
                sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0,-50} | {1,7}", result.Key.Name, result.Value));
            }
            foreach (var result in methodMatrix)
            {
                sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0,-50} | {1,7}", result.Key.Name, result.Value));
            }
            sb.AppendLine(separator);

            return(sb.ToString());
        }