public void Build_WithPropertiesSet_ActionOverwritesApplicationAndControllerModel() { // Arrange var applicationModel = new ApplicationModel(); applicationModel.Properties["test"] = "application"; var controller = new ControllerModel(typeof(TestController).GetTypeInfo(), new List<object>() { }); controller.Application = applicationModel; controller.Properties["test"] = "controller"; applicationModel.Controllers.Add(controller); var methodInfo = typeof(TestController).GetMethod(nameof(TestController.SomeAction)); var actionModel = new ActionModel(methodInfo, new List<object>() { }); actionModel.Selectors.Add(new SelectorModel()); actionModel.Controller = controller; actionModel.Properties["test"] = "action"; controller.Actions.Add(actionModel); // Act var descriptors = ControllerActionDescriptorBuilder.Build(applicationModel); // Assert Assert.Equal("action", descriptors.Single().Properties["test"]); }
public ControllerModel(ControllerModel other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } ControllerName = other.ControllerName; ControllerType = other.ControllerType; // Still part of the same application Application = other.Application; // These are just metadata, safe to create new collections Attributes = new List<object>(other.Attributes); Filters = new List<IFilterMetadata>(other.Filters); RouteValues = new Dictionary<string, string>(other.RouteValues, StringComparer.OrdinalIgnoreCase); Properties = new Dictionary<object, object>(other.Properties); // Make a deep copy of other 'model' types. Actions = new List<ActionModel>(other.Actions.Select(a => new ActionModel(a))); ApiExplorer = new ApiExplorerModel(other.ApiExplorer); ControllerProperties = new List<PropertyModel>(other.ControllerProperties.Select(p => new PropertyModel(p))); Selectors = new List<SelectorModel>(other.Selectors.Select(s => new SelectorModel(s))); }
public void Apply(ControllerModel controller) { var routes = routeBuilder.GetTypedRoutes(); if (routes.ContainsKey(controller.ControllerType)) { var typedRoutes = routes[controller.ControllerType]; foreach (var route in typedRoutes) { var selectorModel = new SelectorModel { AttributeRouteModel = route }; var selectors = controller.Selectors; var action = controller.Actions.FirstOrDefault(x => x.ActionMethod == route.ActionMember); if (action != null) { foreach (var constraint in route.Constraints) { selectorModel.ActionConstraints.Add(constraint); } selectors = action.Selectors; } selectors.Clear(); selectors.Add(selectorModel); } } }
public void Apply(ControllerModel controller) { foreach (var routeValue in controller.RouteValues) { routeKeysProvider.AddKey(routeValue.Key); } }
public void Apply(ControllerModel controller) { if (controller == null) { throw new ArgumentNullException(nameof(controller)); } if (IsConventionApplicable(controller)) { var newActions = new List<ActionModel>(); foreach (var action in controller.Actions) { SetHttpMethodFromConvention(action); // Action Name doesn't really come into play with attribute routed actions. However for a // non-attribute-routed action we need to create a 'named' version and an 'unnamed' version. if (!IsActionAttributeRouted(action)) { var namedAction = action; var unnamedAction = new ActionModel(namedAction); unnamedAction.RouteValues.Add("action", null); newActions.Add(unnamedAction); } } foreach (var action in newActions) { controller.Actions.Add(action); } } }
public void Apply(ControllerModel controller) { var themeAttribute = controller.Attributes.FirstOrDefault(t => t is AdminAttribute); if (themeAttribute != null || controller.ControllerName == AdminAttribute.ThemeValue) { controller.Properties.Add(AdminAttribute.ThemeKey, AdminAttribute.ThemeValue); } }
private void ConfigureRemoteService(ControllerModel controller) { var configuration = GetControllerSettingOrNull(controller.ControllerType); ConfigureApiExplorer(controller); ConfigureSelector(controller, configuration); ConfigureParameters(controller); }
public void Apply(ControllerModel controller) { if (controller == null) { throw new ArgumentNullException(nameof(controller)); } if (IsConventionApplicable(controller)) { controller.RouteConstraints.Add(new AreaAttribute(_area)); } }
private void ConfigureArea(ControllerModel controller, [CanBeNull] AbpServiceControllerSetting configuration) { if (configuration == null) { return; } if (controller.RouteValues.ContainsKey("area")) { return; } controller.RouteValues["area"] = configuration.ModuleName; }
public void Build_WithControllerPropertiesSet_AddsPropertiesWithBinderMetadataSet() { // Arrange var applicationModel = new ApplicationModel(); var controller = new ControllerModel( typeof(TestController).GetTypeInfo(), new List<object>() { }); var propertyInfo = controller.ControllerType.AsType().GetProperty("BoundProperty"); controller.ControllerProperties.Add( new PropertyModel( propertyInfo, new List<object>() { }) { BindingInfo = BindingInfo.GetBindingInfo(new object[] { new FromQueryAttribute() }), PropertyName = "BoundProperty" }); controller.ControllerProperties.Add( new PropertyModel( controller.ControllerType.AsType().GetProperty("UnboundProperty"), new List<object>() { })); controller.Application = applicationModel; applicationModel.Controllers.Add(controller); var methodInfo = typeof(TestController).GetMethod(nameof(TestController.SomeAction)); var actionModel = new ActionModel(methodInfo, new List<object>() { }); actionModel.Selectors.Add(new SelectorModel()); actionModel.Controller = controller; controller.Actions.Add(actionModel); // Act var descriptors = ControllerActionDescriptorBuilder.Build(applicationModel); // Assert var controllerDescriptor = Assert.Single(descriptors); var parameter = Assert.Single(controllerDescriptor.BoundProperties); var property = Assert.IsType<ControllerBoundPropertyDescriptor>(parameter); Assert.Equal("BoundProperty", property.Name); Assert.Equal(propertyInfo, property.PropertyInfo); Assert.Equal(typeof(string), property.ParameterType); Assert.Equal(BindingSource.Query, property.BindingInfo.BindingSource); }
private void ConfigureParameters(ControllerModel controller) { foreach (var action in controller.Actions) { foreach (var prm in action.Parameters) { if (prm.BindingInfo != null) { continue; } if (!TypeHelper.IsPrimitiveExtendedIncludingNullable(prm.ParameterInfo.ParameterType)) { if (CanUseFormBodyBinding(action)) { prm.BindingInfo = BindingInfo.GetBindingInfo(new[] { new FromBodyAttribute() }); } } } } }
public void Apply(ControllerModel controller) { var hasRouteAttributes = controller.Selectors.Any(selector => selector.AttributeRouteModel != null); if (hasRouteAttributes) { // This controller manually defined some routes, so treat this // as an override and not apply the convention here. return; } // Use the namespace and controller name to infer a route for the controller. // // Example: // // controller.ControllerTypeInfo -> "My.Application.Admin.UsersController" // baseNamespace -> "My.Application" // // template => "Admin/[controller]" // // This makes your routes roughly line up with the folder structure of your project. // var namespc = controller.ControllerType.Namespace; var template = new StringBuilder(); template.Append(namespc, _baseNamespace.Length + 1, namespc.Length - _baseNamespace.Length - 1); template.Replace('.', '/'); template.Append("/[controller]"); foreach (var selector in controller.Selectors) { selector.AttributeRouteModel = new AttributeRouteModel() { Template = template.ToString() }; } }
public void Apply(ControllerModel model) { model.Properties["description"] = _value; }
public void Apply(ControllerModel controller) { }
/// <summary> /// Returns a value indicating whether controller model has explicit version information. /// </summary> /// <param name="controller">The <see cref="ControllerModel">model</see> to evaluate.</param> /// <returns>True if the <paramref name="controller"/> has explicit version information; otherwise, false.</returns> public static bool HasExplicitVersioning(this ControllerModel controller) { Arg.NotNull(controller, nameof(controller)); return(controller.Properties.ContainsKey(typeof(ApiVersionModel)) || controller.Attributes.OfType <IApiVersionProvider>().Any()); }
private void ConfigureRemoteService(ControllerModel controller, [CanBeNull] AbpServiceControllerSetting configuration) { ConfigureApiExplorer(controller); ConfigureSelector(controller, configuration); ConfigureParameters(controller); }
private void ConfigureSelector(ControllerModel controller, [CanBeNull] AbpServiceControllerSetting configuration) { RemoveEmptySelectors(controller.Selectors); if (controller.Selectors.Any(selector => selector.AttributeRouteModel != null)) { return; } var moduleName = GetModuleNameOrDefault(controller.ControllerType.AsType()); foreach (var action in controller.Actions) { ConfigureSelector(moduleName, controller.ControllerName, action, configuration); } }
/// <inheritdoc /> public bool IsSatisfiedBy(ControllerModel controller) { Arg.NotNull(controller, nameof(controller)); return(IsApiController(controller)); }
public void Apply(ControllerModel controller) { controller.ControllerName = "ChangedController"; }
public void Apply(ControllerModel controller) { controller.Properties.Add("TestProperty", "TestValue"); }
public void Apply(ControllerModel controller) { var areaName = controller.ControllerType.Assembly.GetName().Name; controller.RouteConstraints.Add(new AreaAttribute(areaName)); }
public void CopyConstructor_CopiesAllProperties() { // Arrange var controller = new ControllerModel( typeof(TestController).GetTypeInfo(), new List <object>() { new HttpGetAttribute(), new MyFilterAttribute(), }); var selectorModel = new SelectorModel(); selectorModel.ActionConstraints.Add(new HttpMethodActionConstraint(new string[] { "GET" })); controller.Selectors.Add(selectorModel); controller.Application = new ApplicationModel(); controller.ControllerName = "cool"; controller.Filters.Add(new MyFilterAttribute()); controller.RouteValues.Add("key", "value"); controller.Properties.Add(new KeyValuePair <object, object>("test key", "test value")); controller.ControllerProperties.Add( new PropertyModel(typeof(TestController).GetProperty("TestProperty"), new List <object>())); // Act var controller2 = new ControllerModel(controller); // Assert foreach (var property in typeof(ControllerModel).GetProperties()) { if (property.Name.Equals("Actions") || property.Name.Equals("Selectors") || property.Name.Equals("ApiExplorer") || property.Name.Equals("ControllerProperties")) { // This test excludes other ApplicationModel objects on purpose because we deep copy them. continue; } var value1 = property.GetValue(controller); var value2 = property.GetValue(controller2); if (typeof(IEnumerable <object>).IsAssignableFrom(property.PropertyType)) { Assert.Equal <object>((IEnumerable <object>)value1, (IEnumerable <object>)value2); // Ensure non-default value Assert.NotEmpty((IEnumerable <object>)value1); } else if (typeof(IDictionary <string, string>).IsAssignableFrom(property.PropertyType)) { Assert.Equal(value1, value2); // Ensure non-default value Assert.NotEmpty((IDictionary <string, string>)value1); } else if (typeof(IDictionary <object, object>).IsAssignableFrom(property.PropertyType)) { Assert.Equal(value1, value2); // Ensure non-default value Assert.NotEmpty((IDictionary <object, object>)value1); } else if (property.PropertyType.IsValueType || Nullable.GetUnderlyingType(property.PropertyType) != null) { Assert.Equal(value1, value2); // Ensure non-default value Assert.NotEqual(value1, Activator.CreateInstance(property.PropertyType)); } else if (property.Name.Equals(nameof(ControllerModel.DisplayName))) { // DisplayName is re-calculated, hence reference equality wouldn't work. Assert.Equal(value1, value2); } else { Assert.Same(value1, value2); // Ensure non-default value Assert.NotNull(value1); } } }
/// <summary> /// Creates a <see cref="ControllerModel"/> for the given <see cref="TypeInfo"/>. /// </summary> /// <param name="typeInfo">The <see cref="TypeInfo"/>.</param> /// <returns>A <see cref="ControllerModel"/> for the given <see cref="TypeInfo"/>.</returns> internal ControllerModel CreateControllerModel(TypeInfo typeInfo) { if (typeInfo == null) { throw new ArgumentNullException(nameof(typeInfo)); } // For attribute routes on a controller, we want to support 'overriding' routes on a derived // class. So we need to walk up the hierarchy looking for the first class to define routes. // // Then we want to 'filter' the set of attributes, so that only the effective routes apply. var currentTypeInfo = typeInfo; var objectTypeInfo = typeof(object).GetTypeInfo(); IRouteTemplateProvider[] routeAttributes; do { routeAttributes = currentTypeInfo .GetCustomAttributes(inherit: false) .OfType <IRouteTemplateProvider>() .ToArray(); if (routeAttributes.Length > 0) { // Found 1 or more route attributes. break; } currentTypeInfo = currentTypeInfo.BaseType.GetTypeInfo(); }while (currentTypeInfo != objectTypeInfo); // CoreCLR returns IEnumerable<Attribute> from GetCustomAttributes - the OfType<object> // is needed to so that the result of ToArray() is object var attributes = typeInfo.GetCustomAttributes(inherit: true); // This is fairly complicated so that we maintain referential equality between items in // ControllerModel.Attributes and ControllerModel.Attributes[*].Attribute. var filteredAttributes = new List <object>(); foreach (var attribute in attributes) { if (attribute is IRouteTemplateProvider) { // This attribute is a route-attribute, leave it out. } else { filteredAttributes.Add(attribute); } } filteredAttributes.AddRange(routeAttributes); attributes = filteredAttributes.ToArray(); var controllerModel = new ControllerModel(typeInfo, attributes); AddRange(controllerModel.Selectors, CreateSelectors(attributes)); controllerModel.ControllerName = typeInfo.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) ? typeInfo.Name.Substring(0, typeInfo.Name.Length - "Controller".Length) : typeInfo.Name; AddRange(controllerModel.Filters, attributes.OfType <IFilterMetadata>()); foreach (var routeValueProvider in attributes.OfType <IRouteValueProvider>()) { controllerModel.RouteValues.Add(routeValueProvider.RouteKey, routeValueProvider.RouteValue); } var apiVisibility = attributes.OfType <IApiDescriptionVisibilityProvider>().FirstOrDefault(); if (apiVisibility != null) { controllerModel.ApiExplorer.IsVisible = !apiVisibility.IgnoreApi; } var apiGroupName = attributes.OfType <IApiDescriptionGroupNameProvider>().FirstOrDefault(); if (apiGroupName != null) { controllerModel.ApiExplorer.GroupName = apiGroupName.GroupName; } // Controllers can implement action filter and result filter interfaces. We add // a special delegating filter implementation to the pipeline to handle it. // // This is needed because filters are instantiated before the controller. if (typeof(IAsyncActionFilter).GetTypeInfo().IsAssignableFrom(typeInfo) || typeof(IActionFilter).GetTypeInfo().IsAssignableFrom(typeInfo)) { controllerModel.Filters.Add(new ControllerActionFilter()); } if (typeof(IAsyncResultFilter).GetTypeInfo().IsAssignableFrom(typeInfo) || typeof(IResultFilter).GetTypeInfo().IsAssignableFrom(typeInfo)) { controllerModel.Filters.Add(new ControllerResultFilter()); } return(controllerModel); }
/// <inheritdoc /> public bool IsSatisfiedBy(ControllerModel controller) { Arg.NotNull(controller, nameof(controller)); return(controller.ControllerType.IsODataController()); }
/// <summary> /// Sets the property associated with the controller model. /// </summary> /// <typeparam name="T">The <see cref="Type">type</see> and key of the property.</typeparam> /// <param name="controller">The <see cref="ControllerModel">model</see> to set the property for.</param> /// <param name="value">The property value to set.</param> public static void SetProperty <T>(this ControllerModel controller, T value) { Arg.NotNull(controller, nameof(controller)); controller.Properties.SetOrRemove(typeof(T), value); }
/// <summary> /// Gets the property associated with the controller model. /// </summary> /// <typeparam name="T">The <see cref="Type">type</see> and key of the property.</typeparam> /// <param name="controller">The <see cref="ControllerModel">model</see> to get the property from.</param> /// <returns>The property value of <typeparamref name="T"/> or its default value.</returns> public static T GetProperty <T>(this ControllerModel controller) { Arg.NotNull(controller, nameof(controller)); return(controller.Properties.GetOrDefault(typeof(T), default(T))); }
public void Apply(ControllerModel controller) { controller.Properties.Add("feature", GetFeatureName(controller.ControllerType)); }
public void Apply(ControllerModel controller) { ControllersCache.Add(controller.ControllerType.AsType()); }
protected virtual bool ShouldApply(ControllerModel controller) => true;
public void Apply(ControllerModel controller) { controller.Properties["license"] = "Copyright (c) .NET Foundation. All rights reserved." + " Licensed under the Apache License, Version 2.0. See License.txt " + "in the project root for license information."; }
/// <summary> /// Sets the property associated with the controller model. /// </summary> /// <typeparam name="T">The <see cref="Type">type</see> and key of the property.</typeparam> /// <param name="controller">The <see cref="ControllerModel">model</see> to set the property for.</param> /// <param name="value">The property value to set.</param> #if NETCOREAPP3_1 public static void SetProperty <T>(this ControllerModel controller, [AllowNull] T value)
private void ConfigureApiExplorer(ControllerModel controller) { if (controller.ApiExplorer.GroupName.IsNullOrEmpty()) { controller.ApiExplorer.GroupName = controller.ControllerName; } if (controller.ApiExplorer.IsVisible == null) { controller.ApiExplorer.IsVisible = true; } foreach (var action in controller.Actions) { ConfigureApiExplorer(action); } }
public static T GetProperty <T>(this ControllerModel controller)
private void ConfigureApiExplorer(ControllerModel controller) { if (controller.ApiExplorer.GroupName.IsNullOrEmpty()) { controller.ApiExplorer.GroupName = controller.ControllerName; } if (controller.ApiExplorer.IsVisible == null) { var controllerType = controller.ControllerType.AsType(); var remoteServiceAtt = ReflectionHelper.GetSingleAttributeOrDefault<RemoteServiceAttribute>(controllerType); if (remoteServiceAtt != null) { controller.ApiExplorer.IsVisible = remoteServiceAtt.IsEnabledFor(controllerType) && remoteServiceAtt.IsMetadataEnabledFor(controllerType); } else { controller.ApiExplorer.IsVisible = true; } } foreach (var action in controller.Actions) { ConfigureApiExplorer(action); } }
private bool IsConventionApplicable(ControllerModel controller) { return controller.Attributes.OfType<IUseWebApiRoutes>().Any(); }
private static void AddControllerPropertyDescriptors(ActionDescriptor actionDescriptor, ControllerModel controller) { actionDescriptor.BoundProperties = controller.ControllerProperties .Where(p => p.BindingInfo != null) .Select(CreateParameterDescriptor) .ToList(); }
public void Apply(ControllerModel model) { model.ControllerName = _controllerName; }