示例#1
0
        /// <summary>
        /// Composes the specified <paramref name="queryExpression"/> for the
        /// given <paramref name="container"/> with authorization
        /// callbacks.
        /// </summary>
        /// <param name="service">Data service on which to invoke method.</param>
        /// <param name="container">resource set to compose with.</param>
        /// <param name="queryExpression">Query to compose.</param>
        /// <returns>The resulting composed query.</returns>
        internal static Expression ComposeResourceContainer(IDataService service, ResourceSetWrapper container, Expression queryExpression)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(container != null, "container != null");
            Debug.Assert(queryExpression != null, "queryExpression != null");

            MethodInfo[] methods = container.QueryInterceptors;
            if (methods != null)
            {
                for (int i = 0; i < methods.Length; i++)
                {
                    Expression predicate;
                    try
                    {
                        predicate = (Expression)methods[i].Invoke(service.Instance, WebUtil.EmptyObjectArray);
                    }
                    catch (TargetInvocationException tie)
                    {
                        ErrorHandler.HandleTargetInvocationException(tie);
                        throw;
                    }

                    if (predicate == null)
                    {
                        throw new InvalidOperationException(Strings.DataService_AuthorizationReturnedNullQuery(methods[i].Name, methods[i].DeclaringType.FullName));
                    }

                    // predicate is LambdaExpression -- otherwise signature check missed something and following cast would throw
                    queryExpression = queryExpression.QueryableWhere((LambdaExpression)predicate);
                }
            }

            return(queryExpression);
        }
示例#2
0
        protected void UpdateAndCheckRequestResponseDSV(ResourceType resourceType, bool topLevel)
        {
            bool flag = this.ContentFormat == System.Data.Services.ContentFormat.Atom;

            if (flag)
            {
                Version requiredVersion = resourceType.EpmMinimumDataServiceProtocolVersion.ToVersion();
                this.RequestDescription.VerifyRequestVersion(requiredVersion, this.service);
            }
            if (topLevel && this.ResponseWillBeSent)
            {
                Version            version2;
                bool               considerEpmInVersion = WebUtil.IsAtomResponseFormat(this.Service.OperationContext.Host.RequestAccept, this.RequestDescription.TargetKind, this.Service.Configuration.DataServiceBehavior.MaxProtocolVersion, this.Service.OperationContext.Host.RequestMaxVersion);
                ResourceSetWrapper targetContainer      = this.RequestDescription.LastSegmentInfo.TargetContainer;
                if (flag)
                {
                    version2 = resourceType.GetMinimumResponseVersion(this.Service, targetContainer, considerEpmInVersion);
                }
                else
                {
                    version2 = resourceType.GetMinimumResponseVersion(this.Service, targetContainer, considerEpmInVersion);
                    if (considerEpmInVersion && (version2 <= System.Data.Services.RequestDescription.Version2Dot0))
                    {
                        this.RequestDescription.VerifyAndRaiseActualResponseVersion(version2, this.service);
                        version2 = resourceType.GetMinimumResponseVersion(this.Service, targetContainer, false);
                    }
                }
                this.RequestDescription.VerifyAndRaiseResponseVersion(version2, this.Service);
            }
        }
 internal static Expression ComposeResourceContainer(IDataService service, ResourceSetWrapper container, Expression queryExpression)
 {
     MethodInfo[] queryInterceptors = container.QueryInterceptors;
     if (queryInterceptors != null)
     {
         for (int i = 0; i < queryInterceptors.Length; i++)
         {
             Expression expression;
             try
             {
                 expression = (Expression)queryInterceptors[i].Invoke(service.Instance, WebUtil.EmptyObjectArray);
             }
             catch (TargetInvocationException exception)
             {
                 ErrorHandler.HandleTargetInvocationException(exception);
                 throw;
             }
             if (expression == null)
             {
                 throw new InvalidOperationException(System.Data.Services.Strings.DataService_AuthorizationReturnedNullQuery(queryInterceptors[i].Name, queryInterceptors[i].DeclaringType.FullName));
             }
             queryExpression = queryExpression.QueryableWhere((LambdaExpression)expression);
         }
     }
     return(queryExpression);
 }
示例#4
0
        /// <summary>Fires the notification for a single action.</summary>
        /// <param name="service">Service on which methods should be invoked.</param>
        /// <param name="target">Object to be tracked.</param>
        /// <param name="container">Container in which object is changed.</param>
        /// <param name="action">Action affecting target.</param>
        internal static void FireNotification(IDataService service, object target, ResourceSetWrapper container, UpdateOperations action)
        {
            Debug.Assert(service != null, "service != null");
            AssertActionValues(target, container);

            MethodInfo[] methods = container.ChangeInterceptors;
            if (methods != null)
            {
                object[] parameters = new object[2];
                parameters[0] = target;
                parameters[1] = action;
                for (int i = 0; i < methods.Length; i++)
                {
                    try
                    {
                        methods[i].Invoke(service.Instance, parameters);
                    }
                    catch (TargetInvocationException exception)
                    {
                        ErrorHandler.HandleTargetInvocationException(exception);
                        throw;
                    }
                }
            }
        }
示例#5
0
 internal void TrackAction(object target, ResourceSetWrapper container, UpdateOperations action)
 {
     if (container.ChangeInterceptors != null)
     {
         Dictionary <object, UpdateOperations> dictionary;
         UpdateOperations operations;
         if (!this.items.TryGetValue(container, out dictionary))
         {
             if (this.service.Provider.IsV1Provider)
             {
                 dictionary = new Dictionary <object, UpdateOperations>(EqualityComparer <object> .Default);
             }
             else
             {
                 dictionary = new Dictionary <object, UpdateOperations>(ReferenceEqualityComparer <object> .Instance);
             }
             this.items.Add(container, dictionary);
         }
         if (dictionary.TryGetValue(target, out operations))
         {
             if ((action | operations) != operations)
             {
                 dictionary[target] = action | operations;
             }
         }
         else
         {
             dictionary.Add(target, action);
         }
     }
 }
示例#6
0
        internal RequestDescription UpdateVersions(string acceptTypesText, ResourceSetWrapper resourceSet, IDataService service)
        {
            DataServiceHostWrapper host = service.OperationContext.Host;

            if ((host.HttpVerb == HttpVerbs.GET) || ((host.HttpVerb == HttpVerbs.POST) && (this.TargetSource == RequestTargetSource.ServiceOperation)))
            {
                if (this.TargetKind == RequestTargetKind.Resource)
                {
                    if (!this.LinkUri)
                    {
                        this.InitializeVersion(service.OperationContext);
                        bool    considerEpmInVersion = WebUtil.IsAtomResponseFormat(acceptTypesText, this.TargetKind, service.Configuration.DataServiceBehavior.MaxProtocolVersion, this.requestMaxVersion);
                        Version version = resourceSet.MinimumResponsePayloadVersion(service, considerEpmInVersion);
                        this.VerifyAndRaiseResponseVersion(version, service);
                    }
                }
                else if (((this.TargetResourceType != null) && (this.CountOption != RequestQueryCountOption.ValueOnly)) && (this.TargetKind != RequestTargetKind.MediaResource))
                {
                    this.VerifyAndRaiseResponseVersion(this.TargetResourceType.MetadataVersion, service);
                }
                else if (this.TargetKind == RequestTargetKind.OpenProperty)
                {
                    this.InitializeVersion(service.OperationContext);
                    Version effectiveMaxResponseVersion = WebUtil.GetEffectiveMaxResponseVersion(service.Configuration.DataServiceBehavior.MaxProtocolVersion, this.requestMaxVersion);
                    this.VerifyAndRaiseResponseVersion(effectiveMaxResponseVersion, service);
                }
            }
            else if (host.HttpVerb == HttpVerbs.PATCH)
            {
                this.VerifyProtocolVersion(Version3Dot0, service);
                this.VerifyRequestVersion(Version3Dot0, service);
            }
            return(this);
        }
示例#7
0
        /// <summary>
        /// Create a new request description from the given request description and new entity as the result.
        /// </summary>
        /// <param name="description">Existing request description.</param>
        /// <param name="entity">entity that needs to be the result of the new request.</param>
        /// <param name="container">container to which the entity belongs to.</param>
        /// <returns>a new instance of request description containing information about the given entity.</returns>
        internal static RequestDescription CreateSingleResultRequestDescription(
            RequestDescription description, object entity, ResourceSetWrapper container)
        {
            // Create a new request description for the results that will be returned.
            SegmentInfo segmentInfo = new SegmentInfo();

            segmentInfo.RequestEnumerable  = new object[] { entity };
            segmentInfo.TargetKind         = description.TargetKind;
            segmentInfo.TargetSource       = description.TargetSource;
            segmentInfo.SingleResult       = true;
            segmentInfo.ProjectedProperty  = description.Property;
            segmentInfo.TargetResourceType = container != null ? container.ResourceType : null;
            segmentInfo.TargetContainer    = container;
            segmentInfo.Identifier         = description.LastSegmentInfo.Identifier;
#if DEBUG
            segmentInfo.AssertValid();
#endif
            SegmentInfo[] segmentInfos = description.SegmentInfos;
            segmentInfos[segmentInfos.Length - 1] = segmentInfo;

            RequestDescription resultDescription = new RequestDescription(
                segmentInfos,
                container != null ? container.Name : null,
                description.UsesContainerName,
                description.MimeType,
                description.ResultUri);

            resultDescription.requireMinimumVersion = description.RequireMinimumVersion;
            resultDescription.responseVersion       = description.ResponseVersion;
            resultDescription.maxFeatureVersion     = description.MaxFeatureVersion;
            return(resultDescription);
        }
示例#8
0
        private void ApplyNavigationProperty(ODataNavigationLink navigationLink, ResourceSetWrapper entityResourceSet, ResourceType entityResourceType, ResourceProperty navigationProperty, object entityResource)
        {
            ResourceSetWrapper targetResourceSet = null;

            targetResourceSet = this.GetNavigationPropertyTargetResourceSet(entityResourceSet, entityResourceType, navigationProperty);
            foreach (ODataItem item in navigationLink.GetAnnotation <ODataNavigationLinkAnnotation>())
            {
                ODataEntityReferenceLink entityReferenceLink = item as ODataEntityReferenceLink;
                if (entityReferenceLink != null)
                {
                    this.ApplyEntityReferenceLinkInNavigationProperty(navigationProperty, entityResource, entityReferenceLink);
                }
                else
                {
                    ODataFeed feed = item as ODataFeed;
                    if (feed != null)
                    {
                        this.ApplyFeedInNavigationProperty(navigationProperty, targetResourceSet, entityResource, feed);
                    }
                    else
                    {
                        ODataEntry entry = (ODataEntry)item;
                        this.ApplyEntryInNavigationProperty(navigationProperty, targetResourceSet, entityResource, entry);
                    }
                }
            }
        }
        public void Init()
        {
            this.entityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Fake.NS", "Type", false)
            {
                CanReflectOnInstanceType = false
            };
            this.entityType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int)))
            {
                CanReflectOnInstanceTypeProperty = false
            });
            this.entityType.SetReadOnly();

            var resourceSet = new ResourceSet("Set", this.entityType);

            resourceSet.SetReadOnly();
            this.resourceSetWrapper = ResourceSetWrapper.CreateForTests(resourceSet);

            this.action = new ServiceAction("Fake", ResourceType.GetPrimitiveResourceType(typeof(int)), OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("p1", this.entityType) }, null);
            this.action.SetReadOnly();

            this.provider = new TestDataServiceProvider();

            this.actionProvider = DataServiceActionProviderWrapper.Create(this.provider, ODataProtocolVersion.V4, () => this.operationContext);
            var host = new DataServiceHostSimulator();

            this.operationContext = new DataServiceOperationContext(host);
            this.operationContext.InitializeAndCacheHeaders(new DataServiceSimulator());
        }
 internal static void CheckResourceRights(ResourceSetWrapper container, EntitySetRights requiredRights)
 {
     if ((requiredRights & container.Rights) == EntitySetRights.None)
     {
         throw DataServiceException.CreateForbidden();
     }
 }
示例#11
0
        /// <summary>
        /// Raise the feature version if the target container contains any type with FF mapped properties that is KeepInContent=false.
        /// </summary>
        /// <param name="service">service instance</param>
        /// <returns>This RequestDescription instance</returns>
        internal RequestDescription UpdateAndCheckEpmFeatureVersion(IDataService service)
        {
            Debug.Assert(this.LastSegmentInfo != null, "this.LastSegmentInfo != null");

            if (this.LinkUri)
            {
                // For $link operations we raise the feature version if either side of $link points to a set that
                // is not V1 compatible.
                ResourceSetWrapper leftSet;
                ResourceSetWrapper rightSet;
                this.GetLinkedResourceSets(out leftSet, out rightSet);

                Debug.Assert(leftSet != null, "leftSet != null");
                Debug.Assert(rightSet != null, "rightSet != null");
                this.UpdateAndCheckEpmFeatureVersion(leftSet, service);
                this.UpdateAndCheckEpmFeatureVersion(rightSet, service);
            }
            else
            {
                // The last segment might not be a resource.  Trace backward to find the target entity resource.
                int resourceIndex = this.GetIndexOfTargetEntityResource();

                // Not every request has a target resource.  Service Operations for example can return just primitives.
                if (resourceIndex != -1)
                {
                    ResourceSetWrapper resourceSet = this.SegmentInfos[resourceIndex].TargetContainer;
                    Debug.Assert(resourceSet != null, "resourceSet != null");
                    this.UpdateAndCheckEpmFeatureVersion(resourceSet, service);
                }
            }

            return(this);
        }
示例#12
0
        /// <summary>Gets a string with methods allowed on the target for the <paramref name="description"/>.</summary>
        /// <param name="configuration">configuration object which has the data</param>
        /// <param name="description">Description with target.</param>
        /// <returns>A string with methods allowed on the description; possibly null.</returns>
        internal static string GetAllowedMethods(DataServiceConfiguration configuration, RequestDescription description)
        {
            Debug.Assert(description != null, "description != null");
            Debug.Assert(
                description.TargetKind != RequestTargetKind.Nothing,
                "description.TargetKind != RequestTargetKind.Void - otherwise it hasn't been determined yet");
            Debug.Assert(
                description.TargetKind != RequestTargetKind.VoidOperation,
                "description.TargetKind != RequestTargetKind.VoidOperation - this method is only for containers");
            if (description.TargetKind == RequestTargetKind.Metadata ||
                description.TargetKind == RequestTargetKind.ServiceDirectory)
            {
                return(XmlConstants.HttpMethodGet);
            }

            if (description.TargetKind == RequestTargetKind.Batch)
            {
                return(XmlConstants.HttpMethodPost);
            }

            int index = description.GetIndexOfTargetEntityResource();

            Debug.Assert(index >= 0 && index < description.SegmentInfos.Count, "index >=0 && index <description.SegmentInfos.Count");
            ResourceSetWrapper container = description.SegmentInfos[index].TargetResourceSet;

            return(GetAllowedMethods(configuration, container, description));
        }
示例#13
0
        /// <summary>Checks whether this request has the specified reading rights.</summary>
        /// <param name="container">Container to check.</param>
        /// <param name="singleResult">Whether a single or multiple resources are requested.</param>
        /// <exception cref="DataServiceException">Thrown if <paramref name="singleResult"/> aren't available.</exception>
        internal static void CheckResourceRightsForRead(ResourceSetWrapper container, bool singleResult)
        {
            Debug.Assert(container != null, "container != null");
            EntitySetRights requiredRights = singleResult ? EntitySetRights.ReadSingle : EntitySetRights.ReadMultiple;

            CheckResourceRights(container, requiredRights);
        }
示例#14
0
        /// <summary>
        /// Applies a navigation link as a navigation property.
        /// </summary>
        /// <param name="navigationLink">The navigation link read from the payload to apply.</param>
        /// <param name="entityResourceSet">The resource set into which the entity belongs to.</param>
        /// <param name="entityResourceType">The type of the entity to apply the properties to.</param>
        /// <param name="navigationProperty">The navigation property which coresponds with the navigation link.</param>
        /// <param name="entityResource">The entity resource to apply the properties to.</param>
        private void ApplyNavigationProperty(
            ODataNavigationLink navigationLink,
            ResourceSetWrapper entityResourceSet,
            ResourceType entityResourceType,
            ResourceProperty navigationProperty,
            object entityResource)
        {
            Debug.Assert(navigationLink != null, "navigationLink != null");
            Debug.Assert(entityResourceSet != null, "entityResourceSet != null");
            Debug.Assert(entityResourceType != null, "entityResourceType != null");
            Debug.Assert(entityResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "Only entity types can be specified for entities.");
            Debug.Assert(navigationProperty != null && navigationProperty.TypeKind == ResourceTypeKind.EntityType, "navigationProperty != null && navigationProperty.TypeKind == ResourceTypeKind.EntityType");
            Debug.Assert(navigationLink.Name == navigationProperty.Name, "The navigationProperty must have the same name as the navigationLink to apply.");
            Debug.Assert(entityResource != null, "entityResource != null");

            ResourceSetWrapper targetResourceSet = null;

            // Get the target resource set for the navigation property, this also causes validation of the resource set and thus migth fail.
            // WCF DS Used to do this in ATOM only if the link was expanded, which was a security issue we decided to fix, so now we do it always.
            targetResourceSet = this.GetNavigationPropertyTargetResourceSet(entityResourceSet, entityResourceType, navigationProperty);

            ODataNavigationLinkAnnotation navigationLinkAnnotation = navigationLink.GetAnnotation <ODataNavigationLinkAnnotation>();

            Debug.Assert(navigationLinkAnnotation != null, "navigationLinkAnnotation != null");
            Debug.Assert(navigationLinkAnnotation.Count > 0, "Each navigation link must have at least one child in request.");
            Debug.Assert(navigationLink.IsCollection.HasValue, "We should know the cardinality of the navigation link by now.");

            // We have to allow IsCollection=false for ResourceSetReference properties as well.
            Debug.Assert(
                navigationLink.IsCollection == true || (navigationLinkAnnotation.Count == 1),
                "If the navigation link is a singleton, then there must be exactly one child in it and the property must be a singleton as well.");
            Debug.Assert(
                navigationLink.IsCollection == false || (navigationProperty.Kind == ResourcePropertyKind.ResourceSetReference),
                "If the navigation link is a collection, then the property must be a collection as well.");

            // Just loop through the navigation link content
            // Note that if the navigation link is a singleton it must have just one item in it, so it's OK to loop anyway.
            foreach (ODataItem childItem in navigationLinkAnnotation)
            {
                ODataEntityReferenceLink entityReferenceLink = childItem as ODataEntityReferenceLink;
                if (entityReferenceLink != null)
                {
                    this.ApplyEntityReferenceLinkInNavigationProperty(navigationProperty, entityResource, entityReferenceLink);
                    continue;
                }

                ODataFeed feed = childItem as ODataFeed;
                if (feed != null)
                {
                    this.ApplyFeedInNavigationProperty(navigationProperty, targetResourceSet, entityResource, feed);
                    continue;
                }

                // It must be entry by now.
                ODataEntry entry = (ODataEntry)childItem;
                this.ApplyEntryInNavigationProperty(navigationProperty, targetResourceSet, entityResource, entry);
            }
        }
示例#15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Microsoft.OData.Service.ExpandAndSelectParseResult"/> class.
        /// </summary>
        /// <param name="requestDescription">The request description.</param>
        /// <param name="dataService">The data service.</param>
        internal ExpandAndSelectParseResult(RequestDescription requestDescription, IDataService dataService)
        {
            Debug.Assert(dataService != null, "dataService != null");
            Debug.Assert(dataService.OperationContext != null, "dataService.OperationContext != null");
            Debug.Assert(dataService.OperationContext.RequestMessage != null, "dataService.OperationContext.RequestMessage != null");

            string expand = dataService.OperationContext.RequestMessage.GetQueryStringItem(XmlConstants.HttpQueryStringExpand);

            this.RawSelectQueryOptionValue = dataService.OperationContext.RequestMessage.GetQueryStringItem(XmlConstants.HttpQueryStringSelect);

            ResourceType       targetResourceType = requestDescription.TargetResourceType;
            ResourceSetWrapper targetResourceSet  = requestDescription.TargetResourceSet;

            if (!string.IsNullOrEmpty(expand))
            {
                if (targetResourceType == null || targetResourceType.ResourceTypeKind != ResourceTypeKind.EntityType || targetResourceSet == null)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_QueryExpandOptionNotApplicable);
                }
            }

            if (!string.IsNullOrEmpty(this.RawSelectQueryOptionValue))
            {
                ValidateSelectIsAllowedForRequest(requestDescription);

                // Throw if $select requests have been disabled by the user
                Debug.Assert(dataService.Configuration != null, "dataService.Configuration != null");
                if (!dataService.Configuration.DataServiceBehavior.AcceptProjectionRequests)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.DataServiceConfiguration_ProjectionsNotAccepted);
                }
            }

            MetadataProviderEdmModel model = dataService.Provider.GetMetadataProviderEdmModel();

            var uriParser = RequestUriProcessor.CreateUriParserWithBatchReferenceCallback(dataService, dataService.OperationContext.AbsoluteRequestUri);

            try
            {
                Debug.Assert(model.Mode == MetadataProviderEdmModelMode.Serialization, "Model expected to be in serialization mode by default");
                model.Mode  = MetadataProviderEdmModelMode.SelectAndExpandParsing;
                this.Clause = uriParser.ParseSelectAndExpand();
            }
            catch (ODataException ex)
            {
                throw new DataServiceException(400, null, ex.Message, null, ex);
            }
            finally
            {
                model.Mode = MetadataProviderEdmModelMode.Serialization;
            }

            if (this.Clause != null)
            {
                this.HasExpand = this.Clause.SelectedItems.OfType <ExpandedNavigationSelectItem>().Any();
                this.HasSelect = HasSelectedItemAtAnyLevel(this.Clause);
            }
        }
示例#16
0
 private void ApplyNavigationProperties(ODataEntryAnnotation entryAnnotation, ResourceSetWrapper entityResourceSet, ResourceType entityResourceType, object entityResource)
 {
     foreach (ODataNavigationLink link in entryAnnotation)
     {
         ResourcePropertyKind stream             = ResourcePropertyKind.Stream;
         ResourceProperty     navigationProperty = entityResourceType.TryResolvePropertyName(link.Name, stream);
         this.ApplyNavigationProperty(link, entityResourceSet, entityResourceType, navigationProperty, entityResource);
     }
 }
        public void WriteComplexColParameter_WithEmptyCollection()
        {
            ResourceSetWrapper resourceSet = new ResourceSetWrapper()
            {
                ResourceSet = new ODataResourceSet()
            };

            WriteParameter(resourceSet, true, (actual) => Assert.Equal("[]", actual));
            WriteParameter(resourceSet, false, (actual) => Assert.Equal("[]", actual));
        }
示例#18
0
        /// <summary>Checks whether this request has the specified rights.</summary>
        /// <param name="container">Container to check.</param>
        /// <param name="requiredRights">Required rights.</param>
        /// <exception cref="DataServiceException">Thrown if <paramref name="requiredRights"/> aren't available.</exception>
        internal static void CheckResourceRights(ResourceSetWrapper container, EntitySetRights requiredRights)
        {
            Debug.Assert(container != null, "container != null");
            Debug.Assert(requiredRights != EntitySetRights.None, "requiredRights != EntitySetRights.None");

            if ((requiredRights & container.Rights) == 0)
            {
                throw DataServiceException.CreateForbidden();
            }
        }
示例#19
0
        public void WriteComplexColParameter_WithEmptyCollection()
        {
            ResourceSetWrapper resourceSet = new ResourceSetWrapper()
            {
                ResourceSet = new ODataResourceSet()
            };

            WriteParameter(resourceSet, true, (actual) => actual.Should().Be("[]"));
            WriteParameter(resourceSet, false, (actual) => actual.Should().Be("[]"));
        }
示例#20
0
        protected bool PushSegmentForProperty(ResourceProperty property, ResourceType currentResourceType, ExpandedProjectionNode expandedProjectionNode)
        {
            ResourceSetWrapper currentContainer = this.CurrentContainer;

            if (currentContainer != null)
            {
                currentContainer = this.service.Provider.GetContainer(currentContainer, currentResourceType, property);
            }
            return(this.PushSegment(currentContainer, expandedProjectionNode));
        }
示例#21
0
        private ResourceSetWrapper GetNavigationPropertyTargetResourceSet(ResourceSetWrapper parentResourceSet, ResourceType parentResourceType, ResourceProperty navigationProperty)
        {
            ResourceSetWrapper resourceSet = base.Service.Provider.GetContainer(parentResourceSet, parentResourceType, navigationProperty);

            if (resourceSet == null)
            {
                throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_InvalidPropertyNameSpecified(navigationProperty.Name, parentResourceType.FullName));
            }
            base.RequestDescription.UpdateAndCheckEpmFeatureVersion(resourceSet, base.Service);
            return(resourceSet);
        }
示例#22
0
 internal ExpandSegment(string name, Expression filter, int maxResultsExpected, ResourceSetWrapper container, ResourceType targetResourceType, ResourceProperty expandedProperty, System.Data.Services.Providers.OrderingInfo orderingInfo)
 {
     WebUtil.CheckArgumentNull <string>(name, "name");
     CheckFilterType(filter);
     this.name               = name;
     this.filter             = filter;
     this.container          = container;
     this.maxResultsExpected = maxResultsExpected;
     this.expandedProperty   = expandedProperty;
     this.orderingInfo       = orderingInfo;
     this.targetResourceType = targetResourceType;
 }
示例#23
0
        /// <summary>
        /// Handle the navigation properties as specified in the payload
        /// </summary>
        /// <param name="parentResourceSet">resource set where <paramref name="resource"/> belongs to</param>
        /// <param name="parentResourceType">resource type declaring the navigation property.</param>
        /// <param name="resource">instance of the resource declaring the navigation property.</param>
        /// <param name="resourceProperty">resource property containing metadata about the navigation property.</param>
        /// <param name="propertyValue">value of the navigation property.</param>
        private void HandleNavigationProperty(ResourceSetWrapper parentResourceSet, ResourceType parentResourceType, object resource, ResourceProperty resourceProperty, object propertyValue)
        {
            Debug.Assert(parentResourceSet != null, "parentResourceSet != null");
            Debug.Assert(parentResourceType != null, "parentResourceType != null");
            Debug.Assert(resourceProperty != null && resourceProperty.TypeKind == ResourceTypeKind.EntityType, "its must be a nav property");

            bool existingRelationship;

            Deserializer.CheckForBindingInPutOperations(this.Service.OperationContext.Host.AstoriaHttpVerb);

            ResourceSetWrapper propertySet = this.Service.Provider.GetContainer(parentResourceSet, parentResourceType, resourceProperty);

            if (propertySet == null)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(resourceProperty.Name, parentResourceType.FullName));
            }

            // FeatureVersion needs to be 2.0 if any of the property in the types contained in the resource set has KeepInContent false
            this.RequestDescription.UpdateAndCheckEpmFeatureVersion(propertySet, this.Service);

            if (resourceProperty.Kind == ResourcePropertyKind.ResourceReference)
            {
                SegmentInfo segmentInfo = CreateSegment(resourceProperty, resourceProperty.Name, propertySet, true /* singleResult */);
                segmentInfo.TargetKind = RequestTargetKind.Resource;

                // For navigation property, allow both inserts and binding in this case
                propertyValue = this.CreateObject(propertyValue, segmentInfo, false /*topLevel*/, out existingRelationship);
                if (!existingRelationship)
                {
                    this.Updatable.SetReference(resource, resourceProperty.Name, propertyValue);
                }
            }
            else if (resourceProperty.Kind == ResourcePropertyKind.ResourceSetReference)
            {
                if (propertyValue == null)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(resourceProperty.Name));
                }

                ArrayList   resourceCollection = GetArrayList(propertyValue);
                SegmentInfo segmentInfo        = CreateSegment(resourceProperty, resourceProperty.Name, propertySet, true /* singleResult */);
                foreach (object resourceObject in resourceCollection)
                {
                    object resourceInstance = this.CreateObject(resourceObject, segmentInfo, false /*topLevel*/, out existingRelationship);
                    Debug.Assert(resourceInstance != null, "resourceInstance != null");

                    if (!existingRelationship)
                    {
                        this.Updatable.AddReferenceToCollection(resource, resourceProperty.Name, resourceInstance);
                    }
                }
            }
        }
示例#24
0
 private bool PushSegment(ResourceSetWrapper container, ExpandedProjectionNode expandedNode)
 {
     if (((this.service.Configuration.MaxResultsPerCollection == 0x7fffffff) && ((container == null) || (container.PageSize == 0))) && ((this.requestDescription.RootProjectionNode == null) && !this.IsCustomPaged))
     {
         return(false);
     }
     if (this.segmentInfo == null)
     {
         this.segmentInfo = new SegmentInfo();
     }
     this.segmentInfo.PushSegment(container, expandedNode);
     return(true);
 }
示例#25
0
        /// <summary>
        /// Raise the feature version if the given set contains any type with FF mapped properties that is KeepInContent=false.
        /// </summary>
        /// <param name="resourceSet">Resource set to test</param>
        /// <param name="service">service instance</param>
        /// <returns>This RequestDescription instance</returns>
        internal RequestDescription UpdateAndCheckEpmFeatureVersion(ResourceSetWrapper resourceSet, IDataService service)
        {
            Debug.Assert(resourceSet != null, "resourceSet != null");
            Debug.Assert(service != null, "provider != null");

            // For feature version we only look at the SET, and bump the version if it's not V1 compatible.  We do this even if the
            // target kind is not Resource.  So we could have request and response DSV be 1.0 while feature version be 2.0.
            if (!resourceSet.EpmIsV1Compatible(service.Provider))
            {
                this.RaiseFeatureVersion(2, 0, service.Configuration);
            }

            return(this);
        }
示例#26
0
        /// <summary>Composes all query interceptors into a single expression.</summary>
        /// <param name="serviceInstance">Web service instance.</param>
        /// <param name="container">Container for which interceptors should run.</param>
        /// <returns>An expression the filter for query interceptors, possibly null.</returns>
        internal static Expression ComposeQueryInterceptors(object serviceInstance, ResourceSetWrapper container)
        {
            Debug.Assert(container != null, "container != null");
            MethodInfo[] methods = container.QueryInterceptors;
            if (methods == null || methods.Length == 0)
            {
                return(null);
            }

            LambdaExpression filter = null;

            for (int i = 0; i < methods.Length; i++)
            {
                Expression predicate;
                try
                {
                    predicate = (Expression)methods[i].Invoke(serviceInstance, WebUtil.EmptyObjectArray);
                }
                catch (TargetInvocationException tie)
                {
                    ErrorHandler.HandleTargetInvocationException(tie);
                    throw;
                }

                if (predicate == null)
                {
                    throw new InvalidOperationException(Strings.DataService_AuthorizationReturnedNullQuery(methods[i].Name, methods[i].DeclaringType.FullName));
                }

                // predicate is LambdaExpression -- otherwise signature check missed something and following cast would throw
                LambdaExpression lambdaPredicate = ((LambdaExpression)predicate);

                if (filter == null)
                {
                    filter = lambdaPredicate;
                }
                else
                {
                    ParameterExpression parameter         = filter.Parameters[0];
                    Expression          adjustedPredicate = ParameterReplacerVisitor.Replace(
                        lambdaPredicate.Body,             // expression
                        lambdaPredicate.Parameters[0],    // oldParameter
                        parameter);                       // newParameter
                    filter = Expression.Lambda(Expression.And(filter.Body, adjustedPredicate), parameter);
                }
            }

            return(filter);
        }
示例#27
0
        private void GetLinkedResourceSets(out ResourceSetWrapper leftSet, out ResourceSetWrapper rightSet)
        {
            int index = 0;

            while (index < this.segmentInfos.Length)
            {
                if (this.segmentInfos[index].TargetKind == RequestTargetKind.Link)
                {
                    break;
                }
                index++;
            }
            leftSet  = this.segmentInfos[index - 1].TargetContainer;
            rightSet = this.segmentInfos[index + 1].TargetContainer;
        }
        internal static string GetAllowedMethods(DataServiceConfiguration configuration, RequestDescription description)
        {
            if ((description.TargetKind == RequestTargetKind.Metadata) || (description.TargetKind == RequestTargetKind.ServiceDirectory))
            {
                return("GET");
            }
            if (description.TargetKind == RequestTargetKind.Batch)
            {
                return("POST");
            }
            int indexOfTargetEntityResource    = description.GetIndexOfTargetEntityResource();
            ResourceSetWrapper targetContainer = description.SegmentInfos[indexOfTargetEntityResource].TargetContainer;

            return(GetAllowedMethods(configuration, targetContainer, description));
        }
示例#29
0
        /// <summary>
        /// Gets a target resource set for the specified navigation property.
        /// </summary>
        /// <param name="parentResourceSet">The resource set of the entity on which the navigation property is accessed.</param>
        /// <param name="parentResourceType">The resourec type of the entity on which the navigation property is accessed.</param>
        /// <param name="navigationProperty">The navigation property to access.</param>
        /// <returns>The target resource set of the navigation property.</returns>
        /// <remarks>This method validates that the resource set is accessible and it performs appropriate version checks.</remarks>
        private ResourceSetWrapper GetNavigationPropertyTargetResourceSet(ResourceSetWrapper parentResourceSet, ResourceType parentResourceType, ResourceProperty navigationProperty)
        {
            Debug.Assert(parentResourceSet != null, "parentResourceSet != null");
            Debug.Assert(parentResourceType != null, "parentResourceType != null");
            Debug.Assert(navigationProperty != null, "navigationProperty != null");

            ResourceSetWrapper targetResourceSet = this.Service.Provider.GetResourceSet(parentResourceSet, parentResourceType, navigationProperty);

            if (targetResourceSet == null)
            {
                throw DataServiceException.CreateBadRequestError(Microsoft.OData.Service.Strings.BadRequest_InvalidPropertyNameSpecified(navigationProperty.Name, parentResourceType.FullName));
            }

            return(targetResourceSet);
        }
        private void WriteResourceSet(ODataWriter odataWriter, ResourceSetWrapper resourceSet)
        {
            odataWriter.WriteStart(resourceSet.ResourceSet);
            var resources = resourceSet.Resources;

            if (resources != null && resources.Count > 0)
            {
                foreach (var resource in resources)
                {
                    WriteResource(odataWriter, resource);
                }
            }

            odataWriter.WriteEnd();
        }