public IActionResult GetNavigation(Guid key, string navigation) { ODataPath path = Request.ODataFeature().Path; if (path.PathTemplate != "~/entityset/key/navigation") { return(BadRequest("Not the correct navigation property access request!")); } if (!(path.Segments.Last() is NavigationPropertySegment property)) { return(BadRequest("Not the correct navigation property access request!")); } T model = _service.Get(c => c.Id == key).First(); if (model == null) { return(BadRequest("Not find the model!")); } PropertyInfo info = typeof(T).GetProperty(navigation); object value = info.GetValue(model); return(Ok(value)); }
public override string SelectAction(Microsoft.AspNet.OData.Routing.ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null || controllerContext == null || actionMap == null) { return(null); } if (odataPath.PathTemplate != "~/entityset/key/navigation" && odataPath.PathTemplate != "~/entityset/key/cast/navigation") { return(base.SelectAction(odataPath, controllerContext, actionMap)); } if (!controllerContext.ControllerDescriptor.ControllerType.IsSubclassOfRawGeneric(typeof(GenericDataController <>))) { return(base.SelectAction(odataPath, controllerContext, actionMap)); } var segment = odataPath.Segments[odataPath.Segments.Count - 1] as NavigationPropertySegment; if (segment != null) { if (odataPath.PathTemplate.StartsWith("~/entityset/key", StringComparison.Ordinal)) { KeySegment keyValueSegment = odataPath.Segments[1] as KeySegment; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.GenerateKey(); } } return(null); }
/// <summary> /// Selects the appropriate action based on the parsed OData URI. /// </summary> /// <param name="odataPath">Parsed OData URI</param> /// <param name="controllerContext">Context for HttpController</param> /// <param name="actionMap">Mapping from action names to HttpActions</param> /// <returns>String corresponding to controller action name</returns> public string SelectAction( ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { // TODO GitHubIssue#44 : implement action selection for $ref, navigation scenarios, etc. Ensure.NotNull(odataPath, "odataPath"); Ensure.NotNull(controllerContext, "controllerContext"); Ensure.NotNull(actionMap, "actionMap"); if (!(controllerContext.Controller is RestierController)) { // RESTier cannot select action on controller which is not RestierController. return null; } HttpMethod method = controllerContext.Request.Method; if (method == HttpMethod.Get && !IsMetadataPath(odataPath)) { return MethodNameOfGet; } ODataPathSegment lastSegment = odataPath.Segments.LastOrDefault(); if (lastSegment != null && lastSegment.SegmentKind == ODataSegmentKinds.UnboundAction) { return MethodNameOfPostAction; } // Let WebAPI select default action return null; }
public void GenerateLocationHeader_UsesEntitySetLinkBuilder_ToGenerateLocationHeader() { // Arrange Uri editLink = new Uri("http://id-link"); Mock <NavigationSourceLinkBuilderAnnotation> linkBuilder = new Mock <NavigationSourceLinkBuilderAnnotation>(); linkBuilder.CallBase = true; linkBuilder.Setup( b => b.BuildEditLink(It.IsAny <ResourceContext>(), ODataMetadataLevel.FullMetadata, null)) .Returns(editLink); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); var request = RequestFactory.CreateFromModel(model.Model, path: path); var createdODataResult = GetCreatedODataResult <TestEntity>(_entity, request); // Act var locationHeader = createdODataResult.GenerateLocationHeader(request); // Assert Assert.Same(editLink, locationHeader); }
public void Property_EntityIdHeader_IsEvaluatedLazilyAndOnlyOnce() { // Arrange Uri idLink = new Uri("http://id-link"); Mock <NavigationSourceLinkBuilderAnnotation> linkBuilder = new Mock <NavigationSourceLinkBuilderAnnotation>(); linkBuilder.CallBase = true; linkBuilder.Setup(b => b.BuildIdLink(It.IsAny <ResourceContext>(), ODataMetadataLevel.FullMetadata)) .Returns(idLink); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); var request = RequestFactory.CreateFromModel(model.Model, path: path); TestController controller = CreateController(request); var createdODataResult = GetCreatedODataResult <TestEntity>(_entity, request, controller); // Act Uri entityIdHeader = createdODataResult.GenerateEntityId(request); // Assert Assert.Same(idLink, entityIdHeader); linkBuilder.Verify( b => b.BuildIdLink(It.IsAny <ResourceContext>(), ODataMetadataLevel.FullMetadata), Times.Once()); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null || controllerContext == null || actionMap == null) { return(null); } if (controllerContext.Request.Method != HttpMethod.Put) { return(null); } if (odataPath.PathTemplate != "~/entityset/key/navigation") { return(null); } KeySegment keySegment = odataPath.Segments[1] as KeySegment; controllerContext.RouteData.Values[ODataRouteConstants.Key] = keySegment.Keys.First().Value; NavigationPropertySegment navSegment = odataPath.Segments[2] as NavigationPropertySegment; return("PutTo" + navSegment.NavigationProperty.Name); }
public void SelectAction_SetsRelatedKey_ForDeleteRefRequests() { // Arrange var keys = new[] { new KeyValuePair <string, object>("ID", 42) }; var relatedKeys = new[] { new KeyValuePair <string, object>("ID", 24) }; CustomersModelWithInheritance model = new CustomersModelWithInheritance(); var specialOrdersProperty = model.SpecialCustomer.FindProperty("SpecialOrders") as IEdmNavigationProperty; ODataPath odataPath = new ODataPath( new EntitySetSegment(model.Customers), new KeySegment(keys, model.Customer, model.Customers), new TypeSegment(model.SpecialCustomer, model.Customers), new NavigationPropertyLinkSegment(specialOrdersProperty, model.Orders), new KeySegment(relatedKeys, model.Order, model.Orders)); var request = RequestFactory.Create(HttpMethod.Delete, "http://localhost/"); var actionMap = SelectActionHelper.CreateActionMap("DeleteRef"); // Act string selectedAction = SelectActionHelper.SelectAction(new RefRoutingConvention(), odataPath, request, actionMap); // Assert Assert.Equal(42, SelectActionHelper.GetRouteData(request).Values["key"]); Assert.Equal("SpecialOrders", SelectActionHelper.GetRouteData(request).Values["navigationProperty"]); Assert.Equal(24, SelectActionHelper.GetRouteData(request).Values["relatedKey"]); }
public void SelectAction_Returns_ExpectedMethodOnDerivedType(string method, string[] methodsInController, string expectedSelectedAction) { // Arrange var keys = new[] { new KeyValuePair <string, object>("ID", 42) }; CustomersModelWithInheritance model = new CustomersModelWithInheritance(); var specialOrdersProperty = model.SpecialCustomer.FindProperty("SpecialOrders") as IEdmNavigationProperty; ODataPath odataPath = new ODataPath( new EntitySetSegment(model.Customers), new KeySegment(keys, model.Customer, model.Customers), new TypeSegment(model.SpecialCustomer, model.Customers), new NavigationPropertyLinkSegment(specialOrdersProperty, model.Orders)); var request = RequestFactory.Create(new HttpMethod(method), "http://localhost/"); var actionMap = SelectActionHelper.CreateActionMap(methodsInController); // Act string selectedAction = SelectActionHelper.SelectAction(new RefRoutingConvention(), odataPath, request, actionMap); // Assert Assert.Equal(expectedSelectedAction, selectedAction); if (expectedSelectedAction == null) { Assert.Empty(SelectActionHelper.GetRouteData(request).Values); } else { Assert.Equal(2, SelectActionHelper.GetRouteData(request).Values.Count); Assert.Equal(42, SelectActionHelper.GetRouteData(request).Values["key"]); Assert.Equal(specialOrdersProperty.Name, SelectActionHelper.GetRouteData(request).Values["navigationProperty"]); } }
/// <summary> /// Converts an instance of <see cref="ODataPath" /> into an OData link. /// </summary> /// <param name="path">The OData path to convert into a link.</param> /// <returns> /// The generated OData link. /// </returns> public virtual string Link(ODataPath path) { if (path == null) { throw Error.ArgumentNull("path"); } return path.ToString(); }
public string SelectController(ODataPath odataPath, HttpRequestMessage request) { if (odataPath != null && odataPath.PathTemplate == "~/$swagger") { return("Swagger"); } return(null); }
public string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath != null && odataPath.PathTemplate == "~/$swagger") { return("GetSwagger"); } return(null); }
public void GenerateLocationHeader_ThrowsEntitySetMissingDuringSerialization_IfODataPathEntitySetIsNull() { // Arrange ODataPath path = new ODataPath(); var request = RequestFactory.CreateFromModel(EdmCoreModel.Instance, path: path); var createdODataResult = GetCreatedODataResult <TestEntity>(_entity, request); // Act & Assert ExceptionAssert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(request), "The related entity set or singleton cannot be found from the OData path. The related entity set or singleton is required to serialize the payload."); }
public void SelectController_ThrowsArgmentNull_IfMissRequest() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataPath odataPath = new ODataPath(new EntitySetSegment(model.Customers)); // Act & Assert ExceptionAssert.ThrowsArgumentNull( () => new MockNavigationSourceRoutingConvention().SelectController(odataPath, null), "request"); }
public static Result ApplyODataQuery(this DataTable sourceData, HttpRequestMessage request, Tuple <IEdmModel, IEdmType> datasourceEdmProperties = null) { Tuple <IEdmModel, IEdmType> SourceModel = datasourceEdmProperties ?? sourceData.BuildEdmModel(); Routing.ODataPath Path = request.ODataProperties().Path; ODataQueryContext SourceContext = new ODataQueryContext(SourceModel.Item1, SourceModel.Item2, Path); ODataQueryOptions Query = new ODataQueryOptions(SourceContext, request); return(sourceData.Apply(Query)); }
public void SelectAction_ThrowsArgumentNull_IfMissActionMap() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataPath odataPath = new ODataPath(new SingletonSegment(model.VipCustomer)); Mock <HttpControllerContext> controllerContext = new Mock <HttpControllerContext>(); // Act & Assert ExceptionAssert.ThrowsArgumentNull( () => new SingletonRoutingConvention().SelectAction(odataPath, controllerContext.Object, null), "actionMap"); }
public void GenerateLocationHeader_ThrowsEntityTypeNotInModel_IfContentTypeIsNotThereInModel() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); var request = RequestFactory.CreateFromModel(model.Model, path: path); var createdODataResult = GetCreatedODataResult <TestEntity>(_entity, request); // Act & Assert ExceptionAssert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(request), "Cannot find the resource type 'Microsoft.AspNet.OData.Test.Results.CreatedODataResultTest+TestEntity' in the model."); }
public void SelectAction_ThrowsArgumentNull_IfMissControllerContext() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataPath odataPath = new ODataPath(new SingletonSegment(model.VipCustomer)); ILookup <string, HttpActionDescriptor> emptyMap = new HttpActionDescriptor[0].ToLookup(desc => (string)null); // Act & Assert ExceptionAssert.ThrowsArgumentNull( () => new SingletonRoutingConvention().SelectAction(odataPath, null, emptyMap), "controllerContext"); }
private static IEnumerable <KeyValuePair <string, object> > GetKeys(DefaultODataPathHandler pathHandler, string serviceRoot, Uri uri, IServiceProvider requestContainer) { ODataPath odataPath = pathHandler.Parse(serviceRoot, uri.ToString(), requestContainer); KeySegment segment = odataPath.Segments.OfType <KeySegment>().Last(); if (segment == null) { throw Error.InvalidOperation(SRResources.EntityReferenceMustHasKeySegment, uri); } return(segment.Keys); }
public ITestActionResult HandleUnmappedRequest(ODataPath odataPath) { var functionSegment = odataPath.Segments.ElementAt(1) as OperationSegment; if (functionSegment != null) { return(Ok(functionSegment.GetParameterValue("productName") as string)); } else { return(BadRequest()); } }
public void GenerateLocationHeader_ThrowsTypeMustBeEntity_IfMappingTypeIsNotEntity() { CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); var request = RequestFactory.CreateFromModel(model.Model, path: path); model.Model.SetAnnotationValue(model.Address, new ClrTypeAnnotation(typeof(TestEntity))); var createdODataResult = GetCreatedODataResult <TestEntity>(_entity, request); // Act & Assert ExceptionAssert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(request), "NS.Address is not an entity type. Only entity types are supported."); }
public void SelectAction_ReturnsNull_NotSupportedMethodForDollarCount(string method) { // Arrange var model = new CustomersModelWithInheritance(); var odataPath = new ODataPath(new EntitySetSegment(model.Customers), CountSegment.Instance); var request = RequestFactory.Create(new HttpMethod(method), "http://localhost/"); var actionMap = SelectActionHelper.CreateActionMap("PostCustomer"); // Act string selectedAction = SelectActionHelper.SelectAction(new EntitySetRoutingConvention(), odataPath, request, actionMap); // Assert Assert.Null(selectedAction); }
/// <inheritdoc/> protected override string SelectAction(string requestMethod, ODataPath odataPath, TestControllerContext controllerContext, IList <string> actionList) { if (odataPath.PathTemplate == "~/entityset/key/navigation/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/$ref" || odataPath.PathTemplate == "~/entityset/key/navigation/key/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/key/$ref") { var actionName = string.Empty; if ((requestMethod == "POST") || (requestMethod == "PUT")) { actionName += "CreateRefTo"; } else if (requestMethod == "DELETE") { actionName += "DeleteRefTo"; } else { return(null); } var navigationSegment = odataPath.Segments.OfType <NavigationPropertyLinkSegment>().Last(); actionName += navigationSegment.NavigationProperty.Name; var castSegment = odataPath.Segments[2] as TypeSegment; if (castSegment != null) { IEdmType elementType = castSegment.EdmType; if (castSegment.EdmType.TypeKind == EdmTypeKind.Collection) { elementType = ((IEdmCollectionType)castSegment.EdmType).ElementType.Definition; } var actionCastName = string.Format("{0}On{1}", actionName, ((IEdmEntityType)elementType).Name); if (actionList.Contains(actionCastName)) { AddLinkInfoToRouteData(controllerContext, odataPath); return(actionCastName); } } if (actionList.Contains(actionName)) { AddLinkInfoToRouteData(controllerContext, odataPath); return(actionName); } } return(null); }
public void SwaggerPathHandlerWorksForSwaggerMetadataUri(string swaggerMetadataUri) { SwaggerPathHandler handler = new SwaggerPathHandler(); IEdmModel model = new EdmModel(); ODataPath path = handler.Parse(model, "http://any", swaggerMetadataUri); ODataPathSegment segment = path.Segments.Last(); Assert.NotNull(path); Assert.Null(path.NavigationSource); Assert.Null(path.EdmType); Assert.Equal("$swagger", segment.ToString()); Assert.IsType <SwaggerPathSegment>(segment); }
public void SelectController_RetrunsNull_IfNotNavigationSourceRequest() { // Arrange var request = RequestFactory.Create(); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); var ordersProperty = model.Customer.FindProperty("Orders") as IEdmNavigationProperty; NavigationPropertyLinkSegment navigationLinkSegment = new NavigationPropertyLinkSegment(ordersProperty, model.Orders); ODataPath odataPath = new ODataPath(navigationLinkSegment); // Act string controller = SelectController(new MockNavigationSourceRoutingConvention(), odataPath, request); // Assert Assert.Null(controller); }
public void GenerateODataLink_ThrowsIdLinkNullForEntityIdHeader_IfEntitySetLinkBuilderReturnsNull() { // Arrange var linkBuilder = new Mock <NavigationSourceLinkBuilderAnnotation>(); var model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); var path = new ODataPath(new EntitySetSegment(model.Customers)); var request = RequestFactory.CreateFromModel(model.Model, path: path); // Act & Assert ExceptionAssert.Throws <InvalidOperationException>( () => ResultHelpers.GenerateODataLink(request, _entity, isEntityId: true), "The Id link builder for the entity set 'Customers' returned null. An Id link is required for the OData-EntityId header."); }
/// <summary> /// Constructs an instance of <see cref="ODataQueryContext"/> with <see cref="IEdmModel" />, element EDM type, /// and <see cref="ODataPath" />. /// </summary> /// <param name="model">The EDM model the given EDM type belongs to.</param> /// <param name="elementType">The EDM type of the element of the collection being queried.</param> /// <param name="path">The parsed <see cref="ODataPath"/>.</param> public ODataQueryContext(IEdmModel model, IEdmType elementType, ODataPath path) { if (model == null) { throw Error.ArgumentNull("model"); } if (elementType == null) { throw Error.ArgumentNull("elementType"); } Model = model; ElementType = elementType; Path = path; NavigationSource = GetNavigationSource(Model, ElementType, path); }
public RestierQueryBuilder(IApi api, ODataPath path) { Ensure.NotNull(api, "api"); Ensure.NotNull(path, "path"); this.api = api; this.path = path; this.handlers[ODataSegmentKinds.EntitySet] = this.HandleEntitySetPathSegment; this.handlers[ODataSegmentKinds.Singleton] = this.HandleSingletonPathSegment; this.handlers[ODataSegmentKinds.UnboundFunction] = this.HandleUnboundFunctionPathSegment; this.handlers[ODataSegmentKinds.Count] = this.HandleCountPathSegment; this.handlers[ODataSegmentKinds.Value] = this.HandleValuePathSegment; this.handlers[ODataSegmentKinds.Key] = this.HandleKeyValuePathSegment; this.handlers[ODataSegmentKinds.Navigation] = this.HandleNavigationPathSegment; this.handlers[ODataSegmentKinds.Property] = this.HandlePropertyAccessPathSegment; }
internal static ODataDeserializerContext BuildDeserializerContext(HttpActionContext actionContext, ModelBindingContext bindingContext, IEdmTypeReference edmTypeReference) { HttpRequestMessage request = actionContext.Request; ODataPath path = request.ODataProperties().Path; IEdmModel edmModel = request.GetModel(); return(new ODataDeserializerContext { Path = path, Model = edmModel, Request = request, ResourceType = bindingContext.ModelType, ResourceEdmType = edmTypeReference, }); }
internal static IReadOnlyDictionary<string, object> GetPathKeyValues(ODataPath path) { if (path.PathTemplate == "~/entityset/key" || path.PathTemplate == "~/entityset/key/cast") { KeyValuePathSegment keySegment = (KeyValuePathSegment)path.Segments[1]; return GetPathKeyValues(keySegment, (IEdmEntityType)path.EdmType); } else { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, Resources.InvalidPathTemplateInRequest, "~/entityset/key")); } }
public void GetODataPayloadSerializer_ReturnsRawValueSerializer_ForValueRequests(Type type, EdmPrimitiveTypeKind edmPrimitiveTypeKind) { // Arrange ODataPath odataPath = new ODataPath(new ValueSegment(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32))); var request = RequestFactory.CreateFromModel(_edmModel); request.ODataContext().Path = odataPath; // Act var serializer = _serializerProvider.GetODataPayloadSerializer(type, request); // Assert Assert.NotEqual(EdmPrimitiveTypeKind.None, edmPrimitiveTypeKind); Assert.NotNull(serializer); Assert.Equal(ODataPayloadKind.Value, serializer.ODataPayloadKind); }
public void GenerateLocationHeader_ThrowsEditLinkNullForLocationHeader_IfEntitySetLinkBuilderReturnsNull() { // Arrange Mock <NavigationSourceLinkBuilderAnnotation> linkBuilder = new Mock <NavigationSourceLinkBuilderAnnotation>(); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); var request = RequestFactory.CreateFromModel(model.Model, path: path); var createdODataResult = GetCreatedODataResult <TestEntity>(_entity, request); // Act ExceptionAssert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(request), "The edit link builder for the entity set 'Customers' returned null. An edit link is required for the location header."); }
/// <summary> /// Matches the current template with an OData path. /// </summary> /// <param name="path">The OData path to be matched against.</param> /// <param name="values">The dictionary of matches to be updated in case of a match.</param> /// <returns><c>true</c> in case of a match; otherwise, <c>false</c>.</returns> public bool TryMatch(ODataPath path, IDictionary<string, object> values) { if (path.Segments.Count != Segments.Count) { return false; } for (int index = 0; index < Segments.Count; index++) { if (!Segments[index].TryMatch(path.Segments[index], values)) { return false; } } return true; }
public void GetResponseStatusCode_ReturnsNoContentForProperties_AndNotFoundForEntities(string odataPath, HttpStatusCode?expected) { // Arrange IEdmModel model = BuildModel(); IODataPathHandler pathHandler = new DefaultODataPathHandler(); ODataPath path = pathHandler.Parse(model, "http://localhost/any", odataPath); // Guard Assert.NotNull(path); // Act HttpStatusCode?statusCode = ODataNullValueMessageHandler.GetUpdatedResponseStatusCodeOrNull(path); // Assert Assert.Equal(expected, statusCode); }
public void GetODataPayloadSerializer_ReturnsRawValueSerializer_ForEnumValueRequests() { // Arrange ODataPath odataPath = new ODataPath(new ValueSegment(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32))); var request = RequestFactory.CreateFromModel(GetEnumModel()); request.ODataContext().Path = odataPath; // Act var serializer = _serializerProvider.GetODataPayloadSerializer(typeof(TestEnum), request); // Assert Assert.NotNull(serializer); var rawValueSerializer = Assert.IsType <ODataRawValueSerializer>(serializer); Assert.Equal(ODataPayloadKind.Value, rawValueSerializer.ODataPayloadKind); }
public void SelectAction_OnSingletonPath_Returns_ExpectedMethodOnBaseType(string method, string[] methodsInController, string expectedSelectedAction) { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); var ordersProperty = model.Customer.FindProperty("Orders") as IEdmNavigationProperty; ODataPath odataPath = new ODataPath(new SingletonSegment(model.VipCustomer), new NavigationPropertySegment(ordersProperty, model.Orders)); var request = RequestFactory.Create(new HttpMethod(method), "http://localhost/"); var actionMap = SelectActionHelper.CreateActionMap(methodsInController); // Act string selectedAction = SelectActionHelper.SelectAction(new NavigationRoutingConvention(), odataPath, request, actionMap); // Assert Assert.Equal(expectedSelectedAction, selectedAction); Assert.Empty(SelectActionHelper.GetRouteData(request).Values); }
public IEnumerable <ControllerActionDescriptor> SelectAction(RouteContext routeContext) { ODataPath odataPath = routeContext.HttpContext.Request.ODataFeature().Path; if (odataPath != null && odataPath.PathTemplate == "~/$swagger") { IActionDescriptorCollectionProvider actionCollectionProvider = routeContext.HttpContext.RequestServices.GetRequiredService <IActionDescriptorCollectionProvider>(); IEnumerable <ControllerActionDescriptor> actionDescriptors = actionCollectionProvider .ActionDescriptors.Items.OfType <ControllerActionDescriptor>() .Where(c => c.ControllerName == "Swagger"); return(actionDescriptors.Where( c => String.Equals(c.ActionName, "GetSwagger", StringComparison.OrdinalIgnoreCase))); } return(null); }
/// <summary> /// Selects OData controller based on parsed OData URI /// </summary> /// <param name="odataPath">Parsed OData URI</param> /// <param name="request">Incoming HttpRequest</param> /// <returns>Prefix for controller name</returns> public string SelectController(ODataPath odataPath, HttpRequestMessage request) { Ensure.NotNull(odataPath, "odataPath"); Ensure.NotNull(request, "request"); if (IsMetadataPath(odataPath)) { return null; } // If user has defined something like PeopleController for the entity set People, // we should let the request being routed to that controller. if (HasControllerForEntitySetOrSingleton(odataPath, request)) { // Fallback to routing conventions defined by OData Web API. return null; } request.SetApiFactory(apiFactory); return RestierControllerName; }
/// <summary> /// Constructs an instance of <see cref="ODataQueryContext"/> with <see cref="IEdmModel" />, element CLR type, /// and <see cref="ODataPath" />. /// </summary> /// <param name="model">The EdmModel that includes the <see cref="IEdmType"/> corresponding to /// the given <paramref name="elementClrType"/>.</param> /// <param name="elementClrType">The CLR type of the element of the collection being queried.</param> /// <param name="path">The parsed <see cref="ODataPath"/>.</param> public ODataQueryContext(IEdmModel model, Type elementClrType, ODataPath path) { if (model == null) { throw Error.ArgumentNull("model"); } if (elementClrType == null) { throw Error.ArgumentNull("elementClrType"); } ElementType = model.GetEdmType(elementClrType); if (ElementType == null) { throw Error.Argument("elementClrType", SRResources.ClrTypeNotInModel, elementClrType.FullName); } ElementClrType = elementClrType; Model = model; Path = path; NavigationSource = GetNavigationSource(Model, ElementType, path); }
private static bool IsMetadataPath(ODataPath odataPath) { return odataPath.PathTemplate == "~" || odataPath.PathTemplate == "~/$metadata"; }
private static void CheckNavigableProperty(ODataPath path, IEdmModel model) { Contract.Assert(path != null); Contract.Assert(model != null); foreach (ODataPathSegment segment in path.Segments) { NavigationPathSegment navigationPathSegment = segment as NavigationPathSegment; if (navigationPathSegment != null) { if (EdmLibHelpers.IsNotNavigable(navigationPathSegment.NavigationProperty, model)) { throw new ODataException(Error.Format( SRResources.NotNavigablePropertyUsedInNavigation, navigationPathSegment.NavigationProperty.Name)); } } } }
private static ODataPathTemplate Templatify(ODataPath path, string pathTemplate) { if (path == null) { throw new ODataException(Error.Format(SRResources.InvalidODataPathTemplate, pathTemplate)); } List<ODataPathSegmentTemplate> templateSegments = new List<ODataPathSegmentTemplate>(); foreach (ODataPathSegment pathSegment in path.Segments) { switch (pathSegment.SegmentKind) { case ODataSegmentKinds._Unresolved: throw new ODataException( Error.Format(SRResources.UnresolvedPathSegmentInTemplate, pathSegment.ToString(), pathTemplate)); case ODataSegmentKinds._Key: templateSegments.Add(new KeyValuePathSegmentTemplate((KeyValuePathSegment)pathSegment)); break; case ODataSegmentKinds._Function: templateSegments.Add(new BoundFunctionPathSegmentTemplate((BoundFunctionPathSegment)pathSegment)); break; case ODataSegmentKinds._UnboundFunction: templateSegments.Add(new UnboundFunctionPathSegmentTemplate((UnboundFunctionPathSegment)pathSegment)); break; case ODataSegmentKinds._DynamicProperty: templateSegments.Add(new DynamicPropertyPathSegmentTemplate((DynamicPropertyPathSegment)pathSegment)); break; default: templateSegments.Add(pathSegment); break; } } return new ODataPathTemplate(templateSegments); }
private static bool HasControllerForEntitySetOrSingleton( ODataPath odataPath, HttpRequestMessage request) { string controllerName = null; ODataPathSegment firstSegment = odataPath.Segments.FirstOrDefault(); if (firstSegment != null) { var entitySetSegment = firstSegment as EntitySetPathSegment; if (entitySetSegment != null) { controllerName = entitySetSegment.EntitySetName; } else { var singletonSegment = firstSegment as SingletonPathSegment; if (singletonSegment != null) { controllerName = singletonSegment.SingletonName; } } } if (controllerName != null) { IDictionary<string, HttpControllerDescriptor> controllers = request.GetConfiguration().Services.GetHttpControllerSelector().GetControllerMapping(); HttpControllerDescriptor descriptor; if (controllers.TryGetValue(controllerName, out descriptor) && descriptor != null) { return true; } } return false; }
private static IEdmNavigationSource GetNavigationSource(IEdmModel model, IEdmType elementType, ODataPath odataPath) { Contract.Assert(model != null); Contract.Assert(elementType != null); IEdmNavigationSource navigationSource = (odataPath != null) ? odataPath.NavigationSource : null; if (navigationSource != null) { return navigationSource; } IEdmEntityContainer entityContainer = model.EntityContainer; if (entityContainer == null) { return null; } List<IEdmEntitySet> matchedNavigationSources = entityContainer.EntitySets().Where(e => e.EntityType() == elementType).ToList(); return (matchedNavigationSources.Count != 1) ? null : matchedNavigationSources[0]; }
private static string GetRootElementName(ODataPath path) { if (path != null) { ODataPathSegment lastSegment = path.Segments.LastOrDefault(); if (lastSegment != null) { BoundActionPathSegment actionSegment = lastSegment as BoundActionPathSegment; if (actionSegment != null) { return actionSegment.Action.Name; } PropertyAccessPathSegment propertyAccessSegment = lastSegment as PropertyAccessPathSegment; if (propertyAccessSegment != null) { return propertyAccessSegment.Property.Name; } } } return null; }
// This function is used to determine whether an OData path includes operation (import) path segments. // We use this function to make sure the value of ODataUri.Path in ODataMessageWriterSettings is null // when any path segment is an operation. ODL will try to calculate the context URL if the ODataUri.Path // equals to null. private static bool IsOperationPath(ODataPath path) { if (path == null) { return false; } foreach (ODataPathSegment segment in path.Segments) { switch (segment.SegmentKind) { case ODataSegmentKinds._Action: case ODataSegmentKinds._Function: case ODataSegmentKinds._UnboundAction: case ODataSegmentKinds._UnboundFunction: return true; } } return false; }