private bool ShouldWritePropertyInContent(IEdmStructuredType owningType, ProjectedPropertiesAnnotation projectedProperties, string propertyName, object propertyValue, EpmSourcePathSegment epmSourcePathSegment)
 {
     bool flag = !projectedProperties.ShouldSkipProperty(propertyName);
     if ((((base.MessageWriterSettings.WriterBehavior != null) && base.MessageWriterSettings.WriterBehavior.UseV1ProviderBehavior) && (owningType != null)) && owningType.IsODataComplexTypeKind())
     {
         IEdmComplexType complexType = (IEdmComplexType) owningType;
         CachedPrimitiveKeepInContentAnnotation annotation = base.Model.EpmCachedKeepPrimitiveInContent(complexType);
         if ((annotation != null) && annotation.IsKeptInContent(propertyName))
         {
             return flag;
         }
     }
     if ((propertyValue == null) && (epmSourcePathSegment != null))
     {
         return true;
     }
     EntityPropertyMappingAttribute entityPropertyMapping = EpmWriterUtils.GetEntityPropertyMapping(epmSourcePathSegment);
     if (entityPropertyMapping == null)
     {
         return flag;
     }
     string str = propertyValue as string;
     if ((str != null) && (str.Length == 0))
     {
         switch (entityPropertyMapping.TargetSyndicationItem)
         {
             case SyndicationItemProperty.AuthorEmail:
             case SyndicationItemProperty.AuthorUri:
             case SyndicationItemProperty.ContributorEmail:
             case SyndicationItemProperty.ContributorUri:
                 return true;
         }
     }
     return (entityPropertyMapping.KeepInContent && flag);
 }
        /// <summary>
        /// Gets the property info for the EDM property declared on this type.
        /// </summary>
        /// <param name="structuredType">The structured type to get the property on.</param>
        /// <param name="property">Property instance to get the property info for.</param>
        /// <param name="model">The model containing annotations.</param>
        /// <returns>Returns the PropertyInfo object for the specified EDM property.</returns>
        internal PropertyInfo GetPropertyInfo(IEdmStructuredType structuredType, IEdmProperty property, IEdmModel model)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(structuredType != null, "structuredType != null");
            Debug.Assert(property != null, "property != null");
            Debug.Assert(model != null, "model != null");
            Debug.Assert(property.GetCanReflectOnInstanceTypeProperty(model), "property.CanReflectOnInstanceTypeProperty()");
#if DEBUG
            Debug.Assert(structuredType.ContainsProperty(property), "The structuredType does not define the specified property.");
#endif

            if (this.propertyInfosDeclaredOnThisType == null)
            {
                this.propertyInfosDeclaredOnThisType = new Dictionary<IEdmProperty, PropertyInfo>(ReferenceEqualityComparer<IEdmProperty>.Instance);
            }

            PropertyInfo propertyInfo;
            if (!this.propertyInfosDeclaredOnThisType.TryGetValue(property, out propertyInfo))
            {
                BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;
                propertyInfo = structuredType.GetInstanceType(model).GetProperty(property.Name, bindingFlags);
                if (propertyInfo == null)
                {
                    throw new ODataException(Strings.PropertyInfoTypeAnnotation_CannotFindProperty(structuredType.ODataFullName(), structuredType.GetInstanceType(model), property.Name));
                }

                this.propertyInfosDeclaredOnThisType.Add(property, propertyInfo);
            }

            Debug.Assert(propertyInfo != null, "propertyInfo != null");
            return propertyInfo;
        }
示例#3
0
        /// <summary>
        /// Constructs a new SelectBinder.
        /// </summary>
        /// <param name="model">The model used for binding.</param>
        /// <param name="edmType">The entity type that the $select is being applied to.</param>
        /// <param name="maxDepth">the maximum recursive depth.</param>
        /// <param name="expandClauseToDecorate">The already built expand clause to decorate</param>
       /// <param name="resolver">Resolver for uri parser.</param>
        public SelectBinder(IEdmModel model, IEdmStructuredType edmType, int maxDepth, SelectExpandClause expandClauseToDecorate, ODataUriResolver resolver = null)
        {
            ExceptionUtils.CheckArgumentNotNull(model, "tokenIn");
            ExceptionUtils.CheckArgumentNotNull(edmType, "entityType");

            this.visitor = new SelectPropertyVisitor(model, edmType, maxDepth, expandClauseToDecorate, resolver);
        }
示例#4
0
        public static IReadOnlyDictionary<string, object> CreatePropertyDictionary(
            this Delta entity, IEdmStructuredType edmType, ApiBase api, bool isCreation)
        {
            var propertiesAttributes = RetrievePropertiesAttributes(edmType, api);

            Dictionary<string, object> propertyValues = new Dictionary<string, object>();
            foreach (string propertyName in entity.GetChangedPropertyNames())
            {
                PropertyAttributes attributes;
                if (propertiesAttributes != null && propertiesAttributes.TryGetValue(propertyName, out attributes))
                {
                    if ((isCreation && (attributes & PropertyAttributes.IgnoreForCreation) != PropertyAttributes.None)
                      || (!isCreation && (attributes & PropertyAttributes.IgnoreForUpdate) != PropertyAttributes.None))
                    {
                        // Will not get the properties for update or creation
                        continue;
                    }
                }

                object value;
                if (entity.TryGetPropertyValue(propertyName, out value))
                {
                    var complexObj = value as EdmComplexObject;
                    if (complexObj != null)
                    {
                        value = CreatePropertyDictionary(complexObj, complexObj.ActualEdmType, api, isCreation);
                    }

                    propertyValues.Add(propertyName, value);
                }
            }

            return propertyValues;
        }
示例#5
0
		protected EdmProperty(IEdmStructuredType declaringType, string name, IEdmTypeReference type) : base(name)
		{
			this.dependents = new HashSetInternal<IDependent>();
			EdmUtil.CheckArgumentNull<IEdmStructuredType>(declaringType, "declaringType");
			EdmUtil.CheckArgumentNull<IEdmTypeReference>(type, "type");
			this.declaringType = declaringType;
			this.type = type;
		}
示例#6
0
		protected EdmStructuredType(bool isAbstract, bool isOpen, IEdmStructuredType baseStructuredType)
		{
			this.declaredProperties = new List<IEdmProperty>();
			this.propertiesDictionary = new Cache<EdmStructuredType, IDictionary<string, IEdmProperty>>();
			this.isAbstract = isAbstract;
			this.isOpen = isOpen;
			this.baseStructuredType = baseStructuredType;
		}
示例#7
0
 /// <summary>
 /// Build a property visitor to visit the select tree and decorate a SelectExpandClause
 /// </summary>
 /// <param name="model">The model used for binding.</param>
 /// <param name="edmType">The entity type that the $select is being applied to.</param>
 /// <param name="maxDepth">the maximum recursive depth.</param>
 /// <param name="expandClauseToDecorate">The already built expand clause to decorate</param>
 /// <param name="resolver">Resolver for uri parser.</param>
 public SelectPropertyVisitor(IEdmModel model, IEdmStructuredType edmType, int maxDepth, SelectExpandClause expandClauseToDecorate, ODataUriResolver resolver)
 {
     this.model = model;
     this.edmType = edmType;
     this.maxDepth = maxDepth;
     this.expandClauseToDecorate = expandClauseToDecorate;
     this.resolver = resolver ?? ODataUriResolver.Default;
 }
示例#8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmProperty"/> class.
        /// </summary>
        /// <param name="declaringType">The type that declares this property.</param>
        /// <param name="name">Name of the property.</param>
        /// <param name="type">Type of the property.</param>
        protected EdmProperty(IEdmStructuredType declaringType, string name, IEdmTypeReference type)
            : base(name)
        {
            EdmUtil.CheckArgumentNull(declaringType, "declaringType");
            EdmUtil.CheckArgumentNull(type, "type");

            this.declaringType = declaringType;
            this.type = type;
        }
示例#9
0
        /// <summary>
        /// Build the ExpandOption variant of an SelectExpandBinder
        /// </summary>
        /// <param name="configuration">The configuration used for binding.</param>
        /// <param name="edmType">The type of the top level expand item.</param>
        /// <param name="navigationSource">The navigation source of the top level expand item.</param>
        public SelectExpandBinder(ODataUriParserConfiguration configuration, IEdmStructuredType edmType, IEdmNavigationSource navigationSource)
        {
            ExceptionUtils.CheckArgumentNotNull(configuration, "configuration");
            ExceptionUtils.CheckArgumentNotNull(edmType, "edmType");

            this.configuration = configuration;
            this.edmType = edmType;
            this.navigationSource = navigationSource;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MetadataProviderEdmStructuralProperty"/> class.
 /// </summary>
 /// <param name="declaringType">The type that declares this property.</param>
 /// <param name="resourceProperty">The resource-property this edm property is based on.</param>
 /// <param name="type">The type of the property.</param>
 /// <param name="defaultValue">The default value of this property.</param>
 /// <param name="concurrencyMode">The concurrency mode of this property.</param>
 public MetadataProviderEdmStructuralProperty(
     IEdmStructuredType declaringType,
     ResourceProperty resourceProperty,
     IEdmTypeReference type, 
     string defaultValue,
     EdmConcurrencyMode concurrencyMode)
     : base(declaringType, resourceProperty.Name, type, defaultValue, concurrencyMode)
 {
     this.ResourceProperty = resourceProperty;
 }
示例#11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
        /// </summary>
        /// <param name="edmType">The <see cref="IEdmStructuredTypeReference"/> of this object.</param>
        /// <param name="isNullable">true if this object can be nullable; otherwise, false.</param>
        protected EdmStructuredObject(IEdmStructuredType edmType, bool isNullable)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            _expectedEdmType = edmType;
            _actualEdmType = edmType;
            IsNullable = isNullable;
        }
示例#12
0
		public BadProperty(IEdmStructuredType declaringType, string name, IEnumerable<EdmError> errors) : base(errors)
		{
			this.type = new Cache<BadProperty, IEdmTypeReference>();
			string str = name;
			string empty = str;
			if (str == null)
			{
				empty = string.Empty;
			}
			this.name = empty;
			this.declaringType = declaringType;
		}
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</param>
        /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</returns>
        public IEdmProperty ValidatePropertyDefined(
            string propertyName,
            IEdmStructuredType owningStructuredType,
            bool throwOnMissingProperty = true)
        {
            if (owningStructuredType == null)
            {
                return null;
            }

            return owningStructuredType.FindProperty(propertyName);
        }
        private IEdmEntityObject Createchool(int id, DateTimeOffset dto, IEdmStructuredType edmType)
        {
            IEdmNavigationProperty navigationProperty = edmType.DeclaredProperties.OfType<EdmNavigationProperty>().FirstOrDefault(e => e.Name == "School");
            if (navigationProperty == null)
            {
                return null;
            }

            EdmEntityObject entity = new EdmEntityObject(navigationProperty.ToEntityType());
            entity.TrySetPropertyValue("ID", id);
            entity.TrySetPropertyValue("CreatedDay", dto);
            return entity;
        }
示例#15
0
 internal static IEdmProperty FindDefinedProperty(string propertyName, IEdmStructuredType owningStructuredType, ODataMessageReaderSettings messageReaderSettings)
 {
     if (owningStructuredType == null)
     {
         return null;
     }
     IEdmProperty property = owningStructuredType.FindProperty(propertyName);
     if (((property == null) && owningStructuredType.IsOpen) && (messageReaderSettings.UndeclaredPropertyBehaviorKinds != ODataUndeclaredPropertyBehaviorKinds.None))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ReaderValidationUtils_UndeclaredPropertyBehaviorKindSpecifiedForOpenType(propertyName, owningStructuredType.ODataFullName()));
     }
     return property;
 }
        private IEdmEntityObject CreateDetailInfo(int id, string title, IEdmStructuredType edmType)
        {
            IEdmNavigationProperty navigationProperty = edmType.DeclaredProperties.OfType<EdmNavigationProperty>().FirstOrDefault(e => e.Name == "DetailInfo");
            if (navigationProperty == null)
            {
                return null;
            }

            EdmEntityObject entity = new EdmEntityObject(navigationProperty.ToEntityType());
            entity.TrySetPropertyValue("ID", id);
            entity.TrySetPropertyValue("Title", title);
            return entity;
        }
        /// <summary>
        /// Gets the property info annotation for the specified type or creates a new one if it doesn't exist.
        /// </summary>
        /// <param name="structuredType">The type to get the annotation for.</param>
        /// <param name="model">The model containing annotations.</param>
        /// <returns>The property info annotation.</returns>
        internal static PropertyInfoTypeAnnotation GetPropertyInfoTypeAnnotation(IEdmStructuredType structuredType, IEdmModel model)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(structuredType != null, "structuredType != null");
            Debug.Assert(model != null, "model != null");

            PropertyInfoTypeAnnotation propertyInfoTypeAnnotation = model.GetAnnotationValue<PropertyInfoTypeAnnotation>(structuredType);
            if (propertyInfoTypeAnnotation == null)
            {
                propertyInfoTypeAnnotation = new PropertyInfoTypeAnnotation();
                model.SetAnnotationValue(structuredType, propertyInfoTypeAnnotation);
            }

            return propertyInfoTypeAnnotation;
        }
        /// <summary>
        /// Validates a stream reference property.
        /// </summary>
        /// <param name="streamProperty">The stream property to check.</param>
        /// <param name="structuredType">The owning type of the stream property or null if no metadata is available.</param>
        /// <param name="streamEdmProperty">The stream property defined by the model.</param>
        /// <param name="messageReaderSettings">The message reader settings being used.</param>
        internal static void ValidateStreamReferenceProperty(ODataProperty streamProperty, IEdmStructuredType structuredType, IEdmProperty streamEdmProperty, ODataMessageReaderSettings messageReaderSettings)
        {
            Debug.Assert(streamProperty != null, "streamProperty != null");

            ValidationUtils.ValidateStreamReferenceProperty(streamProperty, streamEdmProperty);

            if (structuredType != null && structuredType.IsOpen)
            {
                // If no property match was found in the metadata and an error wasn't raised, 
                // it is an open property (which is not supported for streams).
                if (streamEdmProperty == null && !messageReaderSettings.ReportUndeclaredLinkProperties)
                {
                    // Fails with the correct error message.
                    ValidationUtils.ValidateOpenPropertyValue(streamProperty.Name, streamProperty.Value);
                }
            }
        }
        /// <summary>
        /// Validates a stream reference property.
        /// </summary>
        /// <param name="streamProperty">The stream property to check.</param>
        /// <param name="structuredType">The owning type of the stream property or null if no metadata is available.</param>
        /// <param name="streamEdmProperty">The stream property defined by the model.</param>
        internal static void ValidateStreamReferenceProperty(ODataProperty streamProperty, IEdmStructuredType structuredType, IEdmProperty streamEdmProperty)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(streamProperty != null, "streamProperty != null");

            ValidationUtils.ValidateStreamReferenceProperty(streamProperty, streamEdmProperty);

            if (structuredType != null && structuredType.IsOpen)
            {
                // If no property match was found in the metadata and an error wasn't raised, 
                // it is an open property (which is not supported for streams).
                if (streamEdmProperty == null)
                {
                    // Fails with the correct error message.
                    ValidationUtils.ValidateOpenPropertyValue(streamProperty.Name, streamProperty.Value);
                }
            }
        }
示例#20
0
 private IEdmProperty CreateEdmProperty(IEdmStructuredType declaringType, PropertyInfo propertyInfo)
 {
     IEdmProperty property;
     IEdmType edmType = this.GetOrCreateEdmTypeInternal(propertyInfo.PropertyType).EdmType;
     bool isNullable = ClientTypeUtil.CanAssignNull(propertyInfo.PropertyType);
     if ((edmType.TypeKind == EdmTypeKind.Entity) || ((edmType.TypeKind == EdmTypeKind.Collection) && (((IEdmCollectionType) edmType).ElementType.TypeKind() == EdmTypeKind.Entity)))
     {
         IEdmEntityType type2 = declaringType as IEdmEntityType;
         if (type2 == null)
         {
             throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.ClientTypeCache_NonEntityTypeCannotContainEntityProperties(propertyInfo.Name, propertyInfo.DeclaringType.ToString()));
         }
         property = EdmNavigationProperty.CreateNavigationPropertyWithPartner(propertyInfo.Name, edmType.ToEdmTypeReference(isNullable), null, false, EdmOnDeleteAction.None, "Partner", type2.ToEdmTypeReference(true), null, false, EdmOnDeleteAction.None);
     }
     else
     {
         property = new EdmStructuralProperty(declaringType, propertyInfo.Name, edmType.ToEdmTypeReference(isNullable));
     }
     property.SetClientPropertyAnnotation(new ClientPropertyAnnotation(property, propertyInfo, this.protocolVersion));
     return property;
 }
        /// <summary>
        /// Add semantic meaning to a Select or Expand Token
        /// </summary>
        /// <param name="elementType">the top level entity type.</param>
        /// <param name="navigationSource">the top level navigation source</param>
        /// <param name="expandToken">the syntactically parsed expand token</param>
        /// <param name="selectToken">the syntactically parsed select token</param>
        /// <param name="configuration">The configuration to use for parsing.</param>
        /// <returns>A select expand clause bound to metadata.</returns>
        public SelectExpandClause Bind(
            IEdmStructuredType elementType, 
            IEdmNavigationSource navigationSource,
            ExpandToken expandToken, 
            SelectToken selectToken, 
            ODataUriParserConfiguration configuration)
        {
            ExpandToken unifiedSelectExpandToken = SelectExpandSyntacticUnifier.Combine(expandToken, selectToken);

            ExpandTreeNormalizer expandTreeNormalizer = new ExpandTreeNormalizer();
            ExpandToken normalizedSelectExpandToken = expandTreeNormalizer.NormalizeExpandTree(unifiedSelectExpandToken);

            SelectExpandBinder selectExpandBinder = new SelectExpandBinder(configuration, elementType, navigationSource);
            SelectExpandClause clause = selectExpandBinder.Bind(normalizedSelectExpandToken);

            SelectExpandClauseFinisher.AddExplicitNavPropLinksWhereNecessary(clause);

            new ExpandDepthAndCountValidator(configuration.Settings.MaximumExpansionDepth, configuration.Settings.MaximumExpansionCount).Validate(clause);

            return clause;
        }
        /// <summary>
        /// Follow any type segments on the path, stopping at the first segment that isn't a type token.
        /// </summary>
        /// <param name="firstTypeToken">the first type segment</param>
        /// <param name="model">the model these types are contained in.</param>
        /// <param name="maxDepth">the maximum recursive depth</param>
        /// <param name="resolver">Resolver for uri parser.</param>
        /// <param name="currentLevelType">the top level type, will be overwritten with the last entity type in the chain</param>
        /// <param name="firstNonTypeToken">the first non type token in the path</param>
        /// <returns>A path with type segments added to it.</returns>
        public static IEnumerable<ODataPathSegment> FollowTypeSegments(PathSegmentToken firstTypeToken, IEdmModel model, int maxDepth, ODataUriResolver resolver, ref IEdmStructuredType currentLevelType, out PathSegmentToken firstNonTypeToken)
        {
            ExceptionUtils.CheckArgumentNotNull(firstTypeToken, "firstTypeToken");
            ExceptionUtils.CheckArgumentNotNull(model, "model");

            if (!firstTypeToken.IsNamespaceOrContainerQualified())
            {
                throw new ODataException(ODataErrorStrings.SelectExpandPathBinder_FollowNonTypeSegment(firstTypeToken.Identifier));
            }

            int index = 0;
            List<ODataPathSegment> pathToReturn = new List<ODataPathSegment>();
            PathSegmentToken currentToken = firstTypeToken;
            while (currentToken.IsNamespaceOrContainerQualified() && currentToken.NextToken != null)
            {
                IEdmType previousLevelEntityType = currentLevelType;
                currentLevelType = UriEdmHelpers.FindTypeFromModel(model, currentToken.Identifier, resolver) as IEdmStructuredType;
                if (currentLevelType == null)
                {
                    // TODO: fix this error message?
                    throw new ODataException(ODataErrorStrings.ExpandItemBinder_CannotFindType(currentToken.Identifier));
                }

                UriEdmHelpers.CheckRelatedTo(previousLevelEntityType, currentLevelType);
                pathToReturn.Add(new TypeSegment(currentLevelType, /*entitySet*/null));

                index++;
                currentToken = currentToken.NextToken;

                if (index >= maxDepth)
                {
                    throw new ODataException(ODataErrorStrings.ExpandItemBinder_PathTooDeep);
                }
            }

            firstNonTypeToken = currentToken;

            return pathToReturn;
        }
示例#23
0
        /// <summary>
        /// Validates that a property with the specified name exists on a given structured type.
        /// The structured type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningStructuredType">The owning type of the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</param>
        /// <param name="throwOnMissingProperty">Whether throw exception on missing property.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the property with name <paramref name="propertyName"/> 
        /// or null if no metadata is available.</returns>
        internal static IEdmProperty ValidatePropertyDefined(
            string propertyName,
            IEdmStructuredType owningStructuredType,
            bool throwOnMissingProperty = true)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

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

            IEdmProperty property = owningStructuredType.FindProperty(propertyName);

            // verify that the property is declared if the type is not an open type.
            if (throwOnMissingProperty && !owningStructuredType.IsOpen && property == null)
            {
                throw new ODataException(Strings.ValidationUtils_PropertyDoesNotExistOnType(propertyName, owningStructuredType.FullTypeName()));
            }

            return property;
        }
        /// <summary>
        /// Parse the raw select and expand strings into Abstract Syntax Trees
        /// </summary>
        /// <param name="selectClause">the raw select string</param>
        /// <param name="expandClause">the raw expand string</param>
        /// <param name="parentEntityType">the parent entity type for expand option</param>
        /// <param name="configuration">the OData URI parser configuration</param>
        /// <param name="expandTree">the resulting expand AST</param>
        /// <param name="selectTree">the resulting select AST</param>
        public static void Parse(
            string selectClause, 
            string expandClause,
            IEdmStructuredType parentEntityType,
            ODataUriParserConfiguration configuration, 
            out ExpandToken expandTree, 
            out SelectToken selectTree)
        {
            SelectExpandParser selectParser = new SelectExpandParser(selectClause, configuration.Settings.SelectExpandLimit, configuration.EnableCaseInsensitiveUriFunctionIdentifier)
            {
                MaxPathDepth = configuration.Settings.PathLimit
            };
            selectTree = selectParser.ParseSelect();

            SelectExpandParser expandParser = new SelectExpandParser(configuration.Resolver, expandClause, parentEntityType, configuration.Settings.SelectExpandLimit, configuration.EnableCaseInsensitiveUriFunctionIdentifier)
            {
                MaxPathDepth = configuration.Settings.PathLimit,
                MaxFilterDepth = configuration.Settings.FilterLimit,
                MaxOrderByDepth = configuration.Settings.OrderByLimit,
                MaxSearchDepth = configuration.Settings.SearchLimit
            };
            expandTree = expandParser.ParseExpand();
        }
        /// <summary>
        /// Build a segment from a token.
        /// </summary>
        /// <param name="tokenIn">the token to bind</param>
        /// <param name="model">The model.</param>
        /// <param name="edmType">the type of the current scope based on type segments.</param>
        /// <param name="resolver">Resolver for uri parser.</param>
        /// <returns>The segment created from the token.</returns>
        public static ODataPathSegment ConvertNonTypeTokenToSegment(PathSegmentToken tokenIn, IEdmModel model, IEdmStructuredType edmType, ODataUriResolver resolver = null)
        {
            if (resolver == null)
            {
                resolver = ODataUriResolver.Default;
            }

            ODataPathSegment nextSegment;
            if (TryBindAsDeclaredProperty(tokenIn, edmType, resolver, out nextSegment))
            {
                return nextSegment;
            }

            // Operations must be container-qualified, and because the token type indicates it was not a .-seperated identifier, we should not try to look up operations.
            if (tokenIn.IsNamespaceOrContainerQualified())
            {
                if (TryBindAsOperation(tokenIn, model, edmType, out nextSegment))
                {
                    return nextSegment;
                }

                // If an action or function is requested in a selectItem using a qualifiedActionName or a qualifiedFunctionName 
                // and that operation cannot be bound to the entities requested, the service MUST ignore the selectItem.
                if (!edmType.IsOpen)
                {
                    return null;
                }
            }

            if (edmType.IsOpen)
            {
                return new OpenPropertySegment(tokenIn.Identifier);
            }

            throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(edmType.ODataFullName(), tokenIn.Identifier));
        }
示例#26
0
 /// <summary>
 /// Finds a list of types that derive directly from the supplied type.
 /// </summary>
 /// <param name="baseType">The base type that derived types are being searched for.</param>
 /// <returns>A list of types that derive directly from the base type.</returns>
 public abstract IEnumerable <IEdmStructuredType> FindDirectlyDerivedTypes(IEdmStructuredType baseType);
示例#27
0
 /// <summary>
 /// Validates that a property with the specified name exists on a given structured type.
 /// The structured type can be null if no metadata is available.
 /// </summary>
 /// <param name="propertyName">Name of the property.</param>
 /// <param name="owningStructuredType">Hosting type of the property or null if no metadata is
 /// available.</param>
 /// <returns>An <see cref="IEdmProperty"/> instance representing the specified property or
 /// null if no metadata is available.</returns>
 public IEdmProperty ValidatePropertyDefined(string propertyName,
                                             IEdmStructuredType owningStructuredType)
 {
     return(WriterValidationUtils.ValidatePropertyDefined(
                propertyName, owningStructuredType, settings.ThrowOnUndeclaredPropertyForNonOpenType));
 }
示例#28
0
        /// <summary>
        /// Deserializes the given <paramref name="resourceWrapper"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="resourceWrapper">The OData resource to deserialize.</param>
        /// <param name="structuredType">The type of the resource to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized resource.</returns>
        public virtual object ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType,
                                           ODataDeserializerContext readContext)
        {
            if (resourceWrapper == null)
            {
                throw Error.ArgumentNull("resourceWrapper");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (!String.IsNullOrEmpty(resourceWrapper.Resource.TypeName) && structuredType.FullName() != resourceWrapper.Resource.TypeName)
            {
                // received a derived type in a base type deserializer. delegate it to the appropriate derived type deserializer.
                IEdmModel model = readContext.Model;

                if (model == null)
                {
                    throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                }

                IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType;
                if (actualType == null)
                {
                    throw new ODataException("TODO:" /*Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)*/);
                }

                if (actualType.IsAbstract)
                {
                    //string message = Error.Format(SRResources.CannotInstantiateAbstractResourceType, resourceWrapper.Resource.TypeName);
                    throw new ODataException("TODO:");
                }

                IEdmTypeReference actualStructuredType;
                IEdmEntityType    actualEntityType = actualType as IEdmEntityType;
                if (actualEntityType != null)
                {
                    actualStructuredType = new EdmEntityTypeReference(actualEntityType, isNullable: false);
                }
                else
                {
                    actualStructuredType = new EdmComplexTypeReference(actualType as IEdmComplexType, isNullable: false);
                }

                ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(actualStructuredType);
                if (deserializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeDeserialized, actualEntityType.FullName(), typeof(ODataInputFormatter).Name));
                }

                object resource = deserializer.ReadInline(resourceWrapper, actualStructuredType, readContext);

                EdmStructuredObject structuredObject = resource as EdmStructuredObject;
                if (structuredObject != null)
                {
                    structuredObject.ExpectedEdmType = structuredType.StructuredDefinition();
                }

                return(resource);
            }
            else
            {
                object resource = CreateResourceInstance(structuredType, readContext);
                ApplyResourceProperties(resource, resourceWrapper, structuredType, readContext);
                return(resource);
            }
        }
示例#29
0
 public JsonPropertyNameMapper(IEdmModel model, IEdmStructuredType type)
 {
     _model = model;
     _type  = type;
 }
 /// <summary>
 /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
 /// nested properties, navigation properties, and actions to select and expand for the given <paramref name="selectExpandClause"/>.
 /// </summary>
 /// <param name="selectExpandClause">The parsed $select and $expand query options.</param>
 /// <param name="structuredType">The structural type of the resource that would be written.</param>
 /// <param name="model">The <see cref="IEdmModel"/> that contains the given structural type.</param>
 public SelectExpandNode(SelectExpandClause selectExpandClause, IEdmStructuredType structuredType, IEdmModel model)
     : this()
 {
     Initialize(selectExpandClause, structuredType, model, false, null);
 }
示例#31
0
        /// <summary>
        /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
        /// nested properties, navigation properties, and actions to select and expand for the given <paramref name="selectExpandClause"/>.
        /// </summary>
        /// <param name="selectExpandClause">The parsed $select and $expand query options.</param>
        /// <param name="structuredType">The structural type of the resource that would be written.</param>
        /// <param name="model">The <see cref="IEdmModel"/> that contains the given structural type.</param>
        public SelectExpandNode(SelectExpandClause selectExpandClause, IEdmStructuredType structuredType, IEdmModel model)
            : this()
        {
            if (structuredType == null)
            {
                throw Error.ArgumentNull("structuredType");
            }

            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            // So far, it includes all properties of primitive, enum and collection of them
            HashSet <IEdmStructuralProperty> allStructuralProperties = new HashSet <IEdmStructuralProperty>();

            // So far, it includes all properties of complex and collection of complex
            HashSet <IEdmStructuralProperty> allComplexStructuralProperties = new HashSet <IEdmStructuralProperty>();

            GetStructuralProperties(structuredType, allStructuralProperties, allComplexStructuralProperties);

            // So far, it includes all navigation properties
            HashSet <IEdmNavigationProperty> allNavigationProperties;
            HashSet <IEdmAction>             allActions;
            HashSet <IEdmFunction>           allFunctions;

            IEdmEntityType entityType = structuredType as IEdmEntityType;

            if (entityType != null)
            {
                allNavigationProperties = new HashSet <IEdmNavigationProperty>(entityType.NavigationProperties());
                allActions   = new HashSet <IEdmAction>(model.GetAvailableActions(entityType));
                allFunctions = new HashSet <IEdmFunction>(model.GetAvailableFunctions(entityType));
            }
            else
            {
                allNavigationProperties = new HashSet <IEdmNavigationProperty>();
                allActions   = new HashSet <IEdmAction>();
                allFunctions = new HashSet <IEdmFunction>();
            }

            if (selectExpandClause == null)
            {
                SelectedStructuralProperties = allStructuralProperties;
                SelectedComplexProperties    = allComplexStructuralProperties;
                SelectedNavigationProperties = allNavigationProperties;
                SelectedActions            = allActions;
                SelectedFunctions          = allFunctions;
                SelectAllDynamicProperties = true;
            }
            else
            {
                if (selectExpandClause.AllSelected)
                {
                    SelectedStructuralProperties = allStructuralProperties;
                    SelectedComplexProperties    = allComplexStructuralProperties;
                    SelectedNavigationProperties = allNavigationProperties;
                    SelectedActions            = allActions;
                    SelectedFunctions          = allFunctions;
                    SelectAllDynamicProperties = true;
                }
                else
                {
                    BuildSelections(selectExpandClause, allStructuralProperties, allComplexStructuralProperties, allNavigationProperties, allActions, allFunctions);
                    SelectAllDynamicProperties = false;
                }

                BuildExpansions(selectExpandClause, allNavigationProperties);

                // remove expanded navigation properties from the selected navigation properties.
                SelectedNavigationProperties.ExceptWith(ExpandedNavigationProperties.Keys);
            }
        }
        /// <summary>
        /// Reads the content of a properties in an element (complex value, m:properties, ...)
        /// </summary>
        /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param>
        /// <param name="properties">The list of properties to add properties to.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Element    - The element to read properties from.
        /// Post-Condition: XmlNodeType.Element    - The element to read properties from if it is an empty element.
        ///                 XmlNodeType.EndElement - The end element of the element to read properties from.
        /// </remarks>
        private void ReadPropertiesImplementation(IEdmStructuredType structuredType, ReadOnlyEnumerable <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            Debug.Assert(properties != null, "properties != null");
            Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null");
            this.AssertXmlCondition(XmlNodeType.Element);

            // Empty values are valid - they have no properties
            if (!this.XmlReader.IsEmptyElement)
            {
                // Read over the complex value element to its first child node (or end-element)
                this.XmlReader.ReadStartElement();

                do
                {
                    switch (this.XmlReader.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace))
                        {
                            // Found a property
                            IEdmProperty edmProperty    = null;
                            bool         isOpen         = false;
                            bool         ignoreProperty = false;

                            if (structuredType != null)
                            {
                                // Lookup the property in metadata
                                edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty);
                                if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation)
                                {
                                    throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType));
                                }

                                // If the property was not declared, it must be open.
                                isOpen = edmProperty == null;
                            }

                            if (ignoreProperty)
                            {
                                this.XmlReader.Skip();
                            }
                            else
                            {
                                ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null
                                        ? ODataNullValueBehaviorKind.Default
                                        : this.Model.NullValueReadBehaviorKind(edmProperty);
                                ODataProperty property = this.ReadProperty(
                                    false,
                                    edmProperty == null ? null : edmProperty.Name,
                                    edmProperty == null ? null : edmProperty.Type,
                                    nullValueReadBehaviorKind);
                                Debug.Assert(
                                    property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue,
                                    "If we don't ignore null values the property must not be null.");

                                if (property != null)
                                {
                                    if (isOpen)
                                    {
                                        ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value);
                                    }

                                    duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                                    properties.AddToSourceList(property);
                                }
                            }
                        }
                        else
                        {
                            this.XmlReader.Skip();
                        }

                        break;

                    case XmlNodeType.EndElement:
                        // End of the complex value.
                        break;

                    default:
                        // Non-element so for example a text node, just ignore
                        this.XmlReader.Skip();
                        break;
                    }
                }while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            }
        }
        /// <summary>
        /// Writes a single property in ATOM format.
        /// </summary>
        /// <param name="property">The property to write out.</param>
        /// <param name="owningType">The owning type for the <paramref name="property"/> or null if no metadata is available.</param>
        /// <param name="isTopLevel">true if writing a top-level property payload; otherwise false.</param>
        /// <param name="isWritingCollection">true if we are writing a top-level collection instead of an entry.</param>
        /// <param name="beforePropertyAction">Action which is called before the property is written, if it's going to be written.</param>
        /// <param name="duplicatePropertyNamesChecker">The checker instance for duplicate property names.</param>
        /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param>
        /// <returns>true if the property was actually written, false otherwise.</returns>
        private bool WriteProperty(
            ODataProperty property,
            IEdmStructuredType owningType,
            bool isTopLevel,
            bool isWritingCollection,
            Action beforePropertyAction,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
            ProjectedPropertiesAnnotation projectedProperties)
        {
            WriterValidationUtils.ValidatePropertyNotNull(property);

            object value = property.Value;
            string propertyName = property.Name;
            //// TODO: If we implement type conversions the value needs to be converted here
            ////       since the next method call needs to know if the value is a string or not in some cases.

            ODataComplexValue complexValue = value as ODataComplexValue;
            ProjectedPropertiesAnnotation complexValueProjectedProperties = null;
            if (!ShouldWritePropertyInContent(projectedProperties, propertyName))
            {
                return false;
            }

            WriterValidationUtils.ValidatePropertyName(propertyName);
            duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
            IEdmProperty edmProperty = WriterValidationUtils.ValidatePropertyDefined(propertyName, owningType);
            IEdmTypeReference propertyTypeReference = edmProperty == null ? null : edmProperty.Type;

            if (value is ODataStreamReferenceValue)
            {
                throw new ODataException(ODataErrorStrings.ODataWriter_StreamPropertiesMustBePropertiesOfODataEntry(propertyName));
            }

            // Null property value.
            if (value == null)
            {
                this.WriteNullPropertyValue(propertyTypeReference, propertyName, isTopLevel, isWritingCollection, beforePropertyAction);
                return true;
            }

            bool isOpenPropertyType = owningType != null && owningType.IsOpen && propertyTypeReference == null;
            if (isOpenPropertyType)
            {
                ValidationUtils.ValidateOpenPropertyValue(propertyName, value);
            }

            if (complexValue != null)
            {
                return this.WriteComplexValueProperty(
                    complexValue,
                    propertyName,
                    isTopLevel,
                    isWritingCollection,
                    beforePropertyAction,
                    propertyTypeReference,
                    isOpenPropertyType,
                    complexValueProjectedProperties);
            }

            ODataCollectionValue collectionValue = value as ODataCollectionValue;
            if (collectionValue != null)
            {
                this.WriteCollectionValueProperty(
                    collectionValue,
                    propertyName,
                    isTopLevel,
                    isWritingCollection,
                    beforePropertyAction,
                    propertyTypeReference,
                    isOpenPropertyType);

                return true;
            }

            // If the value isn't one of the value types tested for already, it must be a non-null primitive or enum type.
            this.WritePropertyStart(beforePropertyAction, property, isWritingCollection, isTopLevel);
            SerializationTypeNameAnnotation serializationTypeNameAnnotation = property.ODataValue.GetAnnotation<SerializationTypeNameAnnotation>();
            ODataEnumValue enumValue = value as ODataEnumValue;
            if (enumValue != null)
            {
                this.WriteEnumValue(enumValue, /*collectionValidator*/ null, propertyTypeReference, serializationTypeNameAnnotation);
            }
            else
            {
                this.WritePrimitiveValue(value, /*collectionValidator*/ null, propertyTypeReference, serializationTypeNameAnnotation);
            }

            this.WritePropertyEnd();
            return true;
        }
 public TestEdmStructuredObject(IEdmStructuredType edmType, bool isNullable)
     : base(edmType, isNullable)
 {
 }
示例#35
0
        public static IEdmStructuralProperty AssertHasPrimitiveProperty(this IEdmStructuredType edmType, IEdmModel model, string propertyName, EdmPrimitiveTypeKind primitiveTypeKind, bool isNullable)
        {
            Type primitiveType = EdmLibHelpers.GetClrType(new EdmPrimitiveTypeReference(EdmCoreModel.Instance.GetPrimitiveType(primitiveTypeKind), isNullable), model);

            return(edmType.AssertHasProperty <IEdmStructuralProperty>(model, propertyName, primitiveType, isNullable));
        }
示例#36
0
        /// <summary>
        /// Creates an <see cref="ODataReader" /> to read a resource.
        /// </summary>
        /// <param name="navigationSource">The navigation source we are going to read resources for.</param>
        /// <param name="expectedResourceType">The expected resource type for the resource to be read.</param>
        /// <returns>The newly created <see cref="ODataReader"/>.</returns>
        public override ODataReader CreateResourceReader(IEdmNavigationSource navigationSource, IEdmStructuredType expectedResourceType)
        {
            this.AssertSynchronous();
            this.VerifyCanCreateODataReader(navigationSource, expectedResourceType);

            return(this.CreateResourceReaderImplementation(navigationSource, expectedResourceType));
        }
示例#37
0
        /// <summary>
        /// Asynchronously creates an <see cref="ODataReader" /> to read a delta resource set.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to read resources for.</param>
        /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
        /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
        public override Task <ODataReader> CreateDeltaResourceSetReaderAsync(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType)
        {
            this.AssertAsynchronous();
            this.VerifyCanCreateODataReader(entitySet, expectedResourceType);

            // Note that the reading is actually synchronous since we buffer the entire input when getting the stream from the message.
            return(TaskUtils.GetTaskForSynchronousOperation(() => this.CreateResourceSetReaderImplementation(entitySet, expectedResourceType, /*readingParameter*/ false, /*readingDelta*/ true)));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmStructuredObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmStructuredType"/> of this object.</param>
 protected EdmStructuredObject(IEdmStructuredType edmType)
     : this(edmType, isNullable : false)
 {
 }
示例#39
0
        private IEdmVocabularyAnnotatable ComputeTarget()
        {
            if (this.targetContext != null)
            {
                return(this.targetContext);
            }
            else
            {
                Debug.Assert(this.annotationsContext != null, "Annotation must either have a target context or annotations context");
                string              target              = this.annotationsContext.Annotations.Target;
                string[]            targetSegments      = target.Split('/');
                int                 targetSegmentsCount = targetSegments.Count();
                IEdmEntityContainer container;

                if (targetSegmentsCount == 1)
                {
                    string         elementName = targetSegments[0];
                    IEdmSchemaType type        = this.schema.FindType(elementName);
                    if (type != null)
                    {
                        return(type);
                    }

                    IEdmTerm term = this.schema.FindTerm(elementName);
                    if (term != null)
                    {
                        return(term);
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(elementName, this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        return(operation);
                    }

                    container = this.schema.FindEntityContainer(elementName);
                    if (container != null)
                    {
                        return(container);
                    }

                    return(new UnresolvedType(this.Schema.UnresolvedName(targetSegments[0]), this.Location));
                }

                if (targetSegmentsCount == 2)
                {
                    container = this.schema.FindEntityContainer(targetSegments[0]);
                    if (container != null)
                    {
                        IEdmEntityContainerElement containerElement = container.FindEntitySetExtended(targetSegments[1]);
                        if (containerElement != null)
                        {
                            return(containerElement);
                        }

                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(targetSegments[1], container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            return(operationImport);
                        }

                        return(new UnresolvedEntitySet(targetSegments[1], container, this.Location));
                    }

                    IEdmStructuredType type = this.schema.FindType(targetSegments[0]) as IEdmStructuredType;
                    if (type != null)
                    {
                        IEdmProperty property = type.FindProperty(targetSegments[1]);
                        if (property != null)
                        {
                            return(property);
                        }

                        return(new UnresolvedProperty(type, targetSegments[1], this.Location));
                    }

                    IEdmOperation operation = this.FindParameterizedOperation(targetSegments[0], this.Schema.FindOperations, this.CreateAmbiguousOperation);
                    if (operation != null)
                    {
                        IEdmOperationParameter parameter = operation.FindParameter(targetSegments[1]);
                        if (parameter != null)
                        {
                            return(parameter);
                        }

                        return(new UnresolvedParameter(operation, targetSegments[1], this.Location));
                    }

                    return(new UnresolvedProperty(new UnresolvedEntityType(this.Schema.UnresolvedName(targetSegments[0]), this.Location), targetSegments[1], this.Location));
                }

                if (targetSegmentsCount == 3)
                {
                    // The only valid target with three segments is a function parameter.
                    string containerName = targetSegments[0];
                    string operationName = targetSegments[1];
                    string parameterName = targetSegments[2];

                    container = this.Model.FindEntityContainer(containerName);
                    if (container != null)
                    {
                        IEdmOperationImport operationImport = this.FindParameterizedOperationImport(operationName, container.FindOperationImportsExtended, this.CreateAmbiguousOperationImport);
                        if (operationImport != null)
                        {
                            IEdmOperationParameter parameter = operationImport.Operation.FindParameter(parameterName);
                            if (parameter != null)
                            {
                                return(parameter);
                            }

                            return(new UnresolvedParameter(operationImport.Operation, parameterName, this.Location));
                        }
                    }

                    string qualifiedOperationName           = containerName + "/" + operationName;
                    UnresolvedOperation unresolvedOperation = new UnresolvedOperation(qualifiedOperationName, Edm.Strings.Bad_UnresolvedOperation(qualifiedOperationName), this.Location);
                    return(new UnresolvedParameter(unresolvedOperation, parameterName, this.Location));
                }

                return(new BadElement(new EdmError[] { new EdmError(this.Location, EdmErrorCode.ImpossibleAnnotationsTarget, Edm.Strings.CsdlSemantics_ImpossibleAnnotationsTarget(target)) }));
            }
        }
示例#40
0
        /// <summary>
        /// Tries to bind a given token as an Operation.
        /// </summary>
        /// <param name="pathToken">Token to bind.</param>
        /// <param name="model">The model.</param>
        /// <param name="entityType">the current entity type to use as the binding type when looking for operations.</param>
        /// <param name="segment">Bound segment if the token was bound to an operation successfully, or null.</param>
        /// <returns>True if the token was bound successfully, or false otherwise.</returns>
        internal static bool TryBindAsOperation(PathSegmentToken pathToken, IEdmModel model, IEdmStructuredType entityType, out ODataPathSegment segment)
        {
            ExceptionUtils.CheckArgumentNotNull(pathToken, "pathToken");
            ExceptionUtils.CheckArgumentNotNull(entityType, "entityType");

            IEnumerable <IEdmOperation> possibleFunctions = Enumerable.Empty <IEdmOperation>();
            IList <string> parameterNames = new List <string>();

            // Catch all catchable exceptions as FindDeclaredBoundOperations is implemented by anyone.
            // If an exception occurs it will be suppressed and the possible functions will be empty and return false.
            try
            {
                int wildCardPos = pathToken.Identifier.IndexOf("*", StringComparison.Ordinal);
                if (wildCardPos > -1)
                {
                    string namespaceName = pathToken.Identifier.Substring(0, wildCardPos - 1);
                    possibleFunctions = model.FindBoundOperations(entityType).Where(o => o.Namespace == namespaceName);
                }
                else
                {
                    NonSystemToken nonSystemToken = pathToken as NonSystemToken;
                    if (nonSystemToken != null && nonSystemToken.NamedValues != null)
                    {
                        parameterNames = nonSystemToken.NamedValues.Select(s => s.Name).ToList();
                    }

                    if (parameterNames.Count > 0)
                    {
                        // Always force to use fully qualified name when select operation
                        possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier).FilterOperationsByParameterNames(parameterNames, false);
                    }
                    else
                    {
                        possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier);
                    }
                }
            }
            catch (Exception exc)
            {
                if (!ExceptionUtils.IsCatchableExceptionType(exc))
                {
                    throw;
                }
            }

            // Only filter if there is more than one and its needed.
            if (possibleFunctions.Count() > 1)
            {
                possibleFunctions = possibleFunctions.FilterBoundOperationsWithSameTypeHierarchyToTypeClosestToBindingType(entityType);

                // If more than one overload matches, try to select based on optional parameters
                if (parameterNames.Count > 0 && possibleFunctions.Count() > 1)
                {
                    possibleFunctions = possibleFunctions.FilterOverloadsBasedOnParameterCount(parameterNames.Count);
                }
            }

            if (!possibleFunctions.HasAny())
            {
                segment = null;
                return(false);
            }

            possibleFunctions.EnsureOperationsBoundWithBindingParameter();

            segment = new OperationSegment(possibleFunctions, null /*entitySet*/);
            return(true);
        }
示例#41
0
 public NoneKinds2(string namespaceName, string name, IEdmTypeReference type, IEdmStructuredType declaringType)
 {
     this.Namespace     = namespaceName;
     this.Name          = name;
     this.Type          = type;
     this.DeclaringType = declaringType;
     PropertyKind       = EdmPropertyKind.None;
     SchemaElementKind  = EdmSchemaElementKind.None;
     PrimitiveKind      = EdmPrimitiveTypeKind.None;
     TypeKind           = EdmTypeKind.None;
 }
示例#42
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a resource.
 /// </summary>
 /// <param name="navigationSource">The navigation source we are going to read resources for.</param>
 /// <param name="expectedBaseResourceType">The expected structured type for the resource to be read.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataReader CreateResourceReaderImplementation(IEdmNavigationSource navigationSource, IEdmStructuredType expectedBaseResourceType)
 {
     return(new ODataJsonLightReader(this, navigationSource, expectedBaseResourceType, false));
 }
示例#43
0
 /// <summary>
 /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
 /// nested properties, navigation properties, and actions to select and expand for the given <paramref name="writeContext"/>.
 /// </summary>
 /// <param name="structuredType">The structural type of the resource that would be written.</param>
 /// <param name="writeContext">The serializer context to be used while creating the collection.</param>
 /// <remarks>The default constructor is for unit testing only.</remarks>
 public SelectExpandNode(IEdmStructuredType structuredType, ODataSerializerContext writeContext)
     : this(writeContext.SelectExpandClause, structuredType, writeContext.Model)
 {
 }
示例#44
0
 protected virtual void ProcessStructuredType(IEdmStructuredType definition)
 {
     this.ProcessType(definition);
     this.VisitProperties(definition.DeclaredProperties);
 }
示例#45
0
 public IEnumerable <IEdmStructuredType> FindDirectlyDerivedTypes(IEdmStructuredType baseType)
 {
     return(this.primaryModel.FindDirectlyDerivedTypes(baseType));
 }
示例#46
0
        /// <summary>
        /// Generate an expand item (and a select item for the implicit nav prop if necessary) based on an ExpandTermToken
        /// </summary>
        /// <param name="tokenIn">the expandTerm token to visit</param>
        /// <returns>the expand item for this expand term token.</returns>
        private SelectItem GenerateExpandItem(ExpandTermToken tokenIn)
        {
            ExceptionUtils.CheckArgumentNotNull(tokenIn, "tokenIn");

            PathSegmentToken currentToken = tokenIn.PathToNavigationProp;

            IEdmStructuredType      currentLevelEntityType = this.EdmType;
            List <ODataPathSegment> pathSoFar         = new List <ODataPathSegment>();
            PathSegmentToken        firstNonTypeToken = currentToken;

            if (currentToken.IsNamespaceOrContainerQualified())
            {
                pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(currentToken, this.Model, this.Settings.SelectExpandLimit, this.configuration.Resolver, ref currentLevelEntityType, out firstNonTypeToken));
            }

            IEdmProperty edmProperty = this.configuration.Resolver.ResolveProperty(currentLevelEntityType, firstNonTypeToken.Identifier);

            if (edmProperty == null)
            {
                throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(currentLevelEntityType.FullTypeName(), currentToken.Identifier));
            }

            IEdmNavigationProperty currentNavProp     = edmProperty as IEdmNavigationProperty;
            IEdmStructuralProperty currentComplexProp = edmProperty as IEdmStructuralProperty;

            if (currentNavProp == null && currentComplexProp == null)
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_PropertyIsNotANavigationPropertyOrComplexProperty(currentToken.Identifier, currentLevelEntityType.FullTypeName()));
            }

            if (currentComplexProp != null)
            {
                currentNavProp = ParseComplexTypesBeforeNavigation(currentComplexProp, ref firstNonTypeToken, pathSoFar);
            }

            // ensure that we're always dealing with proper V4 syntax
            if (firstNonTypeToken.NextToken != null && firstNonTypeToken.NextToken.NextToken != null)
            {
                throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
            }

            bool isRef = false;

            if (firstNonTypeToken.NextToken != null)
            {
                // lastly... make sure that, since we're on a NavProp, that the next token isn't null.
                if (firstNonTypeToken.NextToken.Identifier == UriQueryConstants.RefSegment)
                {
                    isRef = true;
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ExpandItemBinder_TraversingMultipleNavPropsInTheSamePath);
                }
            }

            // Add the segments in select and expand to parsed segments
            this.parsedSegments.AddRange(pathSoFar);

            IEdmNavigationSource targetNavigationSource = null;

            if (this.NavigationSource != null)
            {
                IEdmPathExpression bindingPath;
                targetNavigationSource = this.NavigationSource.FindNavigationTarget(currentNavProp, BindingPathHelper.MatchBindingPath, this.parsedSegments, out bindingPath);
            }

            NavigationPropertySegment navSegment = new NavigationPropertySegment(currentNavProp, targetNavigationSource);

            pathSoFar.Add(navSegment);
            this.parsedSegments.Add(navSegment);   // Add the navigation property segment to parsed segments for future usage.
            ODataExpandPath pathToNavProp = new ODataExpandPath(pathSoFar);

            ApplyClause applyOption = null;

            if (tokenIn.ApplyOptions != null)
            {
                MetadataBinder binder      = this.BuildNewMetadataBinder(targetNavigationSource);
                ApplyBinder    applyBinder = new ApplyBinder(binder.Bind, binder.BindingState);
                applyOption = applyBinder.BindApply(tokenIn.ApplyOptions);
            }

            ComputeClause computeOption = null;

            if (tokenIn.ComputeOption != null)
            {
                MetadataBinder binder        = this.BuildNewMetadataBinder(targetNavigationSource);
                ComputeBinder  computeBinder = new ComputeBinder(binder.Bind);
                computeOption = computeBinder.BindCompute(tokenIn.ComputeOption);
            }

            var  generatedProperties = GetGeneratedProperties(computeOption, applyOption);
            bool collapsed           = applyOption?.Transformations.Any(t => t.Kind == TransformationNodeKind.Aggregate || t.Kind == TransformationNodeKind.GroupBy) ?? false;

            // call MetadataBinder to build the filter clause
            FilterClause filterOption = null;

            if (tokenIn.FilterOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetNavigationSource, generatedProperties, collapsed);
                FilterBinder   filterBinder = new FilterBinder(binder.Bind, binder.BindingState);
                filterOption = filterBinder.BindFilter(tokenIn.FilterOption);
            }

            // call MetadataBinder again to build the orderby clause
            OrderByClause orderbyOption = null;

            if (tokenIn.OrderByOptions != null)
            {
                MetadataBinder binder        = this.BuildNewMetadataBinder(targetNavigationSource, generatedProperties, collapsed);
                OrderByBinder  orderByBinder = new OrderByBinder(binder.Bind);
                orderbyOption = orderByBinder.BindOrderBy(binder.BindingState, tokenIn.OrderByOptions);
            }

            SearchClause searchOption = null;

            if (tokenIn.SearchOption != null)
            {
                MetadataBinder binder       = this.BuildNewMetadataBinder(targetNavigationSource);
                SearchBinder   searchBinder = new SearchBinder(binder.Bind);
                searchOption = searchBinder.BindSearch(tokenIn.SearchOption);
            }


            if (isRef)
            {
                return(new ExpandedReferenceSelectItem(pathToNavProp, targetNavigationSource, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.CountQueryOption, searchOption, computeOption, applyOption));
            }

            SelectExpandClause subSelectExpand;

            if (tokenIn.ExpandOption != null)
            {
                subSelectExpand = this.GenerateSubExpand(tokenIn);
            }
            else
            {
                subSelectExpand = BuildDefaultSubExpand();
            }

            subSelectExpand = this.DecorateExpandWithSelect(subSelectExpand, currentNavProp, tokenIn.SelectOption, this.CreateBindingState(targetNavigationSource, generatedProperties, collapsed));

            LevelsClause levelsOption = ParseLevels(tokenIn.LevelsOption, currentLevelEntityType, currentNavProp);

            return(new ExpandedNavigationSelectItem(pathToNavProp, targetNavigationSource, subSelectExpand, filterOption, orderbyOption, tokenIn.TopOption, tokenIn.SkipOption, tokenIn.CountQueryOption, searchOption, levelsOption, computeOption, applyOption));
        }
示例#47
0
 /// <summary>
 /// Asynchronously creates an <see cref="ODataReader" /> to read a resource set in a Uri operation parameter.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read resources for.</param>
 /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
 /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
 public virtual Task <ODataReader> CreateUriParameterResourceSetReaderAsync(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.ResourceSet);
 }
示例#48
0
        /// <inheritdoc />
        public bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            Debug.Assert(context.Action != null);

            ActionModel action           = context.Action;
            string      actionMethodName = action.ActionMethod.Name;

            // Need to refactor the following
            // for example:  CreateRef( with the navigation property parameter) should for all navigation properties
            // CreateRefToOrdersFromCustomer, CreateRefToOrders, CreateRef.
            string method = SplitRefActionName(actionMethodName, out string httpMethod, out string property, out string declaring);

            if (method == null)
            {
                return(false);
            }

            // Action parameter should have a (string navigationProperty) parameter
            if (!action.HasParameter <string>("navigationProperty"))
            {
                return(false);
            }

            IEdmNavigationSource navigationSource;
            IEdmEntityType       entityType;

            if (context.EntitySet != null)
            {
                entityType       = context.EntitySet.EntityType();
                navigationSource = context.EntitySet;
            }
            else
            {
                entityType       = context.Singleton.EntityType();
                navigationSource = context.Singleton;
            }

            // For entity set, we should have the key parameter
            // For Singleton, we should not have the key parameter
            bool hasODataKeyParameter = action.HasODataKeyParameter(entityType);

            if ((context.EntitySet != null && !hasODataKeyParameter) ||
                (context.Singleton != null && hasODataKeyParameter))
            {
                return(false);
            }

            // Find the navigation property declaring type
            IEdmStructuredType declaringType = entityType;

            if (declaring != null)
            {
                declaringType = entityType.FindTypeInInheritance(context.Model, declaring);
                if (declaringType == null)
                {
                    return(false);
                }
            }

            // Find the navigation property if have
            IEdmNavigationProperty navigationProperty = null;

            if (property != null)
            {
                navigationProperty = declaringType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == property);
            }

            if (navigationProperty == null)
            {
                return(false);
            }

            IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

            if (context.EntitySet != null)
            {
                segments.Add(new EntitySetSegmentTemplate(context.EntitySet));
                segments.Add(KeySegmentTemplate.CreateKeySegment(entityType, context.EntitySet));
            }
            else
            {
                segments.Add(new SingletonSegmentTemplate(context.Singleton));
            }

            if (entityType != declaringType)
            {
                segments.Add(new CastSegmentTemplate(declaringType, entityType, navigationSource));
            }

            IEdmNavigationSource targetNavigationSource = navigationSource.FindNavigationTarget(navigationProperty, segments, out _);

            if (navigationProperty != null)
            {
                segments.Add(new NavigationSegmentTemplate(navigationProperty, targetNavigationSource));
            }
            else
            {
                //TODO: Add the navigation template segment template,
                // Or add the template for all navigation properties?
                return(false);
            }

            IEdmEntityType navigationPropertyType            = navigationProperty.Type.GetElementTypeOrSelf().AsEntity().EntityDefinition();
            bool           hasNavigationPropertyKeyParameter = action.HasODataKeyParameter(navigationPropertyType, "relatedKey");

            if (hasNavigationPropertyKeyParameter)
            {
                segments.Add(KeySegmentTemplate.CreateKeySegment(navigationPropertyType, targetNavigationSource, "relatedKey"));
            }

            segments.Add(new RefSegmentTemplate(navigationProperty, targetNavigationSource));

            // TODO: support key as segment?
            ODataPathTemplate template = new ODataPathTemplate(segments);

            action.AddSelector(httpMethod, context.Prefix, context.Model, template, context.RouteOptions);

            // processed
            return(true);
        }
示例#49
0
 /// <summary>
 /// Asynchronously creates an <see cref="ODataReader" /> to read a resource in a Uri operation parameter.
 /// </summary>
 /// <param name="navigationSource">The navigation source we are going to read resources for.</param>
 /// <param name="expectedResourceType">The expected structured type for the resource to be read.</param>
 /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
 public virtual Task <ODataReader> CreateUriParameterResourceReaderAsync(IEdmNavigationSource navigationSource, IEdmStructuredType expectedResourceType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.Parameter);
 }
示例#50
0
        /// <summary>
        /// Build a segment from a token.
        /// </summary>
        /// <param name="tokenIn">the token to bind</param>
        /// <param name="model">The model.</param>
        /// <param name="edmType">the type of the current scope based on type segments.</param>
        /// <param name="resolver">Resolver for uri parser.</param>
        /// <param name="state">The binding state.</param>
        /// <returns>The segment created from the token.</returns>
        public static ODataPathSegment ConvertNonTypeTokenToSegment(PathSegmentToken tokenIn, IEdmModel model, IEdmStructuredType edmType, ODataUriResolver resolver, BindingState state = null)
        {
            ExceptionUtils.CheckArgumentNotNull(resolver, "resolver");

            ODataPathSegment nextSegment;

            if (UriParserHelper.IsAnnotation(tokenIn.Identifier))
            {
                if (TryBindAsDeclaredTerm(tokenIn, model, resolver, out nextSegment))
                {
                    return(nextSegment);
                }

                string qualifiedTermName = tokenIn.Identifier.Remove(0, 1);
                int    separator         = qualifiedTermName.LastIndexOf(".", StringComparison.Ordinal);
                string namespaceName     = qualifiedTermName.Substring(0, separator);
                string termName          = qualifiedTermName.Substring(separator == 0 ? 0 : separator + 1);

                // Don't allow selecting odata control information
                if (String.Compare(namespaceName, ODataConstants.ODataPrefix, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    throw new ODataException(ODataErrorStrings.UriSelectParser_TermIsNotValid(tokenIn.Identifier));
                }

                return(new AnnotationSegment(new EdmTerm(namespaceName, termName, EdmCoreModel.Instance.GetUntyped())));
            }

            EndPathToken endPathToken = new EndPathToken(tokenIn.Identifier, null);

            if ((state?.IsCollapsed ?? false) && !(state?.AggregatedPropertyNames?.Contains(endPathToken) ?? false))
            {
                throw new ODataException(ODataErrorStrings.ApplyBinder_GroupByPropertyNotPropertyAccessValue(tokenIn.Identifier));
            }

            if (TryBindAsDeclaredProperty(tokenIn, edmType, resolver, out nextSegment))
            {
                return(nextSegment);
            }

            // Operations must be container-qualified, and because the token type indicates it was not a .-separated identifier, we should not try to look up operations.
            if (tokenIn.IsNamespaceOrContainerQualified())
            {
                if (TryBindAsOperation(tokenIn, model, edmType, out nextSegment))
                {
                    return(nextSegment);
                }

                // If an action or function is requested in a selectItem using a qualifiedActionName or a qualifiedFunctionName
                // and that operation cannot be bound to the entities requested, the service MUST ignore the selectItem.
                if (!edmType.IsOpen)
                {
                    return(null);
                }
            }

            if (edmType.IsOpen || (state?.AggregatedPropertyNames?.Contains(endPathToken) ?? false))
            {
                return(new DynamicPathSegment(tokenIn.Identifier));
            }

            throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclared(edmType.FullTypeName(), tokenIn.Identifier));
        }
示例#51
0
        /// <summary>
        /// Verifies that CreateResourceReader, CreateResourceSetReader, CreateDeltaResourceSetReader or CreateDeltaReader can be called.
        /// </summary>
        /// <param name="navigationSource">The navigation source we are going to read resources for.</param>
        /// <param name="structuredType">The expected structured type for the resource/resource set to be read.</param>
        private void VerifyCanCreateODataReader(IEdmNavigationSource navigationSource, IEdmStructuredType structuredType)
        {
            Debug.Assert(navigationSource == null || structuredType != null, "If an navigation source is specified, the structured type must be specified as well.");

            // We require metadata information for reading requests.
            if (!this.ReadingResponse)
            {
                this.VerifyUserModel();

                // TODO: check for entity only
                if (navigationSource == null && (structuredType != null && structuredType.IsODataEntityTypeKind()))
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightInputContext_NoEntitySetForRequest);
                }
            }

            // We only check that the base type of the entity set is assignable from the specified entity type.
            // If no resource set/resource type is specified in the API, we will read it from the context URI.
            IEdmEntityType entitySetElementType = this.EdmTypeResolver.GetElementType(navigationSource);

            if (navigationSource != null && structuredType != null && !structuredType.IsOrInheritsFrom(entitySetElementType))
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightInputContext_EntityTypeMustBeCompatibleWithEntitySetBaseType(structuredType.FullTypeName(), entitySetElementType.FullName(), navigationSource.FullNavigationSourceName()));
            }
        }
示例#52
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a resource set.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read resources for.</param>
 /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
 /// <param name="readingParameter">true means reading a resource set in uri operation parameter, false reading a resource set in other payloads.</param>
 /// <param name="readingDelta">true if reading a delta resource set.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataReader CreateResourceSetReaderImplementation(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType, bool readingParameter, bool readingDelta)
 {
     return(new ODataJsonLightReader(this, entitySet, expectedResourceType, /*readingResourceSet*/ true, readingParameter, readingDelta));
 }
示例#53
0
        /// <summary>
        /// Asynchronously creates an <see cref="ODataReader" /> to read a resource.
        /// </summary>
        /// <param name="navigationSource">The navigation source we are going to read resources for.</param>
        /// <param name="expectedResourceType">The expected structured type for the resource to be read.</param>
        /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
        public override Task <ODataReader> CreateResourceReaderAsync(IEdmNavigationSource navigationSource, IEdmStructuredType expectedResourceType)
        {
            this.AssertAsynchronous();
            this.VerifyCanCreateODataReader(navigationSource, expectedResourceType);

            // Note that the reading is actually synchronous since we buffer the entire input when getting the stream from the message.
            return(TaskUtils.GetTaskForSynchronousOperation(() => this.CreateResourceReaderImplementation(navigationSource, expectedResourceType)));
        }
示例#54
0
        /// <summary>
        /// Gets a resource metadata builder for the given resource.
        /// </summary>
        /// <param name="resourceState">Resource state to use as reference for information needed by the builder.</param>
        /// <param name="useKeyAsSegment">true if keys should go in separate segments in auto-generated URIs, false if they should go in parentheses.</param>
        /// <returns>A resource metadata builder.</returns>
        public ODataResourceMetadataBuilder GetResourceMetadataBuilderForReader(IODataJsonLightReaderResourceState resourceState, bool useKeyAsSegment)
        {
            Debug.Assert(resourceState != null, "resource != null");

            // Only apply the conventional template builder on response. On a request we would only report what's on the wire.
            if (resourceState.MetadataBuilder == null)
            {
                ODataResourceBase resource = resourceState.Resource;
                if (this.isResponse)
                {
                    ODataTypeAnnotation typeAnnotation = resource.TypeAnnotation;

                    IEdmStructuredType structuredType = null;
                    if (typeAnnotation != null)
                    {
                        if (typeAnnotation.Type != null)
                        {
                            // First try ODataTypeAnnotation.Type (for perf improvement)
                            structuredType = typeAnnotation.Type as IEdmStructuredType;
                        }
                        else if (typeAnnotation.TypeName != null)
                        {
                            // Then try ODataTypeAnnotation.TypeName
                            structuredType = this.model.FindType(typeAnnotation.TypeName) as IEdmStructuredType;
                        }
                    }

                    if (structuredType == null)
                    {
                        // No type name read from the payload. Use resource type from model.
                        structuredType = resourceState.ResourceType;
                    }

                    IEdmNavigationSource      navigationSource            = resourceState.NavigationSource;
                    IEdmEntityType            navigationSourceElementType = this.edmTypeResolver.GetElementType(navigationSource);
                    IODataResourceTypeContext typeContext =
                        ODataResourceTypeContext.Create( /*serializationInfo*/
                            null, navigationSource, navigationSourceElementType, resourceState.ResourceTypeFromMetadata ?? resourceState.ResourceType,
                            /*throwIfMissingTypeInfo*/ true);
                    IODataResourceMetadataContext resourceMetadataContext = ODataResourceMetadataContext.Create(resource, typeContext, /*serializationInfo*/ null, structuredType, this, resourceState.SelectedProperties);

                    ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(this.ServiceBaseUri,
                                                                                             useKeyAsSegment ? ODataUrlKeyDelimiter.Slash : ODataUrlKeyDelimiter.Parentheses);

                    if (structuredType.IsODataEntityTypeKind())
                    {
                        resourceState.MetadataBuilder = new ODataConventionalEntityMetadataBuilder(resourceMetadataContext, this, uriBuilder);
                    }
                    else
                    {
                        resourceState.MetadataBuilder = new ODataConventionalResourceMetadataBuilder(resourceMetadataContext, this, uriBuilder);
                    }
                }
                else
                {
                    resourceState.MetadataBuilder = new NoOpResourceMetadataBuilder(resource);
                }
            }

            return(resourceState.MetadataBuilder);
        }
 public TestEdmStructuredObject(IEdmStructuredType edmType)
     : base(edmType)
 {
 }
示例#56
0
        /// <summary>
        /// Creates an <see cref="ODataReader" /> to read a resource set in a Uri operation parameter.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to read resources for.</param>
        /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
        /// <returns>The newly created <see cref="ODataReader"/>.</returns>
        public override ODataReader CreateUriParameterResourceSetReader(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType)
        {
            this.AssertSynchronous();
            this.VerifyCanCreateODataReader(entitySet, expectedResourceType);

            return(this.CreateResourceSetReaderImplementation(entitySet, expectedResourceType, /*readingParameter*/ true, /*readingDelta*/ false));
        }
        /// <summary>
        /// Write the given collection of properties.
        /// </summary>
        /// <param name="owningType">The <see cref="IEdmStructuredType"/> of the entry (or null if not metadata is available).</param>
        /// <param name="cachedProperties">Collection of cached properties for the entry.</param>
        /// <param name="isWritingCollection">true if we are writing a top level collection instead of an entry.</param>
        /// <param name="beforePropertiesAction">Action which is called before the properties are written, if there are any property.</param>
        /// <param name="afterPropertiesAction">Action which is called after the properties are written, if there are any property.</param>
        /// <param name="duplicatePropertyNamesChecker">The checker instance for duplicate property names.</param>
        /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param>
        /// <returns>true if anything was written, false otherwise.</returns>
        internal bool WriteProperties(
            IEdmStructuredType owningType,
            IEnumerable<ODataProperty> cachedProperties,
            bool isWritingCollection,
            Action beforePropertiesAction,
            Action afterPropertiesAction,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
            ProjectedPropertiesAnnotation projectedProperties)
        {
            if (cachedProperties == null)
            {
                return false;
            }

            bool propertyWritten = false;
            foreach (ODataProperty property in cachedProperties)
            {
                propertyWritten |= this.WriteProperty(
                    property,
                    owningType,
                    /*isTopLevel*/false,
                    isWritingCollection,
                    propertyWritten ? null : beforePropertiesAction,
                    duplicatePropertyNamesChecker,
                    projectedProperties);
            }

            if (afterPropertiesAction != null && propertyWritten)
            {
                afterPropertiesAction();
            }

            return propertyWritten;
        }
示例#58
0
        /// <summary>
        /// Asynchronously creates an <see cref="ODataReader" /> to read a resource set in a Uri operation parameter.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to read resources for.</param>
        /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
        /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
        public override Task <ODataReader> CreateUriParameterResourceSetReaderAsync(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType)
        {
            this.AssertAsynchronous();
            this.VerifyCanCreateODataReader(entitySet, expectedResourceType);

            return(TaskUtils.GetTaskForSynchronousOperation(() => this.CreateResourceSetReaderImplementation(entitySet, expectedResourceType, /*readingParameter*/ true, /*readingDelta*/ false)));
        }
示例#59
0
        public static PropertyInfo GetDynamicPropertyDictionary(IEdmStructuredType edmType, IEdmModel edmModel)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            if (edmModel == null)
            {
                throw Error.ArgumentNull("edmModel");
            }

            DynamicPropertyDictionaryAnnotation annotation =
                edmModel.GetAnnotationValue<DynamicPropertyDictionaryAnnotation>(edmType);
            if (annotation != null)
            {
                return annotation.PropertyInfo;
            }

            return null;
        }
示例#60
0
 /// <summary>
 /// Asynchronously creates an <see cref="ODataReader" /> to read a resource in a Uri operation parameter.
 /// </summary>
 /// <param name="navigationSource">The navigation source we are going to read resources for.</param>
 /// <param name="expectedResourceType">The expected structured type for the resource to be read.</param>
 /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
 public override Task <ODataReader> CreateUriParameterResourceReaderAsync(IEdmNavigationSource navigationSource, IEdmStructuredType expectedResourceType)
 {
     return(this.CreateResourceReaderAsync(navigationSource, expectedResourceType));
 }