public void AppliesToActionWithLongTemplateWorksAsExpected() { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <WithoutPrefixController>("LongAction"); ActionModel action = controller.Actions.First(); SelectorModel selectorModel = Assert.Single(action.Selectors); // Guard Assert.Equal("Customers({key})/Orders({relatedKey})/NS.MyOrder/Title", selectorModel.AttributeRouteModel.Template); Assert.DoesNotContain(selectorModel.EndpointMetadata, a => a is ODataRoutingMetadata); ODataControllerActionContext context = new ODataControllerActionContext(string.Empty, _edmModel, controller) { Action = action, Options = _options, }; // Act bool ok = _attributeConvention.AppliesToAction(context); Assert.False(ok); // Assert SelectorModel actualSelectorModel = Assert.Single(action.Selectors); Assert.Equal("/Customers({key})/Orders({relatedKey})/NS.MyOrder/Title", actualSelectorModel.AttributeRouteModel.Template); Assert.Contains(actualSelectorModel.EndpointMetadata, a => a is ODataRoutingMetadata); }
public void AppliesToControllerWithLongTemplateWorksAsExpected() { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <WithoutPrefixController>("LongAction"); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = new ODataControllerActionContext(string.Empty, EdmModel, controller); AttributeRoutingConvention attributeConvention = CreateConvention(); // Act bool ok = attributeConvention.AppliesToController(context); Assert.False(ok); // Assert Assert.Equal(4, action.Selectors.Count); Assert.Equal(new[] { "/Customers({key})/Orders({relatedKey})/NS.MyOrder/Title", "/Customers({key})/Orders/{relatedKey}/NS.MyOrder/Title", "/Customers/{key}/Orders({relatedKey})/NS.MyOrder/Title", "/Customers/{key}/Orders/{relatedKey}/NS.MyOrder/Title" }, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
public bool AppliesToAction(ODataControllerActionContext context) { if (context.Action.ActionName == "Get") { var entitySet = context.Model.EntityContainer.FindEntitySet("Order Details"); var route = new EntitySetSegmentTemplate(entitySet); var parameters = context.Action.ActionMethod.GetParameters(); if (parameters.Length == 0) { var path = new ODataPathTemplate(route); context.Action.AddSelector("get", context.Prefix, context.Model, path, context.Options.RouteOptions); return(true); } if (parameters.Length == 2 && parameters[0].Name == "keyOrderId" && parameters[1].Name == "keyProductId") { var keys = new Dictionary <string, string> { { "OrderID", "{keyOrderId}" }, { "ProductID", "{keyProductId}" } }; var keyTemplate = new KeySegmentTemplate(keys, entitySet.EntityType(), entitySet); var path = new ODataPathTemplate(route, keyTemplate); context.Action.AddSelector("get", context.Prefix, context.Model, path, context.Options.RouteOptions); return(true); } } return(false); }
public void CtorODataControllerActionContext_SetProperties() { // Arrange & Act string prefix = "odata"; IEdmModel model = new Mock <IEdmModel>().Object; EdmEntityContainer container = new EdmEntityContainer("NS", "Default"); EdmEntityType entityType = new EdmEntityType("NS", "Entity"); IEdmSingleton singleton = container.AddSingleton("Me", entityType); ControllerModel controller = new ControllerModel(typeof(TestController).GetTypeInfo(), new List <object>()); ODataControllerActionContext context = new ODataControllerActionContext(prefix, model, controller) { NavigationSource = singleton }; // Assert Assert.Equal(prefix, context.Prefix); Assert.Same(model, context.Model); Assert.Same(controller, context.Controller); Assert.Null(context.EntitySet); Assert.Same(singleton, context.Singleton); Assert.Same(singleton, context.NavigationSource); Assert.Same(entityType, context.EntityType); Assert.NotNull(context.Options); }
public void AppliesToActionForBasicEntityActionWorksAsExpected(string actionName) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <CustomersController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = action; EntityRoutingConvention entityConvention = ConventionHelpers.CreateConvention <EntityRoutingConvention>(); // Act bool returnValue = entityConvention.AppliesToAction(context); Assert.True(returnValue); // Assert Assert.Equal(2, action.Selectors.Count); Assert.Collection(action.Selectors, e => { Assert.Equal("/Customers(FirstName={keyFirstName},LastName={keyLastName})", e.AttributeRouteModel.Template); }, e => { Assert.Equal("/Customers/FirstName={keyFirstName},LastName={keyLastName}", e.AttributeRouteModel.Template); }); }
public static ODataControllerActionContext BuildContext(string modelPrefix, IEdmModel model, ControllerModel controller) { Assert.NotNull(model); // The reason why to create a context is that: // We don't need to call te FindEntitySet or FindSingleton before every convention. // So, for a controller, we try to call "FindEntitySet" or "FindSingleton" once. string controllerName = controller.ControllerName; ODataControllerActionContext context = new ODataControllerActionContext(modelPrefix, model, controller); IEdmEntitySet entitySet = model.EntityContainer?.FindEntitySet(controllerName); if (entitySet != null) { context.NavigationSource = entitySet; } IEdmSingleton singleton = model.EntityContainer?.FindSingleton(controllerName); if (singleton != null) { context.NavigationSource = singleton; } return(context); }
public void AppliesToControllerWithRoutePrefixWorksAsExpected() { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <WithPrefixController>("List"); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = new ODataControllerActionContext(string.Empty, EdmModel, controller); AttributeRoutingConvention attributeConvention = CreateConvention(); // Act bool ok = attributeConvention.AppliesToController(context); Assert.False(ok); // Assert Assert.Equal(6, action.Selectors.Count); Assert.Equal(new[] { "Customers({key})", "Customers/{key}", "Customers", "Orders({key})", "Orders/{key}", "Orders", }, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
public void AppliesToActionForEntityActionWithEntityTypeNameSameAsEntityTypeOnEntitySetWorksAsExpected(string actionName) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <CustomersController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = action; EntityRoutingConvention entityConvention = ConventionHelpers.CreateConvention <EntityRoutingConvention>(); // Act bool returnValue = entityConvention.AppliesToAction(context); Assert.True(returnValue); // Assert Assert.Equal(2, action.Selectors.Count); Assert.Equal(new[] { "Customers(FirstName={keyFirstName},LastName={keyLastName})", "Customers(FirstName={keyFirstName},LastName={keyLastName})/NS.Customer" }, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
public void AppliesToActionForEntityActionWithDerivedEntityTypeAndCaseInsensitiveWorksAsExpected() { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <CaseInsensitiveCustomersController>("GetVIPCUSTOMER"); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = action; context.Options.RouteOptions.EnableActionNameCaseInsensitive = true; EntityRoutingConvention entityConvention = ConventionHelpers.CreateConvention <EntityRoutingConvention>(); // Act bool returnValue = entityConvention.AppliesToAction(context); Assert.True(returnValue); // Assert Assert.Equal(2, action.Selectors.Count); Assert.Collection(action.Selectors, e => { Assert.Equal("/CaseInsensitiveCustomers(FirstName={keyFirstName},LastName={keyLastName})/NS.VipCustomer", e.AttributeRouteModel.Template); }, e => { Assert.Equal("/CaseInsensitiveCustomers/FirstName={keyFirstName},LastName={keyLastName}/NS.VipCustomer", e.AttributeRouteModel.Template); }); }
/// <summary> /// Apply Default OData attribute routing /// </summary> /// <param name="controllers">The controller models</param> internal void ApplyAttributeRouting(IList <ControllerModel> controllers) { AttributeRoutingConvention attributeRouting = _conventions.OfType <AttributeRoutingConvention>().FirstOrDefault(); if (attributeRouting == null) { return; } ODataControllerActionContext controllerActionContext = new ODataControllerActionContext { Options = _options }; foreach (var controllerModel in controllers.Where(c => !c.IsNonODataController())) { controllerActionContext.Controller = controllerModel; foreach (var actionModel in controllerModel.Actions.Where(a => !a.IsNonODataAction())) { controllerActionContext.Action = actionModel; attributeRouting.AppliesToAction(controllerActionContext); } } }
public void AppliesToActionForGetActionWorksAsExpected(string actionName, string expectedTemplate) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <CustomersController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = action; EntitySetRoutingConvention entitySetConvention = ConventionHelpers.CreateConvention <EntitySetRoutingConvention>(); // Act bool returnValue = entitySetConvention.AppliesToAction(context); Assert.True(returnValue); // Assert Assert.Equal(2, action.Selectors.Count); Assert.Equal(new[] { $"/{expectedTemplate}", $"/{expectedTemplate}/$count" }, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
/// <summary> /// Executed for the second pass of <see cref="ApplicationModel"/> built. /// </summary> /// <param name="context">The <see cref="ApplicationModelProviderContext"/>.</param> public void OnProvidersExecuted(ApplicationModelProviderContext context) { var routes = _options.Models; foreach (var route in routes) { IEdmModel model = route.Value.Item1; if (model == null || model.EntityContainer == null) { continue; } foreach (var controller in context.Result.Controllers) { // Skip the controller with [NonODataController] attribute decorated. if (controller.HasAttribute <NonODataControllerAttribute>()) { continue; } // Apply to ODataModelAttribute if (!CanApply(route.Key, () => controller.GetAttribute <ODataModelAttribute>())) { continue; } ODataControllerActionContext odataContext = BuildContext(route.Key, model, controller); odataContext.ServiceProvider = route.Value.Item2; odataContext.RouteOptions = _options.RouteOptions; // consider to replace the Linq with others? IODataControllerActionConvention[] conventions = _controllerActionConventions.Where(c => c.AppliesToController(odataContext)).ToArray(); if (conventions.Length > 0) { foreach (var action in controller.Actions.Where(a => !a.IsNonODataAction())) { if (!CanApply(route.Key, () => action.GetAttribute <ODataModelAttribute>())) { continue; } // Reset the action on the context. odataContext.Action = action; foreach (var convention in conventions) { if (convention.AppliesToAction(odataContext)) { break; } } } } } } }
public void OnProvidersExecuted(ApplicationModelProviderContext context) { //var conventions = _options.Value.Conventions.OrderBy(c => c.Order); var routes = _options.Models; // Can apply on controller foreach (var route in routes) { IEdmModel model = route.Value; if (model == null || model.EntityContainer == null) { continue; } foreach (var controller in context.Result.Controllers) { // Skip the controller with [NonODataController] attribute decorated // Maybe we don't need this attribute. if (controller.HasAttribute <NonODataControllerAttribute>()) { continue; } // Apply to ODataModelAttribute if (!CanApply(route.Key, controller)) { continue; } // Add here // ODataControllerActionContext odataContext = BuildContext(route.Key, model, controller); odataContext.Controller = controller; // consider to replace the Linq with others? IODataControllerActionConvention[] newConventions = _controllerActionConventions.Where(c => c.AppliesToController(odataContext)).ToArray(); if (newConventions.Length > 0) { foreach (var action in controller.Actions) { odataContext.Action = action; foreach (var con in newConventions) { if (con.AppliesToAction(odataContext)) { break; } } } } } } Console.WriteLine("OnProvidersExecuted"); }
public bool AppliesToAction(ODataControllerActionContext context) { if (context.Prefix == "attributeRouting") { return(true); } return(false); }
public override bool AppliesToController(ODataControllerActionContext context) { if (context.Prefix == "AttributeRouting") { return(base.AppliesToController(context)); } return(false); }
public void AppliesToControllerReturnsExpectedForController(Type controllerType, bool expected) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel(controllerType); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); // Act bool actual = FunctionConvention.AppliesToController(context); // Assert Assert.Equal(expected, actual); }
public virtual bool AppliesToAction(ODataControllerActionContext context) { if (context.Action.ActionName != "GetTest") { return(false); } ODataPathTemplate path = new ODataPathTemplate( new EntitySetTemplateSegment() ); context.Action.AddSelector("Get", context.Prefix, context.Model, path); return(true); }
public void SingletonRoutingConventionTestDataRunsAsExpected(string actionName, string[] templates) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <RefCustomersController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, _edmModel, controller); context.Action = action; // Act _refConvention.AppliesToAction(context); // Assert Assert.Equal(templates.Length, action.Selectors.Count); Assert.Equal(templates, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
public void FunctionRoutingConventionResolveFunctionOverloadAsExpected(MethodInfo method, string[] templates) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModelByMethodInfo <CustomersController>(method); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = action; // Act FunctionConvention.AppliesToAction(context); // Assert Assert.Equal(templates.Length, action.Selectors.Count); Assert.Equal(templates, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
public void AppliesToActionWithRoutePrefixWorksAsExpected() { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <WithPrefixController>("List"); ActionModel action = controller.Actions.First(); Assert.Equal(2, action.Selectors.Count); ODataControllerActionContext context = new ODataControllerActionContext(string.Empty, _edmModel, controller) { Action = action, Options = _options, }; AttributeRoutingConvention attributeConvention = CreateConvention(); // Act bool ok = _attributeConvention.AppliesToAction(context); Assert.False(ok); // Assert Assert.Equal(4, action.Selectors.Count); Assert.Collection(action.Selectors, e => { Assert.Equal("/Customers/{key}", e.AttributeRouteModel.Template); Assert.Contains(e.EndpointMetadata, a => a is ODataRoutingMetadata); }, e => { Assert.Equal("/Orders/{key}", e.AttributeRouteModel.Template); Assert.Contains(e.EndpointMetadata, a => a is ODataRoutingMetadata); }, e => { Assert.Equal("/Customers", e.AttributeRouteModel.Template); Assert.Contains(e.EndpointMetadata, a => a is ODataRoutingMetadata); }, e => { Assert.Equal("/Orders", e.AttributeRouteModel.Template); Assert.Contains(e.EndpointMetadata, a => a is ODataRoutingMetadata); }); }
public void AppliesToActionDoesNothingForNonConventionAction(string actionName) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <AnotherCustomersController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = controller.Actions.First(); EntitySetRoutingConvention entitySetConvention = ConventionHelpers.CreateConvention <EntitySetRoutingConvention>(); // Act entitySetConvention.AppliesToAction(context); // Assert Assert.Empty(action.Selectors); }
public void ActionRoutingConventionTestDataWithCaseInsensitiveActionNameRunsAsExpected(Type controllerType, string actionName, string[] templates) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel(controllerType, actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Options.RouteOptions.EnableActionNameCaseInsensitive = true; context.Action = action; // Act ActionConvention.AppliesToAction(context); // Assert Assert.Equal(templates.Length, action.Selectors.Count); Assert.Equal(templates, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
public void OperationImportRoutingConventionDoesNothingForNotSupportedAction(string actionName) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <ODataOperationImportController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = controller.Actions.First(); // Act bool returnValue = ImportConvention.AppliesToAction(context); Assert.True(returnValue); // Assert Assert.Empty(action.Selectors); }
public void ActionRoutingConventionDoesCaseSensitiveMatchingByDefault(Type controllerType, string actionName, string[] templates) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel(controllerType, actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = action; // Act ActionConvention.AppliesToAction(context); // Assert SelectorModel selector = Assert.Single(action.Selectors); Assert.Null(selector.AttributeRouteModel); Assert.NotEmpty(templates); }
public void AppliesToActionAddTemplateForServiceDocumentWithPrefix(string prefix) { // Arrange string expected = string.IsNullOrEmpty(prefix) ? "/" : $"/{prefix}/"; ControllerModel controller = ControllerModelHelpers.BuildControllerModel <MetadataController>("GetServiceDocument"); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(prefix, EdmCoreModel.Instance, controller); context.Action = action; // Act _metadataConvention.AppliesToAction(context); // Assert SelectorModel selector = Assert.Single(action.Selectors); Assert.Equal(expected, selector.AttributeRouteModel.Template); }
public void NavigationRoutingConventionTestDataRunsAsExpected(Type controllerType, string actionName, string[] templates) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel(controllerType, actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = action; // Act bool returnValue = NavigationConvention.AppliesToAction(context); Assert.True(returnValue); // Assert Assert.Equal(templates.Length, action.Selectors.Count); Assert.Equal(templates, action.Selectors.Select(s => s.AttributeRouteModel.Template)); }
public void RefRoutingConventionDoesNothingForNotSupportedAction(string actionName) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <RefCustomersController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, _edmModel, controller); context.Action = controller.Actions.First(); // Act bool returnValue = _refConvention.AppliesToAction(context); Assert.False(returnValue); // Assert SelectorModel selector = Assert.Single(action.Selectors); Assert.Null(selector.AttributeRouteModel); }
public void AppliesToControllerForSingletonWorksAsExpected(string actionName, string expectedTemplate) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <SingletonTestControllerWithPrefix>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = new ODataControllerActionContext(string.Empty, EdmModel, controller); AttributeRoutingConvention attributeConvention = CreateConvention(); // Act bool ok = attributeConvention.AppliesToController(context); Assert.False(ok); // Assert SelectorModel selector = Assert.Single(action.Selectors); Assert.NotNull(selector.AttributeRouteModel); Assert.Equal(expectedTemplate, selector.AttributeRouteModel.Template); }
public void AppliesToActionWithoutRoutePrefixWorksAsExpected() { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <WithoutPrefixController>("MyAction"); ActionModel action = controller.Actions.First(); Assert.Collection(action.Selectors, // Guard e => { Assert.Equal("Customers({key})", e.AttributeRouteModel.Template); Assert.DoesNotContain(e.EndpointMetadata, a => a is ODataRoutingMetadata); }, e => { Assert.Equal("Customers/{key}/Name", e.AttributeRouteModel.Template); Assert.DoesNotContain(e.EndpointMetadata, a => a is ODataRoutingMetadata); }); ODataControllerActionContext context = new ODataControllerActionContext(string.Empty, _edmModel, controller); context.Action = action; context.Options = _options; // Act bool ok = _attributeConvention.AppliesToAction(context); Assert.False(ok); Assert.Equal(2, action.Selectors.Count); Assert.Collection(action.Selectors, e => { Assert.Equal("/Customers({key})", e.AttributeRouteModel.Template); Assert.Contains(e.EndpointMetadata, a => a is ODataRoutingMetadata); }, e => { Assert.Equal("/Customers/{key}/Name", e.AttributeRouteModel.Template); Assert.Contains(e.EndpointMetadata, a => a is ODataRoutingMetadata); }); }
public void AppliesToActionForPostActionWorksAsExpected(string actionName, string expected) { // Arrange ControllerModel controller = ControllerModelHelpers.BuildControllerModel <CustomersController>(actionName); ActionModel action = controller.Actions.First(); ODataControllerActionContext context = ODataControllerActionContextHelpers.BuildContext(string.Empty, EdmModel, controller); context.Action = controller.Actions.First(); EntitySetRoutingConvention entitySetConvention = ConventionHelpers.CreateConvention <EntitySetRoutingConvention>(); // Act bool returnValue = entitySetConvention.AppliesToAction(context); Assert.True(returnValue); // Assert SelectorModel selector = Assert.Single(action.Selectors); Assert.Equal(expected, selector.AttributeRouteModel.Template); }