public static Type GetClrType(this IEdmModel edmModel, IEdmEntitySetBase entitySet) { IEdmEntityType entityType = entitySet.EntityType(); edmModel = OeEdmClrHelper.GetEdmModel(edmModel, entityType); return(edmModel.GetAnnotationValue <Type>(entityType)); }
public virtual async Task ExecuteResultAsync(ActionContext context) { var settings = new ODataMessageWriterSettings() { BaseUri = _odataUri.ServiceRoot, EnableMessageStreamDisposal = false, ODataUri = _odataUri, Validations = ValidationKinds.ThrowIfTypeConflictsWithMetadata | ValidationKinds.ThrowOnDuplicatePropertyNames, Version = ODataVersion.V4 }; var requestHeaders = OeRequestHeaders.Parse(context.HttpContext.Request.Headers["Accept"], context.HttpContext.Request.Headers["Prefer"]); if (requestHeaders.MaxPageSize > 0 && PageSize == 0) { PageSize = requestHeaders.MaxPageSize; } IODataResponseMessage responseMessage = new Infrastructure.OeInMemoryMessage(context.HttpContext.Response.Body, context.HttpContext.Request.ContentType); using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, settings, _edmModel)) { ODataUtils.SetHeadersForPayload(messageWriter, ODataPayloadKind.ResourceSet); IEdmEntityType entityType = _resultEntitySet.EntityType(); ODataWriter writer = messageWriter.CreateODataResourceSetWriter(_resultEntitySet, entityType); await SerializeAsync(writer, requestHeaders.MetadataLevel); } }
public static Type GetClrType(this IEdmModel edmModel, IEdmEntitySetBase entitySet) { IEdmEntityType entityType = entitySet.EntityType(); OeValueAnnotation <Type> clrTypeAnnotation = edmModel.GetAnnotationValue <OeValueAnnotation <Type> >(entityType); return(clrTypeAnnotation.Value); }
public static Type GetClrType(this IEdmModel edmModel, IEdmEntitySetBase entitySet) { IEdmEntityType entityType = entitySet.EntityType(); IEdmModel? model = OeEdmClrHelper.GetEdmModel(edmModel, entityType); if (model == null) { throw new InvalidOperationException("Add type annotation for " + entityType.FullTypeName()); } return(model.GetAnnotationValue <Type>(entityType)); }
private OeEntryFactory(IEdmEntitySetBase entitySet, OePropertyAccessor[] accessors) { Array.Sort(accessors, AccessorByNameComparer.Instance); EntitySet = entitySet; _allAccessors = accessors; Accessors = GetAccessorsWithoutSkiptoken(accessors); EntityType = entitySet.EntityType(); NavigationLinks = Array.Empty <OeEntryFactory>(); _typeName = EntityType.FullName(); }
public static OePropertyAccessor[] CreateFromExpression(Expression source, ParameterExpression parameter, IEdmEntitySetBase entitySet) { var propertyAccessors = new List <OePropertyAccessor>(); foreach (IEdmStructuralProperty edmProperty in entitySet.EntityType().StructuralProperties()) { MemberExpression expression = Expression.Property(source, source.Type.GetProperty(edmProperty.Name)); propertyAccessors.Add(CreatePropertyAccessor(edmProperty, expression, parameter)); } return(propertyAccessors.ToArray()); }
public static OePropertyAccessor[] CreateFromType(Type clrType, IEdmEntitySetBase entitySet) { ParameterExpression parameter = Expression.Parameter(typeof(Object)); UnaryExpression instance = Expression.Convert(parameter, clrType); var propertyAccessors = new List <OePropertyAccessor>(); foreach (IEdmStructuralProperty edmProperty in entitySet.EntityType().StructuralProperties()) { MemberExpression expression = Expression.Property(instance, clrType.GetProperty(edmProperty.Name)); propertyAccessors.Add(CreatePropertyAccessor(edmProperty, expression, parameter, false)); } return(propertyAccessors.ToArray()); }
internal static OrderByClause GetUniqueOrderBy(IEdmEntitySetBase entitySet, OrderByClause orderByClause, ApplyClause applyClause) { if (orderByClause != null && applyClause == null && GetIsKey(entitySet.EntityType(), GetEdmProperies(orderByClause))) { return(orderByClause); } List <SingleValuePropertyAccessNode> orderByProperties = GetOrderByProperties(entitySet, orderByClause, applyClause); if (orderByProperties.Count == 0) { return(orderByClause ?? throw new InvalidOperationException("orderByClause must not null")); } OrderByClause uniqueOrderByClause = null; for (int i = orderByProperties.Count - 1; i >= 0; i--) { ResourceRangeVariableReferenceNode source; if (orderByProperties[i].Source is SingleNavigationNode navigationNode) { source = (ResourceRangeVariableReferenceNode)navigationNode.Source; } else { source = (ResourceRangeVariableReferenceNode)orderByProperties[i].Source; } uniqueOrderByClause = new OrderByClause(uniqueOrderByClause, orderByProperties[i], OrderByDirection.Ascending, source.RangeVariable); } if (orderByClause == null) { return(uniqueOrderByClause); } var orderByClauses = new Stack <OrderByClause>(); do { orderByClauses.Push(orderByClause); orderByClause = orderByClause.ThenBy; }while (orderByClause != null); while (orderByClauses.Count > 0) { orderByClause = orderByClauses.Pop(); uniqueOrderByClause = new OrderByClause(uniqueOrderByClause, orderByClause.Expression, orderByClause.Direction, orderByClause.RangeVariable); } return(uniqueOrderByClause); }
public OeEntryFactory(IEdmEntitySetBase entitySet, OePropertyAccessor[] accessors, OePropertyAccessor[] skipTokenAccessors) { Array.Sort(accessors, AccessorByNameComparer.Instance); EntitySet = entitySet; _allAccessors = accessors; Accessors = GetAccessorsWithoutSkiptoken(accessors); SkipTokenAccessors = skipTokenAccessors; EdmEntityType = entitySet.EntityType(); NavigationLinks = Array.Empty <OeEntryFactory>(); _typeName = EdmEntityType.FullName(); IsTuple = accessors.Length == 0 ? false : OeExpressionHelper.IsTupleType(accessors[0].PropertyExpression.Expression.Type); }
public static OePropertyAccessor[] CreateFromType(Type clrType, IEdmEntitySetBase entitySet) { ParameterExpression parameter = Expression.Parameter(typeof(Object)); UnaryExpression instance = Expression.Convert(parameter, clrType); var propertyAccessors = new List <OePropertyAccessor>(); if (typeof(OeIndexerProperty).IsAssignableFrom(clrType)) { InterfaceMapping interfaceMapping = clrType.GetInterfaceMap(typeof(OeIndexerProperty)); foreach (IEdmStructuralProperty edmProperty in entitySet.EntityType().StructuralProperties()) { MethodCallExpression expression = Expression.Call(instance, interfaceMapping.TargetMethods[0], Expression.Constant(edmProperty.Name)); propertyAccessors.Add(CreatePropertyAccessor(edmProperty, expression, parameter, false)); } } else { foreach (IEdmStructuralProperty edmProperty in entitySet.EntityType().StructuralProperties()) { PropertyInfo?propertyInfo = clrType.GetPropertyIgnoreCaseOrNull(edmProperty); if (propertyInfo == null) { if (!(edmProperty is OeEdmStructuralShadowProperty)) { throw new InvalidOperationException("Property " + edmProperty.Name + " not found in clr type " + clrType.Name); } } else { MemberExpression expression = Expression.Property(instance, propertyInfo); propertyAccessors.Add(CreatePropertyAccessor(edmProperty, expression, parameter, false)); } } } return(propertyAccessors.ToArray()); }
public static Uri ComputeId(Uri baseUri, IEdmEntitySetBase entitySet, ODataResource entry) { Uri uri = AppendSegment(baseUri, entitySet.Name, true); var builder = new StringBuilder(uri.IsAbsoluteUri ? uri.AbsoluteUri : uri.OriginalString); builder.Append('('); using (IEnumerator <IEdmStructuralProperty> enumerator = entitySet.EntityType().Key().GetEnumerator()) { if (!enumerator.MoveNext()) { throw new InvalidOperationException("Key property not found for EntityType " + entitySet.EntityType().FullName()); } IEdmStructuralProperty keyProperty = enumerator.Current; if (enumerator.MoveNext()) { int counter = 0; do { ODataProperty property = GetProperty(entry, keyProperty.Name); builder.Append(property.Name); builder.Append('='); builder.Append(ODataUriUtils.ConvertToUriLiteral(property.Value, ODataVersion.V4)); if (counter == 0 || enumerator.MoveNext()) { keyProperty = enumerator.Current; builder.Append(','); counter = 1; } else { counter = 2; } }while (counter < 2); } else { ODataProperty property = GetProperty(entry, keyProperty.Name); builder.Append(ODataUriUtils.ConvertToUriLiteral(property.Value, ODataVersion.V4)); } } builder.Append(')'); return(new Uri(builder.ToString(), UriKind.Absolute)); }
public static Uri ComputeId(Uri baseUri, IEdmEntitySetBase entitySet, ODataResource entry) { Uri uri = AppendSegment(baseUri, entitySet.Name, true); var builder = new StringBuilder(uri.IsAbsoluteUri ? uri.AbsoluteUri : uri.OriginalString); builder.Append('('); IEnumerable <IEdmStructuralProperty> keyProperties = entitySet.EntityType().Key(); using (IEnumerator <IEdmStructuralProperty> enumerator = keyProperties.GetEnumerator()) { if (!enumerator.MoveNext()) { return(null); } IEdmStructuralProperty keyProperty = enumerator.Current; if (enumerator.MoveNext()) { int counter = 0; while (keyProperty != null) { ODataProperty property = GetProperty(entry, keyProperty.Name); builder.Append(property.Name); builder.Append('='); builder.Append(ODataUriUtils.ConvertToUriLiteral(property.Value, ODataVersion.V4)); keyProperty = counter == 0 || enumerator.MoveNext() ? enumerator.Current : null; if (keyProperty != null) { builder.Append(','); } counter++; } } else { ODataProperty property = GetProperty(entry, keyProperty.Name); builder.Append(ODataUriUtils.ConvertToUriLiteral(property.Value, ODataVersion.V4)); } } builder.Append(')'); return(new Uri(builder.ToString(), UriKind.Absolute)); }
private static List <SingleValuePropertyAccessNode> GetOrderByProperties(IEdmEntitySetBase entitySet, OrderByClause?orderByClause, ApplyClause?applyClause) { var keys = new List <SingleValuePropertyAccessNode>(); GroupByTransformationNode groupByNode; if (applyClause != null && (groupByNode = applyClause.Transformations.OfType <GroupByTransformationNode>().SingleOrDefault()) != null) { foreach (GroupByPropertyNode node in groupByNode.GroupingProperties) { if (node.Expression == null) { keys.AddRange(node.ChildTransformations.Select(n => (SingleValuePropertyAccessNode)n.Expression)); } else { keys.Add((SingleValuePropertyAccessNode)node.Expression); } } } else { ResourceRangeVariableReferenceNode source = OeEdmClrHelper.CreateRangeVariableReferenceNode(entitySet); foreach (IEdmStructuralProperty key in entitySet.EntityType().Key()) { keys.Add(new SingleValuePropertyAccessNode(source, key)); } } if (orderByClause == null) { return(keys); } for (; orderByClause != null; orderByClause = orderByClause.ThenBy) { if (orderByClause.Expression is SingleValuePropertyAccessNode propertyNode) { int i = keys.FindIndex(p => p.Property == propertyNode.Property); if (i >= 0) { keys.RemoveAt(i); } } } return(keys); }
private OeEntryFactory(IEdmEntitySetBase entitySet, OePropertyAccessor[] accessors) { _entitySet = entitySet; _accessors = accessors; _entityType = entitySet.EntityType(); _navigationLinks = Array.Empty <OeEntryFactory>(); _typeName = EntityType.FullName(); _odataProperties = new ODataProperty[accessors.Length]; for (int i = 0; i < accessors.Length; i++) { _odataProperties[i] = new ODataProperty() { Name = accessors[i].Name } } ; }
public static Uri ComputeId(Uri baseUri, IEdmEntitySetBase entitySet, ODataResource entry) { Uri uri = AppendSegment(baseUri, entitySet.Name, true); var builder = new StringBuilder(uri.IsAbsoluteUri ? uri.AbsoluteUri : uri.OriginalString); builder.Append('('); bool flag = true; IEnumerable <IEdmStructuralProperty> keyProperties = entitySet.EntityType().Key(); foreach (IEdmStructuralProperty keyProperty in keyProperties) { ODataProperty property = null; foreach (ODataProperty entryProperty in entry.Properties) { if (entryProperty.Name == keyProperty.Name) { property = entryProperty; break; } } if (flag) { flag = false; } else { builder.Append(','); } if (keyProperties.Count() > 1) { builder.Append(property.Name); builder.Append('='); } builder.Append(ODataUriUtils.ConvertToUriLiteral(property.Value, ODataVersion.V4)); } builder.Append(')'); return(new Uri(builder.ToString(), UriKind.Absolute)); }
public OeEntryFactory( IEdmEntitySetBase entitySet, OePropertyAccessor[] accessors, OePropertyAccessor[]?skipTokenAccessors) { Array.Sort(accessors, AccessorByNameComparer.Instance); EntitySet = entitySet; _allAccessors = accessors; Accessors = GetAccessorsWithoutSkiptoken(accessors); SkipTokenAccessors = skipTokenAccessors ?? Array.Empty <OePropertyAccessor>(); EdmEntityType = entitySet.EntityType(); NavigationLinks = Array.Empty <OeNavigationEntryFactory>(); _typeName = EdmEntityType.FullName(); if (accessors.Length != 0 && accessors[0].PropertyExpression is MemberExpression propertyExpression) { IsTuple = OeExpressionHelper.IsTupleType(propertyExpression.Expression !.Type); } }
public BatchReferenceSegment(string contentId, IEdmType edmType, IEdmEntitySetBase entitySet) { ExceptionUtils.CheckArgumentNotNull(edmType, "resultingType"); ExceptionUtils.CheckArgumentNotNull(contentId, "contentId"); if (!ODataPathParser.ContentIdRegex.IsMatch(contentId)) { throw new ODataException(ODataErrorStrings.BatchReferenceSegment_InvalidContentID(contentId)); } this.edmType = edmType; this.entitySet = entitySet; this.contentId = contentId; this.Identifier = this.ContentId; this.TargetEdmType = edmType; this.TargetEdmNavigationSource = this.EntitySet; this.SingleResult = true; this.TargetKind = RequestTargetKind.Resource; if (entitySet != null) { UriParserErrorHelper.ThrowIfTypesUnrelated(edmType, entitySet.EntityType(), "BatchReferenceSegments"); } }
private static List <MemberExpression> GetKeyExpressions(IEdmEntitySetBase entitySet, OePropertyAccessor[] accessors) { var propertyExpressions = new List <MemberExpression>(); foreach (IEdmStructuralProperty key in entitySet.EntityType().Key()) { bool found = false; foreach (OePropertyAccessor accessor in accessors) { if (String.CompareOrdinal(accessor.EdmProperty.Name, key.Name) == 0) { propertyExpressions.Add(accessor.PropertyExpression); found = true; break; } } if (!found) { throw new InvalidOperationException("Key property " + key.Name + " not found in accessors"); } } return(propertyExpressions); }
public static OePropertyAccessor[] CreateFromType(Type clrType, IEdmEntitySetBase entitySet) { ParameterExpression parameter = Expression.Parameter(typeof(Object)); UnaryExpression instance = Expression.Convert(parameter, clrType); var propertyAccessors = new List <OePropertyAccessor>(); foreach (IEdmStructuralProperty edmProperty in entitySet.EntityType().StructuralProperties()) { PropertyInfo propertyInfo = clrType.GetProperty(edmProperty.Name); if (propertyInfo == null) { if (!(edmProperty is OeEdmStructuralProperty)) { throw new InvalidOperationException("Property " + edmProperty.Name + " not found in clr type " + clrType.Name); } } else { MemberExpression expression = Expression.Property(instance, propertyInfo); propertyAccessors.Add(CreatePropertyAccessor(edmProperty, expression, parameter, false)); } } return(propertyAccessors.ToArray()); }
/// <summary> /// Selects the action for OData requests. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="controllerContext">The controller context.</param> /// <param name="actionMap">The action map.</param> /// <returns> /// <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected action /// </returns> public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw Error.ArgumentNull("odataPath"); } if (controllerContext == null) { throw Error.ArgumentNull("controllerContext"); } if (actionMap == null) { throw Error.ArgumentNull("actionMap"); } if (odataPath.PathTemplate == "~/entityset") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; HttpMethod httpMethod = controllerContext.Request.Method; if (httpMethod == HttpMethod.Get) { // e.g. Try GetCustomers first, then fall back to Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (httpMethod == HttpMethod.Post) { // e.g. Try PostCustomer first, then fall back to Post action name return(actionMap.FindMatchingAction( "Post" + entitySet.EntityType().Name, "Post")); } } else if (odataPath.PathTemplate == "~/entityset/$count" && controllerContext.Request.Method == HttpMethod.Get) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; // e.g. Try GetCustomers first, then fall back to Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (odataPath.PathTemplate == "~/entityset/cast") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; HttpMethod httpMethod = controllerContext.Request.Method; if (httpMethod == HttpMethod.Get) { // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionMap.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } else if (httpMethod == HttpMethod.Post) { // e.g. Try PostCustomerFromSpecialCustomer first, then fall back to PostFromSpecialCustomer return(actionMap.FindMatchingAction( "Post" + entitySet.EntityType().Name + "From" + entityType.Name, "PostFrom" + entityType.Name)); } } else if (odataPath.PathTemplate == "~/entityset/cast/$count" && controllerContext.Request.Method == HttpMethod.Get) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.Segments[1].EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionMap.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } return(null); }
private object ProcessPostBody(IODataRequestMessage message, IEdmEntitySetBase entitySet, object queryResults) { object lastNewInstance = null; using (var messageReader = new ODataMessageReader(message, this.GetReaderSettings(), this.DataSource.Model)) { var odataItemStack = new Stack<ODataItem>(); var entryReader = messageReader.CreateODataEntryReader(entitySet, entitySet.EntityType()); var currentTargetEntitySet = entitySet; while (entryReader.Read()) { switch (entryReader.State) { case ODataReaderState.EntryStart: odataItemStack.Push(entryReader.Item); break; case ODataReaderState.EntryEnd: { var entry = (ODataEntry)entryReader.Item; // TODO: the code here will be changed to handle following scenarios // 1: non-contained navigation, e.g. People(1)/Friends // 2. general entity set, e.g. People // 3. contained navigation, e.g. People(1)/Trips // 4. upsert, e.g. People(1)/Friends(2) var newInstance = this.DataSource.UpdateProvider.Create(entry.TypeName, queryResults); foreach (var property in entry.Properties) { if (Utility.IsETagProperty(newInstance, property.Name)) continue; this.DataSource.UpdateProvider.Update(newInstance, property.Name, property.Value); } var boundNavPropAnnotation = odataItemStack.Pop().GetAnnotation<BoundNavigationPropertyAnnotation>(); if (boundNavPropAnnotation != null) { foreach (var boundProperty in boundNavPropAnnotation.BoundProperties) { var isCollection = boundProperty.Item1.IsCollection == true; var propertyValue = isCollection ? boundProperty.Item2 : ((IEnumerable<object>)boundProperty.Item2).Single(); this.DataSource.UpdateProvider.Update(newInstance, boundProperty.Item1.Name, propertyValue); } } var parentItem = odataItemStack.Count > 0 ? odataItemStack.Peek() : null; if (parentItem != null) { // This new entry belongs to a navigation property and/or feed - // propagate it up the tree for further processing. AddChildInstanceAnnotation(parentItem, newInstance); } lastNewInstance = newInstance; } break; case ODataReaderState.FeedStart: odataItemStack.Push(entryReader.Item); break; case ODataReaderState.FeedEnd: { var childAnnotation = odataItemStack.Pop().GetAnnotation<ChildInstanceAnnotation>(); var parentNavLink = odataItemStack.Count > 0 ? odataItemStack.Peek() as ODataNavigationLink : null; if (parentNavLink != null) { // This feed belongs to a navigation property - // propagate it up the tree for further processing. AddChildInstanceAnnotation(parentNavLink, childAnnotation.ChildInstances ?? new object[0]); } } break; case ODataReaderState.NavigationLinkStart: { odataItemStack.Push(entryReader.Item); var navigationLink = (ODataNavigationLink)entryReader.Item; var navigationProperty = (IEdmNavigationProperty)currentTargetEntitySet.EntityType().FindProperty(navigationLink.Name); // Current model implementation doesn't expose associations otherwise this would be much cleaner. currentTargetEntitySet = this.DataSource.Model.EntityContainer.EntitySets().Single(s => s.EntityType() == navigationProperty.Type.Definition); } break; case ODataReaderState.NavigationLinkEnd: { var navigationLink = (ODataNavigationLink)entryReader.Item; var childAnnotation = odataItemStack.Pop().GetAnnotation<ChildInstanceAnnotation>(); if (childAnnotation != null) { // Propagate the bound entries to the parent entry. AddBoundNavigationPropertyAnnotation(odataItemStack.Peek(), navigationLink, childAnnotation.ChildInstances); } } break; } } } return lastNewInstance; }
private object ProcessPostBody(IODataRequestMessage message, IEdmEntitySetBase entitySet, object queryResults) { object lastNewInstance = null; using (var messageReader = new ODataMessageReader(message, this.GetReaderSettings(), this.DataSource.Model)) { var odataItemStack = new Stack <ODataItem>(); var entryReader = messageReader.CreateODataEntryReader(entitySet, entitySet.EntityType()); var currentTargetEntitySet = entitySet; while (entryReader.Read()) { switch (entryReader.State) { case ODataReaderState.EntryStart: odataItemStack.Push(entryReader.Item); break; case ODataReaderState.EntryEnd: { var entry = (ODataEntry)entryReader.Item; // TODO: the code here will be changed to handle following scenarios // 1: non-contained navigation, e.g. People(1)/Friends // 2. general entity set, e.g. People // 3. contained navigation, e.g. People(1)/Trips // 4. upsert, e.g. People(1)/Friends(2) var newInstance = this.DataSource.UpdateProvider.Create(entry.TypeName, queryResults); foreach (var property in entry.Properties) { if (Utility.IsETagProperty(newInstance, property.Name)) { continue; } this.DataSource.UpdateProvider.Update(newInstance, property.Name, property.Value); } var boundNavPropAnnotation = odataItemStack.Pop().GetAnnotation <BoundNavigationPropertyAnnotation>(); if (boundNavPropAnnotation != null) { foreach (var boundProperty in boundNavPropAnnotation.BoundProperties) { var isCollection = boundProperty.Item1.IsCollection == true; var propertyValue = isCollection ? boundProperty.Item2 : ((IEnumerable <object>)boundProperty.Item2).Single(); this.DataSource.UpdateProvider.Update(newInstance, boundProperty.Item1.Name, propertyValue); } } var parentItem = odataItemStack.Count > 0 ? odataItemStack.Peek() : null; if (parentItem != null) { // This new entry belongs to a navigation property and/or feed - // propagate it up the tree for further processing. AddChildInstanceAnnotation(parentItem, newInstance); } lastNewInstance = newInstance; } break; case ODataReaderState.FeedStart: odataItemStack.Push(entryReader.Item); break; case ODataReaderState.FeedEnd: { var childAnnotation = odataItemStack.Pop().GetAnnotation <ChildInstanceAnnotation>(); var parentNavLink = odataItemStack.Count > 0 ? odataItemStack.Peek() as ODataNavigationLink : null; if (parentNavLink != null) { // This feed belongs to a navigation property - // propagate it up the tree for further processing. AddChildInstanceAnnotation(parentNavLink, childAnnotation.ChildInstances ?? new object[0]); } } break; case ODataReaderState.NavigationLinkStart: { odataItemStack.Push(entryReader.Item); var navigationLink = (ODataNavigationLink)entryReader.Item; var navigationProperty = (IEdmNavigationProperty)currentTargetEntitySet.EntityType().FindProperty(navigationLink.Name); // Current model implementation doesn't expose associations otherwise this would be much cleaner. currentTargetEntitySet = this.DataSource.Model.EntityContainer.EntitySets().Single(s => s.EntityType() == navigationProperty.Type.Definition); } break; case ODataReaderState.NavigationLinkEnd: { var navigationLink = (ODataNavigationLink)entryReader.Item; var childAnnotation = odataItemStack.Pop().GetAnnotation <ChildInstanceAnnotation>(); if (childAnnotation != null) { // Propagate the bound entries to the parent entry. AddBoundNavigationPropertyAnnotation(odataItemStack.Peek(), navigationLink, childAnnotation.ChildInstances); } } break; } } } return(lastNewInstance); }
/// <inheritdoc/> public override ActionDescriptor SelectAction(RouteContext routeContext, IEnumerable <ControllerActionDescriptor> actionDescriptors) { if (routeContext == null) { throw Error.ArgumentNull("routeContext"); } ODataPath odataPath = routeContext.HttpContext.Request.ODataFeature().Path; HttpRequest request = routeContext.HttpContext.Request; string httpMethod = request.Method.ToUpperInvariant(); if (odataPath.PathTemplate == "~/entityset") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; if (httpMethod == ODataRouteConstants.HttpGet) { // e.g. Try GetCustomers first, then fall back to Get action name return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (httpMethod == ODataRouteConstants.HttpPost) { // e.g. Try PostCustomer first, then fall back to Post action name return(actionDescriptors.FindMatchingAction( "Post" + entitySet.EntityType().Name, "Post")); } } else if (odataPath.PathTemplate == "~/entityset/$count" && httpMethod == ODataRouteConstants.HttpGet) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; // e.g. Try GetCustomers first, then fall back to Get action name return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (odataPath.PathTemplate == "~/entityset/cast") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; if (httpMethod == ODataRouteConstants.HttpGet) { // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } else if (httpMethod == ODataRouteConstants.HttpPost) { // e.g. Try PostCustomerFromSpecialCustomer first, then fall back to PostFromSpecialCustomer return(actionDescriptors.FindMatchingAction( "Post" + entitySet.EntityType().Name + "From" + entityType.Name, "PostFrom" + entityType.Name)); } } else if (odataPath.PathTemplate == "~/entityset/cast/$count" && httpMethod == ODataRouteConstants.HttpGet) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.Segments[1].EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } return(null); }
private string SelectActionImpl(RouteContext routeContext, SelectControllerResult controllerResult, IEnumerable <ControllerActionDescriptor> actionDescriptors) { Microsoft.AspNet.OData.Routing.ODataPath odataPath = routeContext.HttpContext.ODataFeature().Path; HttpRequest request = routeContext.HttpContext.Request; if (odataPath.PathTemplate == "~/entityset") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; if (HttpMethods.IsGet(request.Method)) { // e.g. Try GetCustomers first, then fall back to Get action name return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (HttpMethods.IsPost(request.Method)) { // e.g. Try PostCustomer first, then fall back to Post action name return(actionDescriptors.FindMatchingAction( "Post" + entitySet.EntityType().Name, "Post")); } } else if (odataPath.PathTemplate == "~/entityset/key" || odataPath.PathTemplate == "~/entityset/key/cast") { string httpMethodName; if (HttpMethods.IsGet(request.Method)) { httpMethodName = "Get"; } else if (HttpMethods.IsPut(request.Method)) { httpMethodName = "Put"; } else if (HttpMethods.IsPatch(request.Method)) { httpMethodName = "Patch"; } else if (HttpMethods.IsDelete(request.Method)) { httpMethodName = "Delete"; } else { return(null); } Contract.Assert(httpMethodName != null); IEdmEntityType entityType = (IEdmEntityType)odataPath.EdmType; // e.g. Try GetCustomer first, then fallback on Get action name string actionName = actionDescriptors.FindMatchingAction( httpMethodName + entityType.Name, httpMethodName); if (actionName != null) { KeySegment keySegment = (KeySegment)odataPath.Segments[1]; // TODO: Add key/value to RouteData return(actionName); } } else if (odataPath.PathTemplate == "~/entityset/$count" && HttpMethods.IsGet(request.Method)) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; // e.g. Try GetCustomers first, then fall back to Get action name return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (odataPath.PathTemplate == "~/entityset/cast") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; if (HttpMethods.IsGet(request.Method)) { // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } else if (HttpMethods.IsPost(request.Method)) { // e.g. Try PostCustomerFromSpecialCustomer first, then fall back to PostFromSpecialCustomer return(actionDescriptors.FindMatchingAction( "Post" + entitySet.EntityType().Name + "From" + entityType.Name, "PostFrom" + entityType.Name)); } } else if (odataPath.PathTemplate == "~/entityset/cast/$count" && HttpMethods.IsGet(request.Method)) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.Segments[1].EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionDescriptors.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } return(null); }
/// <summary> /// Selects the action for OData requests. /// </summary> /// <param name="odataPath">The OData path.</param> /// <param name="controllerContext">The controller context.</param> /// <param name="actionMap">The action map.</param> /// <returns> /// <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected action /// </returns> internal static string SelectActionImpl(ODataPath odataPath, IWebApiControllerContext controllerContext, IWebApiActionMap actionMap) { if (odataPath.PathTemplate == "~/entityset") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; if (ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try GetCustomers first, then fall back to Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (ODataRequestMethod.Post == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try PostCustomer first, then fall back to Post action name return(actionMap.FindMatchingAction( "Post" + entitySet.EntityType().Name, "Post")); } } else if (odataPath.PathTemplate == "~/entityset/$count" && ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; // e.g. Try GetCustomers first, then fall back to Get action name return(actionMap.FindMatchingAction( "Get" + entitySet.Name, "Get")); } else if (odataPath.PathTemplate == "~/entityset/cast") { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; if (ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionMap.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } else if (ODataRequestMethod.Post == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { // e.g. Try PostCustomerFromSpecialCustomer first, then fall back to PostFromSpecialCustomer return(actionMap.FindMatchingAction( "Post" + entitySet.EntityType().Name + "From" + entityType.Name, "PostFrom" + entityType.Name)); } } else if (odataPath.PathTemplate == "~/entityset/cast/$count" && ODataRequestMethod.Get == controllerContext.Request.GetRequestMethodOrPreflightMethod()) { EntitySetSegment entitySetSegment = (EntitySetSegment)odataPath.Segments[0]; IEdmEntitySetBase entitySet = entitySetSegment.EntitySet; IEdmCollectionType collectionType = (IEdmCollectionType)odataPath.Segments[1].EdmType; IEdmEntityType entityType = (IEdmEntityType)collectionType.ElementType.Definition; // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer return(actionMap.FindMatchingAction( "Get" + entitySet.Name + "From" + entityType.Name, "GetFrom" + entityType.Name)); } return(null); }
private object ProcessPostBody(IODataRequestMessage message, IEdmEntitySetBase entitySet, object queryResults) { object lastNewInstance = null; using (var messageReader = new ODataMessageReader(message, this.GetReaderSettings())) { var odataItemStack = new Stack <ODataItem>(); var entityStack = new Stack <IEdmEntitySetBase>(); var entryReader = messageReader.CreateODataResourceReader(entitySet, entitySet.EntityType()); var currentTargetEntitySet = entitySet; while (entryReader.Read()) { switch (entryReader.State) { case ODataReaderState.ResourceStart: { var entry = (ODataResource)entryReader.Item; if (entry == null) { break; } odataItemStack.Push(entryReader.Item); entityStack.Push(currentTargetEntitySet); break; } case ODataReaderState.ResourceEnd: { var entry = (ODataResource)entryReader.Item; if (entry == null) { break; } // TODO: the code here will be changed to handle following scenarios // 1: non-contained navigation, e.g. People(1)/Friends // 2. general entity set, e.g. People // 3. contained navigation, e.g. People(1)/Trips // 4. complex property, e.g. Airports('KSFO')/Location // 5. upsert, e.g. People(1)/Friends(2) object newInstance; currentTargetEntitySet = entityStack.Pop(); if (currentTargetEntitySet == null) { // For entry var valueType = EdmClrTypeUtils.GetInstanceType(entry.TypeName); newInstance = Utility.QuickCreateInstance(valueType); } else { // For complex property newInstance = this.DataSource.UpdateProvider.Create(entry.TypeName, queryResults); } foreach (var property in entry.Properties) { if (Utility.IsETagProperty(newInstance, property.Name)) { continue; } this.DataSource.UpdateProvider.Update(newInstance, property.Name, property.Value); } var boundNavPropAnnotation = odataItemStack.Pop().GetAnnotation <BoundNavigationPropertyAnnotation>(); if (boundNavPropAnnotation != null) { foreach (var boundProperty in boundNavPropAnnotation.BoundProperties) { var isCollection = boundProperty.Item1.IsCollection == true; var propertyValue = isCollection ? boundProperty.Item2 : ((IEnumerable <object>)boundProperty.Item2).Single(); this.DataSource.UpdateProvider.Update(newInstance, boundProperty.Item1.Name, propertyValue); } } var parentItem = odataItemStack.Count > 0 ? odataItemStack.Peek() : null; if (parentItem != null) { // This new resource belongs to a navigation property and/or complex/complex collection property and/or feed - // propagate it up the tree for further processing. AddChildInstanceAnnotation(parentItem, newInstance); } lastNewInstance = newInstance; } break; case ODataReaderState.ResourceSetStart: odataItemStack.Push(entryReader.Item); break; case ODataReaderState.ResourceSetEnd: { var childAnnotation = odataItemStack.Pop().GetAnnotation <ChildInstanceAnnotation>(); var parentNavLink = odataItemStack.Count > 0 ? odataItemStack.Peek() as ODataNestedResourceInfo : null; if (parentNavLink != null) { // This feed belongs to a navigation property - // propagate it up the tree for further processing. AddChildInstanceAnnotations(parentNavLink, childAnnotation == null ? new object[0] : (childAnnotation.ChildInstances ?? new object[0])); } } break; case ODataReaderState.NestedResourceInfoStart: { odataItemStack.Push(entryReader.Item); var nestedResourceInfo = (ODataNestedResourceInfo)entryReader.Item; IEdmNavigationProperty navigationProperty = currentTargetEntitySet == null ? null : currentTargetEntitySet.EntityType().FindProperty(nestedResourceInfo.Name) as IEdmNavigationProperty; // Current model implementation doesn't expose associations otherwise this would be much cleaner. if (navigationProperty != null) { currentTargetEntitySet = this.DataSource.Model.EntityContainer.EntitySets().Single(s => s.EntityType() == navigationProperty.Type.Definition); } else { currentTargetEntitySet = null; } entityStack.Push(currentTargetEntitySet); } break; case ODataReaderState.NestedResourceInfoEnd: { var navigationLink = (ODataNestedResourceInfo)entryReader.Item; var childAnnotation = odataItemStack.Pop().GetAnnotation <ChildInstanceAnnotation>(); if (childAnnotation != null) { // Propagate the bound entries to the parent entry. AddBoundNavigationPropertyAnnotation(odataItemStack.Peek(), navigationLink, childAnnotation == null ? new object[0] : childAnnotation.ChildInstances); } entityStack.Pop(); currentTargetEntitySet = entityStack.Peek(); } break; } } } return(lastNewInstance); }