protected object GetObjectFromSegmentInfo(ResourceType resourceType, System.Data.Services.SegmentInfo segmentInfo, bool verifyETag, bool checkForNull, bool replaceResource) { object crossReferencedResource; if (segmentInfo.RequestExpression == null) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_ResourceCanBeCrossReferencedOnlyForBindOperation); } if (IsCrossReferencedSegment(segmentInfo, this.service)) { crossReferencedResource = GetCrossReferencedResource(segmentInfo); } else { crossReferencedResource = GetResource(segmentInfo, (resourceType != null) ? resourceType.FullName : null, this.Service, checkForNull); if (verifyETag) { this.service.Updatable.SetETagValues(crossReferencedResource, segmentInfo.TargetContainer); } } if (replaceResource) { crossReferencedResource = this.Updatable.ResetResource(crossReferencedResource); WebUtil.CheckResourceExists(crossReferencedResource != null, segmentInfo.Identifier); } return(crossReferencedResource); }
private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url) { base.CheckAndIncrementObjectCount(); RequestDescription description = RequestUriProcessor.ProcessRequestUri(RequestUriProcessor.GetAbsoluteUriFromReference(url, base.Service.OperationContext), base.Service, true); if ((this.ContentFormat == ContentFormat.Atom) && !description.IsSingleResult) { if ((navigationProperty != null) && (navigationProperty.Kind == ResourcePropertyKind.ResourceReference)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name)); } } else { object propertyValue = base.Service.GetResource(description, description.SegmentInfos.Length - 1, null); if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference) { base.Updatable.SetReference(entityResource, navigationProperty.Name, propertyValue); } else { WebUtil.CheckResourceExists(propertyValue != null, description.LastSegmentInfo.Identifier); base.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, propertyValue); } } }
/// <summary> /// Creates a new segment for an open property. /// </summary> /// <param name="previous">previous segment info.</param> /// <param name="identifier">name of the segment.</param> /// <returns>new open property segment.</returns> private static SegmentInfo CreateOpenPropertySegment(SegmentInfo previous, string identifier) { SegmentInfo segment = new SegmentInfo { Identifier = identifier }; // Handle an open type property. If the current leaf isn't an // object (which implies it's already an open type), then // it should be marked as an open type. if (previous.TargetResourceType != null) { WebUtil.CheckResourceExists(previous.TargetResourceType.IsOpenType, segment.Identifier); } // Open navigation properties are not supported on OpenTypes. We should throw on the following cases: // 1. the segment before $ref is always a navigation property pointing to a resource // 2. if the segment hasQuery, it is pointing to a resource // 3. if this is a POST operation, the target has to be either a set of links or an entity set if (previous.TargetKind == RequestTargetKind.Link) { throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(segment.Identifier)); } segment.TargetSource = RequestTargetSource.Property; segment.TargetResourceType = null; segment.TargetKind = RequestTargetKind.OpenProperty; segment.SingleResult = true; return(segment); }
public static IDataServiceInvokable CreateServiceActionInvokable(DataServiceOperationContext operationContext, IDataServiceActionProvider actionProvider, ServiceAction serviceAction, object[] parameterTokens) { WebUtil.CheckArgumentNull <DataServiceOperationContext>(operationContext, "operationContext"); WebUtil.CheckArgumentNull <IDataServiceActionProvider>(actionProvider, "actionProvider"); WebUtil.CheckArgumentNull <ServiceAction>(serviceAction, "serviceAction"); IDataServiceInvokable invokable = actionProvider.CreateInvokable(operationContext, serviceAction, parameterTokens); WebUtil.CheckResourceExists(invokable != null, serviceAction.Name); return(invokable); }
protected object GetTargetResourceToBind(Uri referencedUri, bool checkNull) { System.Data.Services.RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true); object obj2 = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null); if (checkNull) { WebUtil.CheckResourceExists(obj2 != null, description.LastSegmentInfo.Identifier); } return(obj2); }
public ConstantExpression GetQueryRootForResourceSet(ResourceSetWrapper resourceSet, DataServiceOperationContext operationContext) { IQueryable queryRootForResourceSet = this.queryProvider.GetQueryRootForResourceSet(resourceSet.ResourceSet); WebUtil.CheckResourceExists(queryRootForResourceSet != null, resourceSet.Name); if (!resourceSet.QueryRootType.IsAssignableFrom(queryRootForResourceSet.GetType())) { throw new InvalidOperationException(System.Data.Services.Strings.DataServiceProviderWrapper_InvalidQueryRootType(resourceSet.Name, resourceSet.QueryRootType.FullName)); } return(Expression.Constant(queryRootForResourceSet)); }
public static IDataServiceInvokable CreateServiceActionInvokable(DataServiceOperationContext operationContext, IDataServiceActionProvider actionProvider, ServiceAction serviceAction, object[] parameterTokens) { WebUtil.CheckArgumentNull(operationContext, "operationContext"); WebUtil.CheckArgumentNull(actionProvider, "actionProvider"); WebUtil.CheckArgumentNull(serviceAction, "serviceAction"); operationContext.CurrentDataService.ProcessingPipeline.AssertAndUpdateDebugStateAtInvokeServiceAction(operationContext.CurrentDataService); IDataServiceInvokable result = actionProvider.CreateInvokable(operationContext, serviceAction, parameterTokens); WebUtil.CheckResourceExists(result != null, serviceAction.Name); return(result); }
internal static QueryResultInfo GetSingleResultFromRequest(SegmentInfo segmentInfo) { Debug.Assert(segmentInfo != null && segmentInfo.RequestEnumerable != null, "segmentInfo != null && segmentInfo.RequestEnumerable != null"); var queryResults = new QueryResultInfo(segmentInfo.RequestEnumerable); try { WebUtil.CheckResourceExists(queryResults.MoveNext(), segmentInfo.Identifier); WebUtil.CheckNullDirectReference(queryResults.Current, segmentInfo); return(queryResults); } catch { // Dispose the Enumerator in case of error WebUtil.Dispose(queryResults); throw; } }
/// <summary> /// Sets a resource reference to resource referenced by a URL. /// </summary> /// <param name="entityResource">The entity resource to set the resource reference on.</param> /// <param name="navigationProperty">The navigation property for which to set the reference to null.</param> /// <param name="url">The URL which points to the resource to set as the value of the navigation property.</param> private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url) { Debug.Assert(entityResource != null, "entityResource != null"); Debug.Assert(navigationProperty != null, "navigationProperty != null"); // Update the object count when you are performing a bind operation. this.CheckAndIncrementObjectCount(); // Get the referenced resource. Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(url, this.Service.OperationContext); RequestDescription requestDescription = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true /*internalQuery*/); // ATOM deserializer checks that the url doesn't point to a collection. If it does it will ignore the link. if (this.IsAtomRequest && !requestDescription.IsSingleResult) { if (navigationProperty != null && navigationProperty.Kind == ResourcePropertyKind.ResourceReference) { throw DataServiceException.CreateBadRequestError(Microsoft.OData.Service.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name)); } return; } // Get the resource object referencedResource = this.Service.GetResource(requestDescription, requestDescription.SegmentInfos.Count - 1, null); if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference) { this.Updatable.SetReference(entityResource, navigationProperty.Name, referencedResource); } else { Debug.Assert(navigationProperty.Kind == ResourcePropertyKind.ResourceSetReference, "Only navigation properties are allowed in this method."); // If we are to set the resource to a collection property it must not be null (so check for nulls), otherwise do allow nulls for backward compatibility. WebUtil.CheckResourceExists(referencedResource != null, requestDescription.LastSegmentInfo.Identifier); this.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, referencedResource); } }
internal static IEnumerator GetSingleResultFromRequest(SegmentInfo segmentInfo) { IEnumerator enumerator2; IEnumerator requestEnumerator = WebUtil.GetRequestEnumerator(segmentInfo.RequestEnumerable); bool flag = true; try { WebUtil.CheckResourceExists(requestEnumerator.MoveNext(), segmentInfo.Identifier); RequestDescription.CheckNullDirectReference(requestEnumerator.Current, segmentInfo); flag = false; enumerator2 = requestEnumerator; } finally { if (flag) { WebUtil.Dispose(requestEnumerator); } } return(enumerator2); }
/// <summary>Creates the first <see cref="SegmentInfo"/> for a request.</summary> /// <param name="segment">The text of the segment.</param> /// <returns>A description of the information on the segment.</returns> private SegmentInfo CreateFirstSegment(ODataPathSegment segment) { Debug.Assert(segment != null, "identifier != null"); // Look for well-known system entry points. if (segment is MetadataSegment) { return(new SegmentInfo { Identifier = XmlConstants.UriMetadataSegment, TargetKind = RequestTargetKind.Metadata }); } if (segment is BatchSegment) { return(new SegmentInfo { Identifier = XmlConstants.UriBatchSegment, TargetKind = RequestTargetKind.Batch }); } if (segment is CountSegment) { // $count on root: throw throw DataServiceException.CreateResourceNotFound(Strings.RequestUriProcessor_CountOnRoot); } // Look for a service operation. OperationImportSegment serviceOperation = segment as OperationImportSegment; if (serviceOperation != null) { Debug.Assert(serviceOperation.OperationImports.Count() == 1, "Operation import segment should only ever have exactly one operation. Was a change made to how MetadataProviderEdmModel finds actions/service operations"); var operationImport = serviceOperation.OperationImports.Single(); var operation = ((MetadataProviderEdmOperationImport)operationImport).ServiceOperation; Debug.Assert(operation != null, "operation != null"); if (operation.Kind == OperationKind.ServiceOperation) { return(CreateSegmentForServiceOperation(operation)); } Debug.Assert(operation.Kind == OperationKind.Action, "serviceAction.Kind == OperationKind.Action"); return(this.CreateSegmentForServiceAction(null /*previousSegment*/, operation)); } var batchReferenceSegment = segment as BatchReferenceSegment; if (batchReferenceSegment != null) { SegmentInfo referencedSegmentInfo = this.crossReferenceCallback(batchReferenceSegment.ContentId); Debug.Assert(referencedSegmentInfo != null, "Could not find SegmentInfo for content-id: " + batchReferenceSegment.ContentId); referencedSegmentInfo.Identifier = batchReferenceSegment.ContentId; return(referencedSegmentInfo); } // Look for an entity set. EntitySetSegment entitySetSegment = segment as EntitySetSegment; if (entitySetSegment != null) { var container = ((IResourceSetBasedEdmEntitySet)entitySetSegment.EntitySet).ResourceSet; Debug.Assert(container != null, "container != null"); SegmentInfo segmentInfo = new SegmentInfo { Identifier = container.Name, TargetResourceSet = container, TargetResourceType = container.ResourceType, TargetSource = RequestTargetSource.EntitySet, TargetKind = RequestTargetKind.Resource, SingleResult = false }; return(segmentInfo); } WebUtil.CheckResourceExists(false, segment.ToString()); return(null); }
/// <summary>Applies the information from a link to the specified resource.</summary> /// <param name='link'>LinkDescriptor with information to apply.</param> /// <param name="resourceSet">Set for the target resource.</param> /// <param name='resourceType'>Type for the target resource.</param> /// <param name='resource'>Target resource to which information will be applied.</param> /// <param name="propertyName">Name of the property that this link represents.</param> private void ApplyLink(SyndicationLink link, ResourceSetWrapper resourceSet, ResourceType resourceType, object resource, string propertyName) { Debug.Assert(link != null, "link != null"); Debug.Assert(resourceType != null, "resourceType != null"); Debug.Assert(resource != null, "resource != null"); ResourceProperty property = resourceType.TryResolvePropertyName(propertyName); if (property == null) { // Open navigation properties are not supported on OpenTypes throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(propertyName)); } if (property.TypeKind != ResourceTypeKind.EntityType) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidNavigationPropertyName(propertyName, resourceType.FullName)); } string typeParameterValue = ValidateTypeParameterForNonOpenTypeProperties(link.MediaType, property); LinkContent linkContent = this.HandleLinkContent(link, resource, resourceSet, resourceType, property, typeParameterValue, propertyName); #region Handle bind/unbind operation // If the href was specified empty or an empty inline element was specified, then we will set the // reference to null - this helps in overrriding if there was a default non-value for this property // else if only link element was specified, and then href points to a single result, then we will // perform a bind operation if ((linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && String.IsNullOrEmpty(link.Uri.OriginalString)) || linkContent == LinkContent.EmptyInlineElementSpecified) { // update the object count when you are performing a bind operation this.CheckAndIncrementObjectCount(); if (property != null && property.Kind == ResourcePropertyKind.ResourceSetReference) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(propertyName)); } // For open properties, we will assume that this is a reference property and set it to null this.Updatable.SetReference(resource, propertyName, null); } else if (linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && !String.IsNullOrEmpty(link.Uri.OriginalString)) { // update the object count when you are performing a bind operation this.CheckAndIncrementObjectCount(); // If the link points to a reference navigation property, then update the link Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(link.Uri.OriginalString, this.Service.OperationContext); RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service); if (!description.IsSingleResult) { if (property != null && property.Kind == ResourcePropertyKind.ResourceReference) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_LinkHrefMustReferToSingleResource(propertyName)); } return; } // no need to check for null. For collection properties, they can never be null and that // check has been added below. For reference properties, if they are null, it means unbind // and hence no need to check for null. // Get the resource object targetResource = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null); if (property.Kind == ResourcePropertyKind.ResourceReference) { this.Updatable.SetReference(resource, propertyName, targetResource); } else { WebUtil.CheckResourceExists(targetResource != null, description.LastSegmentInfo.Identifier); this.Updatable.AddReferenceToCollection(resource, propertyName, targetResource); } } #endregion Handle bind/unbind operation }