/// <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 <IHttpActionResult> Post(EdmEntityObject edmEntityObject, CancellationToken cancellationToken) { if (edmEntityObject == null) { throw new ArgumentNullException(nameof(edmEntityObject)); } 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 = await api.GetModelAsync(cancellationToken).ConfigureAwait(false); var postItem = new DataModificationItem( entitySet.Name, expectedEntityType.GetClrType(model), actualEntityType.GetClrType(model), RestierEntitySetOperation.Insert, null, null, edmEntityObject.CreatePropertyDictionary(actualEntityType, api, true)); var changeSetProperty = Request.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)); }
public static IDictionary <string, PropertyAttributes> RetrievePropertiesAttributes( IEdmStructuredType edmType, ApiBase api) { if (typePropertiesAttributes.TryGetValue(edmType, out var propertiesAttributes)) { return(propertiesAttributes); } var model = api.GetModelAsync().Result; 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); }
public static Type GetClrType(this IEdmType edmType, ApiBase api) { IEdmModel edmModel = api.GetModelAsync().Result; ClrTypeAnnotation annotation = edmModel.GetAnnotationValue <ClrTypeAnnotation>(edmType); if (annotation != null) { return(annotation.ClrType); } throw new NotSupportedException(string.Format( CultureInfo.InvariantCulture, Resources.ElementTypeNotFound, edmType.FullTypeName())); }
private static IEdmModel GetModel(ApiBase api) { // Here await is not used because if method MapRestierRoute is mapped async, // Then during application starts, the http service initialization may complete first // before this method call is complete. // Then all request will fail, and this happen for some test cases before when get model takes long time. IEdmModel model; try { model = api.GetModelAsync().Result; } catch (AggregateException e) { // Without await, the exception is wrapped and inner exception has more meaningful message. throw e.InnerException; } return(model); }