public void GetActions_CreatesNamedAndUnnamedAction() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast<ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.StoreController).GetTypeInfo(); var actions = results .Where(ad => ad.ControllerTypeInfo == controllerType) .Where(ad => ad.MethodInfo.Name == "GetAll") .ToArray(); Assert.Equal(2, actions.Length); var action = Assert.Single( actions, a => a.RouteConstraints.Any(rc => rc.RouteKey == "action" && rc.RouteValue == "GetAll")); Assert.Equal( new string[] { "GET" }, Assert.Single(action.ActionConstraints.OfType<HttpMethodConstraint>()).HttpMethods); action = Assert.Single( actions, a => a.RouteConstraints.Any(rc => rc.RouteKey == "action" && rc.RouteValue == "")); Assert.Equal( new string[] { "GET" }, Assert.Single(action.ActionConstraints.OfType<HttpMethodConstraint>()).HttpMethods); }
} = -900; // Run after the default MVC provider, but before others. /// <inheritdoc/> public void OnProvidersExecuting(ActionDescriptorProviderContext context) { var pageRouteModels = BuildModel(); for (var i = 0; i < pageRouteModels.Count; i++) { AddActionDescriptors(context.Results, pageRouteModels[i]); } }
public void OnProvidersExecuted(ActionDescriptorProviderContext context) { if (context.Results.Count == 0) { throw new InvalidOperationException("No actions found!"); } Interlocked.Increment(ref _callCount); }
public void Apply(ActionDescriptorProviderContext context, ControllerActionDescriptor action) { Contract.Requires(context != null); Contract.Requires(action != null); var model = action.GetApiVersionModel(Explicit | Implicit); var mappings = RouteCollectionProvider.Items; var routeInfos = new HashSet <ODataAttributeRouteInfo>(new ODataAttributeRouteInfoComparer()); UpdateControllerName(action); if (model.IsApiVersionNeutral) { if (mappings.Count == 0) { return; } // any mapping will do for a version-neutral action; just take the first one var mapping = mappings[0]; UpdateBindingInfo(action, mapping, routeInfos); } else { foreach (var apiVersion in model.DeclaredApiVersions) { if (!mappings.TryGetValue(apiVersion, out var mappingsPerApiVersion)) { continue; } foreach (var mapping in mappingsPerApiVersion) { UpdateBindingInfo(action, mapping, routeInfos); } } } if (routeInfos.Count == 0) { return; } using (var iterator = routeInfos.GetEnumerator()) { iterator.MoveNext(); action.AttributeRouteInfo = iterator.Current; while (iterator.MoveNext()) { context.Results.Add(Clone(action, iterator.Current)); } } }
public void GetDescriptors_AddsActionDescriptorForEachSelector() { // Arrange var applicationModelProvider = new TestPageRouteModelProvider( new PageRouteModel("/base-path/Test.cshtml", "/base-path/Test") { Selectors = { CreateSelectorModel("base-path/Test/Home") } }, new PageRouteModel("/base-path/Index.cshtml", "/base-path/Index") { Selectors = { CreateSelectorModel("base-path/Index"), CreateSelectorModel("base-path/"), } }, new PageRouteModel("/base-path/Admin/Index.cshtml", "/base-path/Admin/Index") { Selectors = { CreateSelectorModel("base-path/Admin/Index"), CreateSelectorModel("base-path/Admin"), } }, new PageRouteModel("/base-path/Admin/User.cshtml", "/base-path/Admin/User") { Selectors = { CreateSelectorModel("base-path/Admin/User"), }, }); var options = GetRazorPagesOptions(); var provider = new PageActionDescriptorProvider( new[] { applicationModelProvider }, GetAccessor <MvcOptions>(), options); var context = new ActionDescriptorProviderContext(); // Act provider.OnProvidersExecuting(context); // Assert Assert.Collection(context.Results, result => Assert.Equal("base-path/Test/Home", result.AttributeRouteInfo.Template), result => Assert.Equal("base-path/Index", result.AttributeRouteInfo.Template), result => Assert.Equal("base-path/", result.AttributeRouteInfo.Template), result => Assert.Equal("base-path/Admin/Index", result.AttributeRouteInfo.Template), result => Assert.Equal("base-path/Admin", result.AttributeRouteInfo.Template), result => Assert.Equal("base-path/Admin/User", result.AttributeRouteInfo.Template)); }
public void Invoke(ActionDescriptorProviderContext context, Action callNext) { callNext(); if (context.Results.Count == 0) { throw new InvalidOperationException("No actions found!"); } Interlocked.Increment(ref _callCount); }
public void Apply(ActionDescriptorProviderContext context, ControllerActionDescriptor action) { var model = action.GetApiVersionModel(Explicit | Implicit); var routeInfos = model.IsApiVersionNeutral ? ExpandVersionNeutralActions(action) : ExpandVersionedActions(action, model); foreach (var routeInfo in routeInfos) { context.Results.Add(Clone(action, routeInfo)); } }
/// <inheritdoc /> public void OnProvidersExecuting(ActionDescriptorProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } foreach (var descriptor in GetDescriptors()) { context.Results.Add(descriptor); } }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var item in context.Results.ToList()) { if (item is ControllerActionDescriptor controllerActionDescriptor) { if (controllerActionDescriptor.ControllerTypeInfo == _controllerType) { context.Results.Remove(item); } } } }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var descriptor in context.Results) { for (int i = 0; i < descriptor.Parameters.Count; ++i) { if (typeof(ODataQueryOptions).IsAssignableFrom(descriptor.Parameters[i].ParameterType)) { descriptor.Parameters[i].BindingInfo.BindingSource = BindingSource.Special; } } } }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var item in EnumerateItems()) { if (item.Filename.StartsWith("_")) { // Pages like _PageImports should not be routable. continue; } AddActionDescriptors(context.Results, item); } }
private void UpdateCollection() { // Using the lock to initialize writes means that we serialize changes. This eliminates // the potential for changes to be processed out of order - the risk is that newer data // could be overwritten by older data. lock (_lock) { var context = new ActionDescriptorProviderContext(); for (var i = 0; i < _actionDescriptorProviders.Length; i++) { _actionDescriptorProviders[i].OnProvidersExecuting(context); } for (var i = _actionDescriptorProviders.Length - 1; i >= 0; i--) { _actionDescriptorProviders[i].OnProvidersExecuted(context); } // The sequence for an update is important because we don't want anyone to obtain // the new change token but the old action descriptor collection. // 1. Obtain the old cancellation token source (don't trigger it yet) // 2. Set the new action descriptor collection // 3. Set the new change token // 4. Trigger the old cancellation token source // // Consumers who poll will observe a new action descriptor collection at step 2 - they will see // the new collection and ignore the change token. // // Consumers who listen to the change token will requery at step 4 - they will see the new collection // and new change token. // // Anyone who acquires the collection and change token between steps 2 and 3 will be notified of // a no-op change at step 4. // Step 1. var oldCancellationTokenSource = _cancellationTokenSource; // Step 2. _collection = new ActionDescriptorCollection( new ReadOnlyCollection <ActionDescriptor>(context.Results), _version++); // Step 3. _cancellationTokenSource = new CancellationTokenSource(); _changeToken = new CancellationChangeToken(_cancellationTokenSource.Token); // Step 4 - might be null if it's the first time. oldCancellationTokenSource?.Cancel(); } }
public void GetDescriptors_CopiesRouteValuesFromModel() { // Arrange var model = new PageRouteModel("/Areas/Accounts/Pages/Test.cshtml", "/Test", "Accounts") { RouteValues = { { "page", "/Test" }, { "area", "Accounts" }, }, Selectors = { new SelectorModel { AttributeRouteModel = new AttributeRouteModel { Template = "Accounts/Test/{id:int?}", } } } }; var applicationModelProvider = new TestPageRouteModelProvider(model); var provider = new PageActionDescriptorProvider( new[] { applicationModelProvider }, GetAccessor <MvcOptions>(), GetRazorPagesOptions()); var context = new ActionDescriptorProviderContext(); // Act provider.OnProvidersExecuting(context); // Assert var result = Assert.Single(context.Results); var descriptor = Assert.IsType <PageActionDescriptor>(result); Assert.Equal(model.RelativePath, descriptor.RelativePath); Assert.Collection( descriptor.RouteValues.OrderBy(kvp => kvp.Key), kvp => { Assert.Equal("area", kvp.Key); Assert.Equal("Accounts", kvp.Value); }, kvp => { Assert.Equal("page", kvp.Key); Assert.Equal("/Test", kvp.Value); }); Assert.Equal("Accounts", descriptor.AreaName); Assert.Equal("Accounts/Test/{id:int?}", descriptor.AttributeRouteInfo.Template); }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var descriptor in context.Results) { for (int i = 0; i < descriptor.Parameters.Count; ++i) { if (descriptor.Parameters[i].ParameterType == typeof(CancellationToken)) { descriptor.Parameters.RemoveAt(i); --i; } } } }
public void GetDescriptors_DoesNotAddDescriptorsIfNoApplicationModelsAreDiscovered() { // Arrange var applicationModelProvider = new TestPageRouteModelProvider(); var provider = new PageActionDescriptorProvider( new[] { applicationModelProvider }, GetAccessor <MvcOptions>(), GetRazorPagesOptions()); var context = new ActionDescriptorProviderContext(); // Act provider.OnProvidersExecuting(context); // Assert Assert.Empty(context.Results); }
public void Apply(ActionDescriptorProviderContext context, ControllerActionDescriptor action) { var odataActionWithExplicitHttpMethods = action.ActionConstraints != null && action.ActionConstraints.OfType <HttpMethodActionConstraint>().Any(); if (odataActionWithExplicitHttpMethods) { return; } var httpMethod = GetImplicitHttpMethod(action); var actionConstraints = action.ActionConstraints ?? new List <IActionConstraintMetadata>(); actionConstraints.Add(new HttpMethodActionConstraint(new[] { httpMethod })); action.ActionConstraints = actionConstraints; }
public void GetActions_ApiControllerWithoutControllerSuffix_IsNotController() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast<ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.Blog).GetTypeInfo(); var actions = results.Where(ad => ad.ControllerTypeInfo == controllerType).ToArray(); Assert.Empty(actions); }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var item in context.Results.ToList()) { if (item is ControllerActionDescriptor controllerActionDescriptor) { var controllerToRemove = _controllerTypes.SingleOrDefault(c => c.ControllerType == controllerActionDescriptor.ControllerTypeInfo); if (controllerToRemove != null) { if (controllerToRemove.Actions == null || controllerToRemove.Actions.Contains(controllerActionDescriptor.ActionName)) { context.Results.Remove(item); } } } } }
/// <inheritdoc /> public virtual void OnProvidersExecuted(ActionDescriptorProviderContext context) { foreach (var actions in GroupActionsByController(context.Results)) { var collatedModel = CollateModel(actions); foreach (var action in actions) { var model = action.GetProperty <ApiVersionModel>(); if (model != null && !model.IsApiVersionNeutral) { action.SetProperty(model.Aggregate(collatedModel)); } } } }
public void GetActions_ApiControllerWithoutControllerSuffix_IsNotController() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast <ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.Blog).GetTypeInfo(); var actions = results.Where(ad => ad.ControllerTypeInfo == controllerType).ToArray(); Assert.Empty(actions); }
private void UpdateCollection() { var context = new ActionDescriptorProviderContext(); for (var i = 0; i < _actionDescriptorProviders.Length; i++) { _actionDescriptorProviders[i].OnProvidersExecuting(context); } for (var i = _actionDescriptorProviders.Length - 1; i >= 0; i--) { _actionDescriptorProviders[i].OnProvidersExecuted(context); } _collection = new ActionDescriptorCollection( new ReadOnlyCollection <ActionDescriptor>(context.Results), Interlocked.Increment(ref _version)); }
public void Invoke(ActionDescriptorProviderContext context, Action callNext) { foreach (var assembly in _assemblyProvider.CandidateAssemblies) { foreach (var type in assembly.GetExportedTypes()) { var typeInfo = type.GetTypeInfo(); if (typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.ContainsGenericParameters && typeof(MvcModule).IsAssignableFrom(type) && type != typeof(MvcModule)) { context.Results.AddRange(GetActions(type)); } } } callNext(); }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var part in _applicationPartManager.ApplicationParts.OfType <IApplicationPartTypeProvider>()) { foreach (var typeInfo in part.Types) { var type = typeInfo.AsType(); if (typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.ContainsGenericParameters && typeof(MvcModule).IsAssignableFrom(type) && type != typeof(MvcModule)) { foreach (var action in GetActions(type)) { context.Results.Add(action); } } } } }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var assembly in _assemblyProvider.CandidateAssemblies) { foreach (var type in assembly.GetExportedTypes()) { var typeInfo = type.GetTypeInfo(); if (typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.ContainsGenericParameters && typeof(MvcModule).IsAssignableFrom(type) && type != typeof(MvcModule)) { foreach (var action in GetActions(type)) { context.Results.Add(action); } } } } }
public void OnProvidersExecuted(ActionDescriptorProviderContext context) { if (routeCollectionProvider.Items.Count == 0) { return; } var results = context.Results.ToArray(); var conventions = new IODataActionDescriptorConvention[] { new ImplicitHttpMethodConvention(), new ODataRouteBindingInfoConvention(routeCollectionProvider, modelMetadataProvider, options), }; foreach (var action in ODataActions(results)) { foreach (var convention in conventions) { convention.Apply(context, action); } } }
public void GetDescriptors_AddsMultipleDescriptorsForPageWithMultipleSelectors() { // Arrange var applicationModelProvider = new TestPageRouteModelProvider( new PageRouteModel("/Catalog/Details/Index.cshtml", "/Catalog/Details/Index") { Selectors = { CreateSelectorModel("/Catalog/Details/Index/{id:int?}"), CreateSelectorModel("/Catalog/Details/{id:int?}"), }, }); var provider = new PageActionDescriptorProvider( new[] { applicationModelProvider }, GetAccessor <MvcOptions>(), GetRazorPagesOptions()); var context = new ActionDescriptorProviderContext(); // Act provider.OnProvidersExecuting(context); // Assert Assert.Collection(context.Results, result => { var descriptor = Assert.IsType <PageActionDescriptor>(result); Assert.Equal("/Catalog/Details/Index.cshtml", descriptor.RelativePath); Assert.Equal("/Catalog/Details/Index", descriptor.RouteValues["page"]); Assert.Equal("/Catalog/Details/Index/{id:int?}", descriptor.AttributeRouteInfo.Template); }, result => { var descriptor = Assert.IsType <PageActionDescriptor>(result); Assert.Equal("/Catalog/Details/Index.cshtml", descriptor.RelativePath); Assert.Equal("/Catalog/Details/Index", descriptor.RouteValues["page"]); Assert.Equal("/Catalog/Details/{id:int?}", descriptor.AttributeRouteInfo.Template); }); }
private ActionDescriptorCollection GetCollection() { var providers = _serviceProvider.GetServices<IActionDescriptorProvider>() .OrderBy(p => p.Order) .ToArray(); var context = new ActionDescriptorProviderContext(); foreach (var provider in providers) { provider.OnProvidersExecuting(context); } for (var i = providers.Length - 1; i >= 0; i--) { providers[i].OnProvidersExecuted(context); } return new ActionDescriptorCollection( new ReadOnlyCollection<ActionDescriptor>(context.Results), 0); }
private ActionDescriptorsCollection GetCollection() { var providers = _serviceProvider.GetServices <IActionDescriptorProvider>() .OrderBy(p => p.Order) .ToArray(); var context = new ActionDescriptorProviderContext(); foreach (var provider in providers) { provider.OnProvidersExecuting(context); } for (var i = providers.Length - 1; i >= 0; i--) { providers[i].OnProvidersExecuted(context); } return(new ActionDescriptorsCollection( new ReadOnlyCollection <ActionDescriptor>(context.Results), 0)); }
public void GetActions_CreatesNamedAndUnnamedAction() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast <ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.StoreController).GetTypeInfo(); var actions = results .Where(ad => ad.ControllerTypeInfo == controllerType) .Where(ad => ad.MethodInfo.Name == "GetAll") .ToArray(); Assert.Equal(2, actions.Length); var action = Assert.Single( actions, a => a.RouteConstraints.Any(rc => rc.RouteKey == "action" && rc.RouteValue == "GetAll")); Assert.Equal( new string[] { "GET" }, Assert.Single(action.ActionConstraints.OfType <HttpMethodConstraint>()).HttpMethods); action = Assert.Single( actions, a => a.RouteConstraints.Any(rc => rc.RouteKey == "action" && rc.RouteValue == "")); Assert.Equal( new string[] { "GET" }, Assert.Single(action.ActionConstraints.OfType <HttpMethodConstraint>()).HttpMethods); }
public void GetActions_AllWebApiActionsAreInWebApiArea() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast <ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.StoreController).GetTypeInfo(); var actions = results .Where(ad => ad.ControllerTypeInfo == controllerType) .ToArray(); Assert.NotEmpty(actions); foreach (var action in actions) { Assert.Single(action.RouteConstraints, c => c.RouteKey == "area" && c.RouteValue == "api"); } }
public void GetActions_AllWebApiActionsAreOverloaded() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); provider.Invoke(context); var results = context.Results.Cast <ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.StoreController).GetTypeInfo(); var actions = results .Where(ad => ad.ControllerTypeInfo == controllerType) .ToArray(); Assert.NotEmpty(actions); foreach (var action in actions) { Assert.Single(action.ActionConstraints, c => c is OverloadActionConstraint); } }
private void UpdateCollection() { // Using the lock to initialize writes means that we serialize changes. This eliminates // the potential for changes to be processed out of order - the risk is that newer data // could be overwritten by older data. lock (_lock) { var context = new ActionDescriptorProviderContext(); for (var i = 0; i < _actionDescriptorProviders.Length; i++) { _actionDescriptorProviders[i].OnProvidersExecuting(context); } for (var i = _actionDescriptorProviders.Length - 1; i >= 0; i--) { _actionDescriptorProviders[i].OnProvidersExecuted(context); } // The sequence for an update is important because we don't want anyone to obtain // the new change token but the old action descriptor collection. // 1. Obtain the old cancellation token source (don't trigger it yet) // 2. Set the new action descriptor collection // 3. Set the new change token // 4. Trigger the old cancellation token source // // Consumers who poll will observe a new action descriptor collection at step 2 - they will see // the new collection and ignore the change token. // // Consumers who listen to the change token will re-query at step 4 - they will see the new collection // and new change token. // // Anyone who acquires the collection and change token between steps 2 and 3 will be notified of // a no-op change at step 4. // Step 1. var oldCancellationTokenSource = _cancellationTokenSource; foreach (var actionDescriptor in context.Results) { if (actionDescriptor.AttributeRouteInfo == null || actionDescriptor.ActionConstraints == null) { if (actionDescriptor.ActionConstraints == null) { // check from config for default HTTP method actionDescriptor.ActionConstraints = new List <IActionConstraintMetadata> { new HttpMethodActionConstraint(new[] { "GET" }) }; } var routeTemplate = _routeTemplateResolver.ResolveRouteTemplate(actionDescriptor); if (!string.IsNullOrEmpty(routeTemplate)) { actionDescriptor.AttributeRouteInfo = new AttributeRouteInfo { Template = routeTemplate }; } } } // Step 2. _collection = new ActionDescriptorCollection( new ReadOnlyCollection <ActionDescriptor>(context.Results), _version++); // Step 3. _cancellationTokenSource = new CancellationTokenSource(); _changeToken = new CancellationChangeToken(_cancellationTokenSource.Token); // Step 4 - might be null if it's the first time. oldCancellationTokenSource?.Cancel(); } }
public void Invoke(ActionDescriptorProviderContext context, Action callNext) { context.Results.AddRange(GetDescriptors()); callNext(); }
public void OnProvidersExecuted(ActionDescriptorProviderContext context) { }
public void OnProvidersExecuting(ActionDescriptorProviderContext context) { }
private void Invoke(ControllerActionDescriptorProvider provider, ActionDescriptorProviderContext context) { provider.OnProvidersExecuting(context); provider.OnProvidersExecuted(context); }
public void GetActions_AllWebApiActionsAreInWebApiArea() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast<ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.StoreController).GetTypeInfo(); var actions = results .Where(ad => ad.ControllerTypeInfo == controllerType) .ToArray(); Assert.NotEmpty(actions); foreach (var action in actions) { Assert.Single(action.RouteConstraints, c => c.RouteKey == "area" && c.RouteValue == "api"); } }
public void GetActions_Parameters_WithBindingSource() { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast<ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.EmployeesController).GetTypeInfo(); var actions = results .Where(ad => ad.ControllerTypeInfo == controllerType) .Where(ad => ad.Name == "Post") .ToArray(); Assert.NotEmpty(actions); foreach (var action in actions) { var parameter = Assert.Single(action.Parameters); Assert.Null(parameter.BindingInfo.BindingSource); } }
public void GetActions_Parameters_ImplicitOptional(string name) { // Arrange var provider = CreateProvider(); // Act var context = new ActionDescriptorProviderContext(); Invoke(provider, context); var results = context.Results.Cast<ControllerActionDescriptor>(); // Assert var controllerType = typeof(TestControllers.EventsController).GetTypeInfo(); var actions = results .Where(ad => ad.ControllerTypeInfo == controllerType) .Where(ad => ad.Name == name) .ToArray(); Assert.NotEmpty(actions); foreach (var action in actions) { var parameter = Assert.Single(action.Parameters); Assert.Equal((new FromUriAttribute()).BindingSource, parameter.BindingInfo.BindingSource); var optionalParameters = (HashSet<string>)action.Properties["OptionalParameters"]; Assert.True(optionalParameters.Contains(parameter.Name)); } }