/// <summary> /// Validates the type of an entry in a top-level feed. /// </summary> /// <param name="entityType">The type of the entry.</param> internal void ValidateEntry(IEdmEntityType entityType) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entityType != null, "entityType != null"); // If we don't have a type, store the type of the first item. if (this.itemType == null) { this.itemType = entityType; } // Validate the expected and actual types. if (this.itemType.IsEquivalentTo(entityType)) { return; } // If the types are not equivalent, make sure they have a common base type. IEdmType commonBaseType = EdmLibraryExtensions.GetCommonBaseType(this.itemType, entityType); if (commonBaseType == null) { throw new ODataException(Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName())); } this.itemType = (IEdmEntityType)commonBaseType; }
internal static void CheckEntityPropertyMapping(ODataVersion version, IEdmEntityType entityType, IEdmModel model) { ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType); if ((epmCache != null) && (version < epmCache.EpmTargetTree.MinimumODataProtocolVersion)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_EpmVersionNotSupported(entityType.ODataFullName(), ODataUtils.ODataVersionToString(epmCache.EpmTargetTree.MinimumODataProtocolVersion), ODataUtils.ODataVersionToString(version))); } }
internal void ValidateEntry(IEdmEntityType entityType) { if (this.itemType == null) { this.itemType = entityType; } if (!((IEdmType) this.itemType).IsEquivalentTo(((IEdmType) entityType))) { IEdmType commonBaseType = this.itemType.GetCommonBaseType(entityType); if (commonBaseType == null) { throw new ODataException(Microsoft.Data.OData.Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName())); } this.itemType = (IEdmEntityType) commonBaseType; } }
private static void LoadEpmAnnotations(IEdmModel model, IEdmEntityType entityType) { string typeName = entityType.ODataFullName(); ODataEntityPropertyMappingCollection mappings = new ODataEntityPropertyMappingCollection(); model.LoadEpmAnnotations(entityType, mappings, typeName, null); IEnumerable <IEdmProperty> declaredProperties = entityType.DeclaredProperties; if (declaredProperties != null) { foreach (IEdmProperty property in declaredProperties) { model.LoadEpmAnnotations(property, mappings, typeName, property); } } model.SetAnnotationValue <ODataEntityPropertyMappingCollection>(entityType, mappings); }
/// <summary> /// If an entity type name is found in the payload this method is called to apply it to the current scope. /// This method should be called even if the type name was not found in which case a null should be passed in. /// The method validates that some type will be available as the current entity type after it returns (if we are parsing using metadata). /// </summary> /// <param name="entityTypeNameFromPayload">The entity type name found in the payload or null if no type was specified in the payload.</param> protected void ApplyEntityTypeNameFromPayload(string entityTypeNameFromPayload) { Debug.Assert( this.scopes.Count > 0 && this.scopes.Peek().Item is ODataEntry, "Entity type can be applied only when in entry scope."); SerializationTypeNameAnnotation serializationTypeNameAnnotation; EdmTypeKind targetTypeKind; IEdmEntityTypeReference targetEntityTypeReference = (IEdmEntityTypeReference)ReaderValidationUtils.ResolvePayloadTypeNameAndComputeTargetType( EdmTypeKind.Entity, /*defaultPrimitivePayloadType*/ null, this.CurrentEntityType.ToTypeReference(), entityTypeNameFromPayload, this.inputContext.Model, this.inputContext.MessageReaderSettings, this.inputContext.Version, () => EdmTypeKind.Entity, out targetTypeKind, out serializationTypeNameAnnotation); IEdmEntityType targetEntityType = null; ODataEntry entry = this.CurrentEntry; if (targetEntityTypeReference != null) { targetEntityType = targetEntityTypeReference.EntityDefinition(); entry.TypeName = targetEntityType.ODataFullName(); if (serializationTypeNameAnnotation != null) { entry.SetAnnotation(serializationTypeNameAnnotation); } } else if (entityTypeNameFromPayload != null) { entry.TypeName = entityTypeNameFromPayload; } // Set the current entity type since the type from payload might be more derived than // the expected one. this.CurrentEntityType = targetEntityType; }
/// <summary> /// Check whether the EPM on the specified entity type is supported in the specified version. /// </summary> /// <param name="version">The version to check.</param> /// <param name="entityType">The entity type to check.</param> /// <param name="model">The model containing annotations for the entity type.</param> internal static void CheckEntityPropertyMapping(ODataVersion version, IEdmEntityType entityType, IEdmModel model) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entityType != null, "entityType != null"); Debug.Assert(model != null, "model != null"); ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType); if (epmCache != null) { Debug.Assert(epmCache.EpmTargetTree != null, "If the EPM annotation is present the EPM tree must already be initialized."); if (version < epmCache.EpmTargetTree.MinimumODataProtocolVersion) { throw new ODataException( Strings.ODataVersionChecker_EpmVersionNotSupported( entityType.ODataFullName(), ODataUtils.ODataVersionToString(epmCache.EpmTargetTree.MinimumODataProtocolVersion), ODataUtils.ODataVersionToString(version))); } } }
protected void ApplyEntityTypeNameFromPayload(string entityTypeNameFromPayload) { SerializationTypeNameAnnotation annotation; EdmTypeKind kind; IEdmEntityTypeReference reference = (IEdmEntityTypeReference)ReaderValidationUtils.ResolvePayloadTypeNameAndComputeTargetType(EdmTypeKind.Entity, null, this.CurrentEntityType.ToTypeReference(), entityTypeNameFromPayload, this.inputContext.Model, this.inputContext.MessageReaderSettings, this.inputContext.Version, () => EdmTypeKind.Entity, out kind, out annotation); IEdmEntityType type = null; ODataEntry currentEntry = this.CurrentEntry; if (reference != null) { type = reference.EntityDefinition(); currentEntry.TypeName = type.ODataFullName(); if (annotation != null) { currentEntry.SetAnnotation <SerializationTypeNameAnnotation>(annotation); } } else if (entityTypeNameFromPayload != null) { currentEntry.TypeName = entityTypeNameFromPayload; } this.CurrentEntityType = type; }
/// <summary> /// Returns the fully qualified name of <paramref name="entityType"/> if it is a derived type of the <paramref name="entitySet"/>; /// returns null if <paramref name="entityType"/> is the root type of <paramref name="entitySet"/>. /// </summary> /// <param name="entitySet">The entity set in question.</param> /// <param name="entityType">The eneity type in question.</param> /// <returns> /// Returns the fully qualified name of <paramref name="entityType"/> if it is a derived type of the <paramref name="entitySet"/>; /// returns null if <paramref name="entityType"/> is the root type of <paramref name="entitySet"/>. /// </returns> private static string GetTypecast(IEdmEntitySet entitySet, IEdmEntityType entityType) { DebugUtils.CheckNoExternalCallers(); if (entitySet == null || entityType == null) { return(null); } // The client type resolver is not necessary for writes, ResolveEntitySetElementType() will return entitySet.ElementType when model is null // and we don't need to look up the type in the model. IEdmEntityType entitySetElementType = EdmTypeWriterResolver.Instance.GetElementType(entitySet); if (entitySetElementType.IsEquivalentTo(entityType)) { return(null); } if (!entitySetElementType.IsAssignableFrom(entityType)) { throw new ODataException(OData.Strings.ODataJsonLightMetadataUriBuilder_ValidateDerivedType(entitySetElementType.FullName(), entityType.FullName())); } return(entityType.ODataFullName()); }
/// <summary> /// Validates that a navigation property with the specified name exists on a given entity type. /// The entity type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param> /// <param name="messageReaderSettings">The message reader settings being used.</param> /// <returns>The <see cref="IEdmNavigationProperty"/> instance representing the navigation property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmNavigationProperty ValidateNavigationPropertyDefined( string propertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings) { Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); Debug.Assert(messageReaderSettings != null, "messageReaderSettings != null"); if (owningEntityType == null) { return null; } IEdmProperty property = ValidateLinkPropertyDefined(propertyName, owningEntityType, messageReaderSettings); if (property == null) { if (owningEntityType.IsOpen && !messageReaderSettings.ReportUndeclaredLinkProperties) { // We don't support open navigation properties throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } } else if (property.PropertyKind != EdmPropertyKind.Navigation) { // The property must be a navigation property throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return (IEdmNavigationProperty)property; }
private static void LoadEpmAnnotations(IEdmModel model, IEdmEntityType entityType) { string typeName = entityType.ODataFullName(); ODataEntityPropertyMappingCollection mappings = new ODataEntityPropertyMappingCollection(); model.LoadEpmAnnotations(entityType, mappings, typeName, null); IEnumerable<IEdmProperty> declaredProperties = entityType.DeclaredProperties; if (declaredProperties != null) { foreach (IEdmProperty property in declaredProperties) { model.LoadEpmAnnotations(property, mappings, typeName, property); } } model.SetAnnotationValue<ODataEntityPropertyMappingCollection>(entityType, mappings); }
/// <summary> /// Loads the serializable EPM annotations on the given <paramref name="entityType"/> into their in-memory representation. /// </summary> /// <param name="model">The model the entity type belongs to.</param> /// <param name="entityType">The <see cref="IEdmEntityType"/> to load the EPM annotations for.</param> private static void LoadEpmAnnotations(IEdmModel model, IEdmEntityType entityType) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entityType != null, "entityType != null"); string entityTypeName = entityType.ODataFullName(); ODataEntityPropertyMappingCollection mappings = new ODataEntityPropertyMappingCollection(); // Load the annotations from the type (these are the mappings for properties not explicitly declared on this type) model.LoadEpmAnnotations(entityType, mappings, entityTypeName, null /*property*/); IEnumerable<IEdmProperty> declaredProperties = entityType.DeclaredProperties; if (declaredProperties != null) { foreach (IEdmProperty property in declaredProperties) { // Load the EPM annotations for all properties independent of their kind in order to fail on invalid property kinds. model.LoadEpmAnnotations(property, mappings, entityTypeName, property); } } // Set the new EPM annotation on the entity type only at the very end to not leave a // inconsistent annotation if building it fails. model.SetAnnotationValue(entityType, mappings); }
/// <summary> /// Validates that the specified <paramref name="entry"/> is a valid entry as per the specified type. /// </summary> /// <param name="entry">The entry to validate.</param> /// <param name="entityType">Optional entity type to validate the entry against.</param> /// <param name="model">Model containing the entity type.</param> /// <param name="validateMediaResource">true if the validation of the default MediaResource should be done; false otherwise.</param> /// <remarks>If the <paramref name="entityType"/> is available only entry-level tests are performed, properties and such are not validated.</remarks> internal static void ValidateEntryMetadataResource(ODataEntry entry, IEdmEntityType entityType, IEdmModel model, bool validateMediaResource) { Debug.Assert(entry != null, "entry != null"); if (entityType != null) { Debug.Assert(model != null, "model != null"); Debug.Assert(model.IsUserModel(), "model.IsUserModel()"); if (validateMediaResource) { if (entry.MediaResource == null) { if (entityType.HasStream) { throw new ODataException(Strings.ValidationUtils_EntryWithoutMediaResourceAndMLEType(entityType.ODataFullName())); } } else { if (!entityType.HasStream) { throw new ODataException(Strings.ValidationUtils_EntryWithMediaResourceAndNonMLEType(entityType.ODataFullName())); } } } } }
/// <summary> /// Validates that a navigation property with the specified name exists on a given entity type. /// The entity type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the navigation property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType) { Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningEntityType == null) { return null; } IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType); if (property == null) { // We don't support open navigation properties Debug.Assert(owningEntityType.IsOpen, "We should have already failed on non-existing property on a closed type."); throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } if (property.PropertyKind != EdmPropertyKind.Navigation) { // The property must be a navigation property throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return (IEdmNavigationProperty)property; }
/// <summary> /// Validates that a navigation property with the specified name exists on a given entity type. /// The entity type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the navigation property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType) { Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningEntityType == null) { return(null); } IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType); if (property == null) { // We don't support open navigation properties Debug.Assert(owningEntityType.IsOpen, "We should have already failed on non-existing property on a closed type."); throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } if (property.PropertyKind != EdmPropertyKind.Navigation) { // The property must be a navigation property throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return((IEdmNavigationProperty)property); }
/// <summary> /// Binds a key property value. /// </summary> /// <param name="namedValue">The named value to bind.</param> /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param> /// <returns>The bound key property value node.</returns> private KeyPropertyValue BindKeyPropertyValue(NamedValue namedValue, IEdmEntityType collectionItemEntityType) { // These are exception checks because the data comes directly from the potentially user specified tree. ExceptionUtils.CheckArgumentNotNull(namedValue, "namedValue"); ExceptionUtils.CheckArgumentNotNull(namedValue.Value, "namedValue.Value"); Debug.Assert(collectionItemEntityType != null, "collectionItemType != null"); IEdmProperty keyProperty = null; if (namedValue.Name == null) { foreach (IEdmProperty p in collectionItemEntityType.Key()) { if (keyProperty == null) { keyProperty = p; } else { throw new ODataException(Strings.MetadataBinder_UnnamedKeyValueOnTypeWithMultipleKeyProperties(collectionItemEntityType.ODataFullName())); } } } else { keyProperty = collectionItemEntityType.Key().Where(k => string.CompareOrdinal(k.Name, namedValue.Name) == 0).SingleOrDefault(); if (keyProperty == null) { throw new ODataException(Strings.MetadataBinder_PropertyNotDeclaredOrNotKeyInKeyValue(namedValue.Name, collectionItemEntityType.ODataFullName())); } } IEdmTypeReference keyPropertyType = keyProperty.Type; SingleValueQueryNode value = (SingleValueQueryNode)this.Bind(namedValue.Value); // TODO: Check that the value is of primitive type value = ConvertToType(value, keyPropertyType); Debug.Assert(keyProperty != null, "keyProperty != null"); return new KeyPropertyValue() { KeyProperty = keyProperty, KeyValue = value }; }
internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmType parentNavigationPropertyType) { if (parentNavigationPropertyType != null) { IEdmEntityType baseType = (parentNavigationPropertyType.TypeKind == EdmTypeKind.Collection) ? ((IEdmEntityType) ((IEdmCollectionType) parentNavigationPropertyType).ElementType.Definition) : ((IEdmEntityType) parentNavigationPropertyType); if (!baseType.IsAssignableFrom(entryEntityType)) { throw new ODataException(Microsoft.Data.OData.Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), baseType.ODataFullName())); } } }
internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmType parentNavigationPropertyType) { if (parentNavigationPropertyType != null) { IEdmEntityType baseType = (parentNavigationPropertyType.TypeKind == EdmTypeKind.Collection) ? ((IEdmEntityType)((IEdmCollectionType)parentNavigationPropertyType).ElementType.Definition) : ((IEdmEntityType)parentNavigationPropertyType); if (!baseType.IsAssignableFrom(entryEntityType)) { throw new ODataException(Microsoft.Data.OData.Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), baseType.ODataFullName())); } } }
internal static IEdmProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType) { if (owningEntityType == null) { return(null); } IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType); if (property == null) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } if (property.PropertyKind != EdmPropertyKind.Navigation) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return(property); }
internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings) { if (owningEntityType == null) { return null; } IEdmProperty property = ValidateLinkPropertyDefined(propertyName, owningEntityType, messageReaderSettings); if (property == null) { if (owningEntityType.IsOpen) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } } else if (property.PropertyKind != EdmPropertyKind.Navigation) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return (IEdmNavigationProperty) property; }
internal static IEdmProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType) { if (owningEntityType == null) { return null; } IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType); if (property == null) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } if (property.PropertyKind != EdmPropertyKind.Navigation) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return property; }
/// <summary> /// Validates an entry in an expanded link to make sure the entity types match. /// </summary> /// <param name="entryEntityType">The <see cref="IEdmEntityType"/> of the entry.</param> /// <param name="parentNavigationPropertyType">The type of the parent navigation property.</param> internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmType parentNavigationPropertyType) { DebugUtils.CheckNoExternalCallers(); if (parentNavigationPropertyType == null) { return; } Debug.Assert(entryEntityType != null, "If we have a parent navigation property type we should also have an entry type."); bool navPropIsCollection = parentNavigationPropertyType.TypeKind == EdmTypeKind.Collection; IEdmEntityType parentNavigationPropertyEntityType = (IEdmEntityType)(navPropIsCollection ? ((IEdmCollectionType)parentNavigationPropertyType).ElementType.Definition : parentNavigationPropertyType); // Make sure the entity types are compatible if (!parentNavigationPropertyEntityType.IsAssignableFrom(entryEntityType)) { throw new ODataException(Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), parentNavigationPropertyEntityType.ODataFullName())); } }
/// <summary> /// Validates that a navigation property with the specified name exists on a given entity type. /// The entity type can be null if no metadata is available. /// </summary> /// <param name="propertyName">The name of the property to validate.</param> /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param> /// <param name="undeclaredPropertyBehaviorKinds">Value of UndeclaredPropertyBehaviorKinds in message settings.</param> /// <returns>The <see cref="IEdmProperty"/> instance representing the navigation property with name <paramref name="propertyName"/> /// or null if no metadata is available.</returns> internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType, ODataUndeclaredPropertyBehaviorKinds undeclaredPropertyBehaviorKinds) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)"); if (owningEntityType == null) { return(null); } IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType, undeclaredPropertyBehaviorKinds); if (property == null) { // .None / .LinkProperty bool throwErr = !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty) && !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.SupportUndeclaredValueProperty); // We don't support open navigation properties // when writing undeclared property is supported, shouldn't throw exception if (throwErr) { Debug.Assert(owningEntityType.IsOpen, "We should have already failed on non-existing property on a closed type."); } throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } if (property.PropertyKind != EdmPropertyKind.Navigation) { // The property must be a navigation property throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return((IEdmNavigationProperty)property); }
/// <summary> /// Binds a key property value. /// </summary> /// <param name="namedValue">The named value to bind.</param> /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param> /// <returns>The bound key property value node.</returns> private KeyPropertyValue BindKeyPropertyValue(NamedValue namedValue, IEdmEntityType collectionItemEntityType) { // These are exception checks because the data comes directly from the potentially user specified tree. ExceptionUtils.CheckArgumentNotNull(namedValue, "namedValue"); ExceptionUtils.CheckArgumentNotNull(namedValue.Value, "namedValue.Value"); Debug.Assert(collectionItemEntityType != null, "collectionItemType != null"); IEdmProperty keyProperty = null; if (namedValue.Name == null) { foreach (IEdmProperty p in collectionItemEntityType.Key()) { if (keyProperty == null) { keyProperty = p; } else { throw new ODataException(ODataErrorStrings.MetadataBinder_UnnamedKeyValueOnTypeWithMultipleKeyProperties(collectionItemEntityType.ODataFullName())); } } } else { keyProperty = collectionItemEntityType.Key().Where(k => string.CompareOrdinal(k.Name, namedValue.Name) == 0).SingleOrDefault(); if (keyProperty == null) { throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclaredOrNotKeyInKeyValue(namedValue.Name, collectionItemEntityType.ODataFullName())); } } IEdmTypeReference keyPropertyType = keyProperty.Type; SingleValueNode value = (SingleValueNode)this.keyValueBindMethod(namedValue.Value); // TODO: Check that the value is of primitive type Debug.Assert(keyPropertyType.IsODataPrimitiveTypeKind(), "The key's type must be primitive."); value = MetadataBindingUtils.ConvertToTypeIfNeeded(value, keyPropertyType); Debug.Assert(keyProperty != null, "keyProperty != null"); return(new KeyPropertyValue() { KeyProperty = keyProperty, KeyValue = value }); }
/// <summary> /// Binds a key property value. /// </summary> /// <param name="namedValue">The named value to bind.</param> /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param> /// <param name="keys">Dictionary of alias to keys.</param> /// <param name="keyPropertyValue">The bound key property value node.</param> /// <returns>The bound key property value node.</returns> private bool TryBindKeyPropertyValue(NamedValue namedValue, IEdmEntityType collectionItemEntityType, IDictionary<string, IEdmProperty> keys, out KeyPropertyValue keyPropertyValue) { // These are exception checks because the data comes directly from the potentially user specified tree. ExceptionUtils.CheckArgumentNotNull(namedValue, "namedValue"); ExceptionUtils.CheckArgumentNotNull(namedValue.Value, "namedValue.Value"); Debug.Assert(collectionItemEntityType != null, "collectionItemType != null"); IEdmProperty keyProperty = null; if (namedValue.Name == null) { foreach (IEdmProperty p in keys.Values) { if (keyProperty == null) { keyProperty = p; } else { throw new ODataException(ODataErrorStrings.MetadataBinder_UnnamedKeyValueOnTypeWithMultipleKeyProperties(collectionItemEntityType.ODataFullName())); } } } else { keyProperty = keys.SingleOrDefault(k => string.CompareOrdinal(k.Key, namedValue.Name) == 0).Value; if (keyProperty == null) { keyPropertyValue = null; return false; } } IEdmTypeReference keyPropertyType = keyProperty.Type; SingleValueNode value = (SingleValueNode)this.keyValueBindMethod(namedValue.Value); // TODO: Check that the value is of primitive type Debug.Assert(keyPropertyType.IsODataPrimitiveTypeKind(), "The key's type must be primitive."); value = MetadataBindingUtils.ConvertToTypeIfNeeded(value, keyPropertyType); Debug.Assert(keyProperty != null, "keyProperty != null"); keyPropertyValue = new KeyPropertyValue() { KeyProperty = keyProperty, KeyValue = value }; return true; }
/// <summary> /// Validates an entry in an expanded link to make sure the entity types match. /// </summary> /// <param name="entryEntityType">The <see cref="IEdmEntityType"/> of the entry.</param> /// <param name="parentNavigationPropertyType">The type of the parent navigation property.</param> internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmEntityType parentNavigationPropertyType) { if (parentNavigationPropertyType == null) { return; } Debug.Assert(entryEntityType != null, "If we have a parent navigation property type we should also have an entry type."); // Make sure the entity types are compatible if (!parentNavigationPropertyType.IsAssignableFrom(entryEntityType)) { throw new ODataException(Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), parentNavigationPropertyType.ODataFullName())); } }
internal static void ValidateEntryMetadata(ODataEntry entry, IEdmEntityType entityType, IEdmModel model, bool validateMediaResource) { if ((entityType != null) && validateMediaResource) { bool flag = model.HasDefaultStream(entityType); if (entry.MediaResource == null) { if (flag) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryWithoutMediaResourceAndMLEType(entityType.ODataFullName())); } } else if (!flag) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryWithMediaResourceAndNonMLEType(entityType.ODataFullName())); } } }
internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings) { if (owningEntityType == null) { return(null); } IEdmProperty property = ValidateLinkPropertyDefined(propertyName, owningEntityType, messageReaderSettings); if (property == null) { if (owningEntityType.IsOpen) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName())); } } else if (property.PropertyKind != EdmPropertyKind.Navigation) { throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString())); } return((IEdmNavigationProperty)property); }
/// <summary> /// Validates the type of an entry in a top-level feed. /// </summary> /// <param name="entityType">The type of the entry.</param> internal void ValidateEntry(IEdmEntityType entityType) { Debug.Assert(entityType != null, "entityType != null"); // If we don't have a type, store the type of the first item. if (this.itemType == null) { this.itemType = entityType; } // Validate the expected and actual types. if (this.itemType.IsEquivalentTo(entityType)) { return; } // If the types are not equivalent, make sure they have a common base type. IEdmType commonBaseType = EdmLibraryExtensions.GetCommonBaseType(this.itemType, entityType); if (commonBaseType == null) { throw new ODataException(Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName())); } this.itemType = (IEdmEntityType)commonBaseType; }
internal void ValidateEntry(IEdmEntityType entityType) { if (this.itemType == null) { this.itemType = entityType; } if (!((IEdmType)this.itemType).IsEquivalentTo(((IEdmType)entityType))) { IEdmType commonBaseType = this.itemType.GetCommonBaseType(entityType); if (commonBaseType == null) { throw new ODataException(Microsoft.Data.OData.Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName())); } this.itemType = (IEdmEntityType)commonBaseType; } }