private static System.Data.Services.SegmentInfo CreateValueSegment(System.Data.Services.SegmentInfo previous, IDataService service, string identifier, bool hasQuery) { System.Data.Services.SegmentInfo info; if (previous.TargetKind == RequestTargetKind.Primitive) { info = new System.Data.Services.SegmentInfo(previous); } else { CheckSegmentIsComposable(previous); info = new System.Data.Services.SegmentInfo { TargetSource = RequestTargetSource.Property, TargetResourceType = previous.TargetResourceType }; } info.Identifier = identifier; WebUtil.CheckSyntaxValid(!hasQuery); CheckSingleResult(previous.SingleResult, previous.Identifier); info.RequestExpression = previous.RequestExpression; info.SingleResult = true; if (previous.TargetKind == RequestTargetKind.Primitive) { info.TargetKind = RequestTargetKind.PrimitiveValue; if (previous.TargetResourceType.InstanceType.IsSpatial()) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_ValuesCannotBeReturnedForSpatialTypes); } return info; } if (previous.TargetKind == RequestTargetKind.OpenProperty) { info.TargetKind = RequestTargetKind.OpenPropertyValue; return info; } info.TargetKind = RequestTargetKind.MediaResource; RequestQueryProcessor.CheckEmptyQueryArguments(service, false); return info; }
private static System.Data.Services.SegmentInfo[] CreateSegments(string[] segments, IDataService service) { System.Data.Services.SegmentInfo segment = null; System.Data.Services.SegmentInfo[] infoArray = new System.Data.Services.SegmentInfo[segments.Length]; bool crossReferencingUrl = false; bool flag2 = false; ResourceType targetResourceType = null; for (int i = 0; i < segments.Length; i++) { string str2; System.Data.Services.SegmentInfo info2; string str = segments[i]; bool hasQuery = ExtractSegmentIdentifier(str, out str2); string queryPortion = hasQuery ? str.Substring(str2.Length) : null; if (str2.Length == 0) { throw DataServiceException.ResourceNotFoundError(System.Data.Services.Strings.RequestUriProcessor_EmptySegmentInRequestUrl); } if (segment == null) { info2 = CreateFirstSegment(service, str2, queryPortion, out crossReferencingUrl); } else { if (DataServiceActionProviderWrapper.IsServiceActionSegment(segment)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestUriProcessor_MustBeLeafSegment(segment.Identifier)); } if ((((segment.TargetKind == RequestTargetKind.Batch) || (segment.TargetKind == RequestTargetKind.Metadata)) || ((segment.TargetKind == RequestTargetKind.PrimitiveValue) || (segment.TargetKind == RequestTargetKind.VoidOperation))) || (((segment.TargetKind == RequestTargetKind.OpenPropertyValue) || (segment.TargetKind == RequestTargetKind.MediaResource)) || (segment.TargetKind == RequestTargetKind.Collection))) { throw DataServiceException.ResourceNotFoundError(System.Data.Services.Strings.RequestUriProcessor_MustBeLeafSegment(segment.Identifier)); } if (flag2 && (str2 != "$count")) { throw DataServiceException.ResourceNotFoundError(System.Data.Services.Strings.RequestUriProcessor_CannotSpecifyAfterPostLinkSegment(str2, "$links")); } if (str2 == "$value") { info2 = CreateValueSegment(segment, service, str2, hasQuery); } else { if (segment.TargetKind == RequestTargetKind.Primitive) { throw DataServiceException.ResourceNotFoundError(System.Data.Services.Strings.RequestUriProcessor_ValueSegmentAfterScalarPropertySegment(segment.Identifier, str2)); } if (((segment.TargetKind == RequestTargetKind.Resource) && segment.SingleResult) && (str2 == "$links")) { info2 = new System.Data.Services.SegmentInfo(segment) { Identifier = str2, TargetKind = RequestTargetKind.Link }; } else if (str2 == "$count") { info2 = CreateCountSegment(segment, service); } else { ResourceProperty property; flag2 = segment.TargetKind == RequestTargetKind.Link; CheckSegmentIsComposable(segment); if (segment.TargetResourceType == null) { property = null; targetResourceType = null; } else { property = segment.TargetResourceType.TryResolvePropertyName(str2); } if (property != null) { CheckSingleResult(segment.SingleResult, segment.Identifier); targetResourceType = null; if (property.IsOfKind(ResourcePropertyKind.Stream)) { info2 = CreateNamedStreamSegment(segment, property, service); } else { info2 = CreatePropertySegment(segment, property, queryPortion, service, crossReferencingUrl); } } else { if (segment.TargetContainer != null) { targetResourceType = WebUtil.ResolveTypeIdentifier(service.Provider, str2, segment.TargetResourceType, targetResourceType != null); } else { targetResourceType = null; } if (targetResourceType != null) { info2 = CreateTypeNameSegment(segment, targetResourceType, service, str2, queryPortion); } else { bool flag4; OperationWrapper serviceAction = null; string nameFromContainerQualifiedName = service.Provider.GetNameFromContainerQualifiedName(str2, out flag4); if ((segment.TargetResourceType != null) && (!segment.TargetResourceType.IsOpenType || flag4)) { serviceAction = service.ActionProvider.TryResolveServiceAction(service.OperationContext, nameFromContainerQualifiedName); } if (serviceAction != null) { info2 = CreateSegmentForServiceAction(segment, serviceAction, service, str2, queryPortion); } else { CheckSingleResult(segment.SingleResult, segment.Identifier); info2 = CreateOpenPropertySegment(segment, service, str2, queryPortion != null); } } } } } } infoArray[i] = info2; segment = infoArray[i]; } if ((segments.Length != 0) && (segment.TargetKind == RequestTargetKind.Link)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestUriProcessor_MissingSegmentAfterLink("$links")); } if (infoArray.Length > 0) { if ((segment.Operation != null) && (segment.Operation.ResultKind == ServiceOperationResultKind.QueryWithSingleResult)) { RequestQueryProcessor.CheckEmptySetQueryArguments(service); } ComposeExpressionForSegments(infoArray, service); } return infoArray; }
private static System.Data.Services.SegmentInfo CreateTypeNameSegment(System.Data.Services.SegmentInfo previous, ResourceType targetResourceType, IDataService service, string identifier, string queryPortion) { WebUtil.CheckMaxProtocolVersion(RequestDescription.Version3Dot0, service.Configuration.DataServiceBehavior.MaxProtocolVersion.ToVersion()); System.Data.Services.SegmentInfo segment = new System.Data.Services.SegmentInfo { Identifier = identifier }; segment.Operation = previous.Operation; segment.TargetKind = previous.TargetKind; segment.TargetSource = previous.TargetSource; segment.TargetResourceType = targetResourceType; segment.SingleResult = previous.SingleResult; segment.TargetContainer = previous.TargetContainer; segment.ProjectedProperty = previous.ProjectedProperty; segment.IsTypeIdentifierSegment = true; if (queryPortion != null) { WebUtil.CheckSyntaxValid(!segment.SingleResult); ExtractKeyPredicates(queryPortion, segment); } return segment; }
private static System.Data.Services.SegmentInfo CreateSegmentForServiceAction(System.Data.Services.SegmentInfo previousSegment, OperationWrapper serviceAction, IDataService service, string identifier, string queryPortion) { System.Data.Services.SegmentInfo info = new System.Data.Services.SegmentInfo { Identifier = identifier, Operation = serviceAction }; if ((previousSegment != null) && (previousSegment.TargetKind == RequestTargetKind.Link)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestUriProcessor_LinkSegmentMustBeFollowedByEntitySegment(identifier, "$links")); } if ((previousSegment != null) && Deserializer.IsCrossReferencedSegment(previousSegment, service)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestUriProcessor_BatchedActionOnEntityCreatedInSameChangeset(identifier)); } info.TargetSource = RequestTargetSource.ServiceOperation; if (service.OperationContext.RequestMethod != serviceAction.Method) { throw DataServiceException.CreateMethodNotAllowed(System.Data.Services.Strings.RequestUriProcessor_MethodNotAllowed, serviceAction.Method); } if ((queryPortion != null) && !string.IsNullOrEmpty(RemoveFilterParens(queryPortion))) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestUriProcessor_SegmentDoesNotSupportKeyPredicates(identifier)); } if (serviceAction.ResultKind != ServiceOperationResultKind.Void) { info.TargetContainer = serviceAction.GetResultSet(service.Provider, (previousSegment == null) ? null : previousSegment.TargetContainer); info.TargetResourceType = serviceAction.ReturnType; info.TargetKind = TargetKindFromType(info.TargetResourceType); if ((info.TargetKind == RequestTargetKind.Resource) && (info.TargetContainer == null)) { throw DataServiceException.CreateForbidden(); } info.SingleResult = serviceAction.ResultKind == ServiceOperationResultKind.DirectValue; } else { info.TargetContainer = null; info.TargetResourceType = null; info.TargetKind = RequestTargetKind.VoidOperation; } RequestQueryProcessor.CheckEmptyQueryArguments(service, false); return info; }
private static System.Data.Services.SegmentInfo CreatePropertySegment(System.Data.Services.SegmentInfo previous, ResourceProperty property, string queryPortion, IDataService service, bool crossReferencingUri) { System.Data.Services.SegmentInfo segment = new System.Data.Services.SegmentInfo { Identifier = property.Name, ProjectedProperty = property }; segment.TargetResourceType = property.ResourceType; ResourcePropertyKind kind = property.Kind; segment.SingleResult = kind != ResourcePropertyKind.ResourceSetReference; segment.TargetSource = RequestTargetSource.Property; if ((previous.TargetKind == RequestTargetKind.Link) && (property.TypeKind != ResourceTypeKind.EntityType)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestUriProcessor_LinkSegmentMustBeFollowedByEntitySegment(segment.Identifier, "$links")); } switch (kind) { case ResourcePropertyKind.ResourceSetReference: case ResourcePropertyKind.ResourceReference: segment.TargetKind = RequestTargetKind.Resource; segment.TargetContainer = service.Provider.GetContainer(previous.TargetContainer, previous.TargetResourceType, property); if (segment.TargetContainer == null) { throw DataServiceException.CreateResourceNotFound(property.Name); } break; case ResourcePropertyKind.Collection: segment.TargetKind = RequestTargetKind.Collection; break; case ResourcePropertyKind.ComplexType: segment.TargetKind = RequestTargetKind.ComplexObject; break; default: segment.TargetKind = RequestTargetKind.Primitive; break; } if (queryPortion != null) { WebUtil.CheckSyntaxValid(!segment.SingleResult); if (crossReferencingUri) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_ResourceCanBeCrossReferencedOnlyForBindOperation); } ExtractKeyPredicates(queryPortion, segment); } return segment; }
private static System.Data.Services.SegmentInfo CreateOpenPropertySegment(System.Data.Services.SegmentInfo previous, IDataService service, string identifier, bool hasQuery) { System.Data.Services.SegmentInfo info = new System.Data.Services.SegmentInfo { Identifier = identifier }; if (previous.TargetResourceType != null) { WebUtil.CheckResourceExists(previous.TargetResourceType.IsOpenType, info.Identifier); } if (((previous.TargetKind == RequestTargetKind.Link) || hasQuery) || (service.OperationContext.Host.HttpVerb == HttpVerbs.POST)) { throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(info.Identifier)); } info.TargetSource = RequestTargetSource.Property; info.TargetResourceType = null; info.TargetKind = RequestTargetKind.OpenProperty; info.SingleResult = true; return info; }
private static System.Data.Services.SegmentInfo CreateNamedStreamSegment(System.Data.Services.SegmentInfo previous, ResourceProperty streamProperty, IDataService service) { System.Data.Services.SegmentInfo info = new System.Data.Services.SegmentInfo { Identifier = streamProperty.Name }; info.TargetKind = RequestTargetKind.MediaResource; info.RequestExpression = previous.RequestExpression; info.SingleResult = true; info.TargetResourceType = previous.TargetResourceType; info.TargetSource = RequestTargetSource.Property; RequestQueryProcessor.CheckEmptyQueryArguments(service, false); return info; }
private static System.Data.Services.SegmentInfo CreateFirstSegment(IDataService service, string identifier, string queryPortion, out bool crossReferencingUrl) { bool flag; crossReferencingUrl = false; System.Data.Services.SegmentInfo segment = new System.Data.Services.SegmentInfo { Identifier = identifier }; if (segment.Identifier == "$metadata") { WebUtil.CheckSyntaxValid(queryPortion == null); segment.TargetKind = RequestTargetKind.Metadata; return segment; } if (segment.Identifier == "$batch") { WebUtil.CheckSyntaxValid(queryPortion == null); segment.TargetKind = RequestTargetKind.Batch; return segment; } if (segment.Identifier == "$count") { throw DataServiceException.CreateResourceNotFound(System.Data.Services.Strings.RequestUriProcessor_CountOnRoot); } segment.Operation = service.Provider.TryResolveServiceOperation(segment.Identifier); if (segment.Operation != null) { return CreateSegmentForServiceOperation(service, queryPortion, segment); } System.Data.Services.SegmentInfo segmentForContentId = service.GetSegmentForContentId(segment.Identifier); if (segmentForContentId != null) { segmentForContentId.Identifier = segment.Identifier; crossReferencingUrl = true; return segmentForContentId; } ResourceSetWrapper wrapper = service.Provider.TryResolveResourceSet(segment.Identifier); if (wrapper != null) { segment.TargetContainer = wrapper; segment.TargetResourceType = wrapper.ResourceType; segment.TargetSource = RequestTargetSource.EntitySet; segment.TargetKind = RequestTargetKind.Resource; segment.SingleResult = false; if (queryPortion != null) { ExtractKeyPredicates(queryPortion, segment); } return segment; } string nameFromContainerQualifiedName = service.Provider.GetNameFromContainerQualifiedName(identifier, out flag); OperationWrapper serviceAction = service.ActionProvider.TryResolveServiceAction(service.OperationContext, nameFromContainerQualifiedName); WebUtil.CheckResourceExists(serviceAction != null, identifier); return CreateSegmentForServiceAction(null, serviceAction, service, identifier, queryPortion); }