Пример #1
0
        private ResourcePropertyInfo GetResourcePropertyInfo(ResourceProperty resourceProperty)
        {
            ResourcePropertyInfo propertyInfoDecaredOnThisType = null;

            for (ResourceType type = this; (propertyInfoDecaredOnThisType == null) && (type != null); type = type.BaseType)
            {
                propertyInfoDecaredOnThisType = type.GetPropertyInfoDecaredOnThisType(resourceProperty);
            }
            return(propertyInfoDecaredOnThisType);
        }
Пример #2
0
        protected ResourcePropertyInfo GetNavigationPropertyInfo(IExpandedResult expanded, object customObject, ResourceType currentResourceType, ResourceProperty property)
        {
            ExpandedProjectionNode node;
            object obj2   = null;
            bool   expand = this.ShouldExpandSegment(property, currentResourceType, out node);

            if (expand)
            {
                obj2 = this.GetExpandedProperty(expanded, customObject, property, node);
            }
            return(ResourcePropertyInfo.CreateResourcePropertyInfo(property, obj2, node, expand));
        }
Пример #3
0
        private ResourcePropertyInfo GetPropertyInfoDecaredOnThisType(ResourceProperty resourceProperty)
        {
            ResourcePropertyInfo info;

            if (this.propertyInfosDeclaredOnThisType == null)
            {
                this.propertyInfosDeclaredOnThisType = new Dictionary <ResourceProperty, ResourcePropertyInfo>(ReferenceEqualityComparer <ResourceProperty> .Instance);
            }
            if (!this.propertyInfosDeclaredOnThisType.TryGetValue(resourceProperty, out info))
            {
                PropertyInfo property = this.InstanceType.GetProperty(resourceProperty.Name, BindingFlags.Public | BindingFlags.Instance);
                if (property == null)
                {
                    throw new DataServiceException(500, System.Data.Services.Strings.BadProvider_UnableToGetPropertyInfo(this.FullName, resourceProperty.Name));
                }
                info = new ResourcePropertyInfo(property);
                this.propertyInfosDeclaredOnThisType.Add(resourceProperty, info);
            }
            return(info);
        }
Пример #4
0
        private void WriteNavigationProperties(IExpandedResult expanded, EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, IEnumerable <ProjectionNode> projectionNodesForCurrentResourceType)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(
                projectionNodesForCurrentResourceType == null ||
                projectionNodesForCurrentResourceType.All(projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(entityToSerialize.ResourceType)),
                "The projection nodes must be filtered to the current resource type only.");

            IEnumerable <ResourceProperty> navProperties =
                projectionNodesForCurrentResourceType == null
                ? this.Provider.GetResourceSerializableProperties(this.CurrentContainer, entityToSerialize.ResourceType).Where(p => p.TypeKind == ResourceTypeKind.EntityType)
                : projectionNodesForCurrentResourceType.Where(p => p.Property != null && p.Property.TypeKind == ResourceTypeKind.EntityType).Select(p1 => p1.Property);

            foreach (ResourceProperty property in navProperties)
            {
                ResourcePropertyInfo navProperty = this.GetNavigationPropertyInfo(expanded, entityToSerialize.Entity, entityToSerialize.ResourceType, property);
                ODataNavigationLink  navLink     = this.GetNavigationLink(entityToSerialize, navProperty.Property);

                // WCF Data Services show performance degradation with JsonLight when entities have > 25 Navgations on writing entries
                // DEVNOTE: for performance reasons, if the link has no content due to the metadata level, and is not expanded
                // then don't tell ODataLib about it at all.
                if (navLink.Url == null && navLink.AssociationLinkUrl == null && !navProperty.Expand)
                {
                    continue;
                }

                var linkArgs = new DataServiceODataWriterNavigationLinkArgs(navLink, this.Service.OperationContext);
                this.dataServicesODataWriter.WriteStart(linkArgs);

                if (navProperty.Expand)
                {
                    object          navPropertyValue          = navProperty.Value;
                    IExpandedResult navPropertyExpandedResult = navPropertyValue as IExpandedResult;
                    object          expandedPropertyValue     =
                        navPropertyExpandedResult != null?
                        GetExpandedElement(navPropertyExpandedResult) :
                            navPropertyValue;

                    bool needPop = this.PushSegmentForProperty(navProperty.Property, entityToSerialize.ResourceType, navProperty.ExpandedNode);

                    // if this.CurrentContainer is null, the target set of the navigation property is hidden.
                    if (this.CurrentContainer != null)
                    {
                        if (navProperty.Property.Kind == ResourcePropertyKind.ResourceSetReference)
                        {
                            IEnumerable enumerable;
                            bool        collection = WebUtil.IsElementIEnumerable(expandedPropertyValue, out enumerable);
                            Debug.Assert(collection, "metadata loading must have ensured that navigation set properties must implement IEnumerable");

                            QueryResultInfo queryResults = new QueryResultInfo(enumerable);
                            try
                            {
                                queryResults.MoveNext();
                                Func <Uri> getNavPropertyRelativeUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navLink.Name);
                                Func <Uri> getNavPropertyAbsoluteUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLink, navLink.Name);
                                this.WriteFeedElements(navPropertyExpandedResult, queryResults, navProperty.Property.ResourceType, navLink.Name, getNavPropertyRelativeUri, getNavPropertyAbsoluteUri, false);
                            }
                            finally
                            {
                                // After the navigation property is completely serialized, dispose the property value.
                                WebUtil.Dispose(queryResults);
                            }
                        }
                        else if (WebUtil.IsNullValue(expandedPropertyValue))
                        {
                            // Write a null reference navigation property
                            var entryArgs = new DataServiceODataWriterEntryArgs(null, null, this.Service.OperationContext);
                            this.dataServicesODataWriter.WriteStart(entryArgs);
                            this.dataServicesODataWriter.WriteEnd(entryArgs);
                        }
                        else
                        {
                            this.WriteEntry(navPropertyExpandedResult, expandedPropertyValue, resourceInstanceInFeed, navProperty.Property.ResourceType);
                        }
                    }

                    this.PopSegmentName(needPop);
                }

                this.dataServicesODataWriter.WriteEnd(linkArgs); // end of navigation property
            }
        }
Пример #5
0
 private ResourcePropertyInfo GetPropertyInfoDecaredOnThisType(ResourceProperty resourceProperty)
 {
     ResourcePropertyInfo info;
     if (this.propertyInfosDeclaredOnThisType == null)
     {
         this.propertyInfosDeclaredOnThisType = new Dictionary<ResourceProperty, ResourcePropertyInfo>(ReferenceEqualityComparer<ResourceProperty>.Instance);
     }
     if (!this.propertyInfosDeclaredOnThisType.TryGetValue(resourceProperty, out info))
     {
         PropertyInfo property = this.InstanceType.GetProperty(resourceProperty.Name, BindingFlags.Public | BindingFlags.Instance);
         if (property == null)
         {
             throw new DataServiceException(500, System.Data.Services.Strings.BadProvider_UnableToGetPropertyInfo(this.FullName, resourceProperty.Name));
         }
         info = new ResourcePropertyInfo(property);
         this.propertyInfosDeclaredOnThisType.Add(resourceProperty, info);
     }
     return info;
 }
Пример #6
0
 /// <summary>
 /// Adds A resourcepropertyInfo instance to the internal propertyInfosDeclaredOnThisType dictionary.
 /// </summary>
 /// <param name="resourceProperty">The resource property to add to the dictionary</param>
 /// <param name="propertyInfo">The propertyInfo handle to the instance property represented by the <paramref name="resourceProperty"/> </param>
 /// <returns>A resourcepropertyInfo instance that allows access to the instance property</returns>
 private ResourcePropertyInfo AddPropertyToResourceTypePropertyInfoCache(ResourceProperty resourceProperty, PropertyInfo propertyInfo)
 {
     ResourcePropertyInfo resourcePropertyInfo = new ResourcePropertyInfo(propertyInfo);
     var propertiesDictionary = new Dictionary<ResourceProperty, ResourcePropertyInfo>(this.propertyInfosDeclaredOnThisType, ReferenceEqualityComparer<ResourceProperty>.Instance);
     propertiesDictionary.Add(resourceProperty, resourcePropertyInfo);
     Interlocked.Exchange(ref this.propertyInfosDeclaredOnThisType, propertiesDictionary);
     return resourcePropertyInfo;
 }