public void CopyConstructor_DoesDeepCopyOfOtherModels() { // Arrange var action = new ActionModel(typeof(TestController).GetMethod(nameof(TestController.Edit)), new List<object>()); var parameter = new ParameterModel(action.ActionMethod.GetParameters()[0], new List<object>()); parameter.Action = action; action.Parameters.Add(parameter); var route = new AttributeRouteModel(new HttpGetAttribute("api/Products")); action.Selectors.Add(new SelectorModel() { AttributeRouteModel = route }); var apiExplorer = action.ApiExplorer; apiExplorer.IsVisible = false; apiExplorer.GroupName = "group1"; // Act var action2 = new ActionModel(action); // Assert Assert.NotSame(action, action2.Parameters[0]); Assert.NotSame(apiExplorer, action2.ApiExplorer); Assert.NotSame(action.Selectors, action2.Selectors); Assert.NotNull(action2.Selectors); Assert.Single(action2.Selectors); Assert.NotSame(route, action2.Selectors[0].AttributeRouteModel); }
private bool IsComplexTypeParameter(ParameterModel parameter) { // No need for information from attributes on the parameter. Just use its type. var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterInfo.ParameterType); return(metadata.IsComplexType); }
/// <summary> /// Creates a <see cref="ParameterModel"/> for the given <see cref="ParameterInfo"/>. /// </summary> /// <param name="parameterInfo">The <see cref="ParameterInfo"/>.</param> /// <returns>A <see cref="ParameterModel"/> for the given <see cref="ParameterInfo"/>.</returns> internal ParameterModel CreateParameterModel(ParameterInfo parameterInfo) { if (parameterInfo == null) { throw new ArgumentNullException(nameof(parameterInfo)); } var attributes = parameterInfo.GetCustomAttributes(inherit: true); BindingInfo bindingInfo; if (_modelMetadataProvider is ModelMetadataProvider modelMetadataProviderBase) { var modelMetadata = modelMetadataProviderBase.GetMetadataForParameter(parameterInfo); bindingInfo = BindingInfo.GetBindingInfo(attributes, modelMetadata); } else { // GetMetadataForParameter should only be used if the user has opted in to the 2.1 behavior. bindingInfo = BindingInfo.GetBindingInfo(attributes); } var parameterModel = new ParameterModel(parameterInfo, attributes) { ParameterName = parameterInfo.Name, BindingInfo = bindingInfo, }; return(parameterModel); }
/// <summary> /// Initializes a new <see cref="ParameterModel"/>. /// </summary> /// <param name="other">The parameter model to copy.</param> public ParameterModel(ParameterModel other) : base(other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } Action = other.Action; ParameterInfo = other.ParameterInfo; }
private static ParameterDescriptor CreateParameterDescriptor(ParameterModel parameterModel) { var parameterDescriptor = new ControllerParameterDescriptor() { Name = parameterModel.ParameterName, ParameterType = parameterModel.ParameterInfo.ParameterType, BindingInfo = parameterModel.BindingInfo, ParameterInfo = parameterModel.ParameterInfo, }; return(parameterDescriptor); }
private bool IsComplexTypeParameter(ParameterModel parameter) { // No need for information from attributes on the parameter. Just use its type. var metadata = _modelMetadataProvider .GetMetadataForType(parameter.ParameterInfo.ParameterType); if (AllowInferringBindingSourceForCollectionTypesAsFromQuery && metadata.IsCollectionType) { return(false); } return(metadata.IsComplexType); }
// Internal for unit testing. internal BindingSource InferBindingSourceForParameter(ParameterModel parameter) { if (ParameterExistsInAnyRoute(parameter.Action, parameter.ParameterName)) { return(BindingSource.Path); } var bindingSource = IsComplexTypeParameter(parameter) ? BindingSource.Body : BindingSource.Query; return(bindingSource); }
public ParameterModel(ParameterModel other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } Action = other.Action; Attributes = new List <object>(other.Attributes); BindingInfo = other.BindingInfo == null ? null : new BindingInfo(other.BindingInfo); ParameterInfo = other.ParameterInfo; ParameterName = other.ParameterName; Properties = new Dictionary <object, object>(other.Properties); }
public ParameterModel(ParameterModel other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } Action = other.Action; Attributes = new List<object>(other.Attributes); BindingInfo = other.BindingInfo == null ? null : new BindingInfo(other.BindingInfo); ParameterInfo = other.ParameterInfo; ParameterName = other.ParameterName; Properties = new Dictionary<object, object>(other.Properties); }
public void OnProvidersExecuting_AppliesConventions() { // Arrange var controllerModel = new ControllerModel(typeof(TestApiController).GetTypeInfo(), new[] { new ApiControllerAttribute() }) { Selectors = { new SelectorModel { AttributeRouteModel = new AttributeRouteModel() } }, }; var method = typeof(TestApiController).GetMethod(nameof(TestApiController.TestAction)); var actionModel = new ActionModel(method, Array.Empty <object>()) { Controller = controllerModel, }; controllerModel.Actions.Add(actionModel); var parameter = method.GetParameters()[0]; var parameterModel = new ParameterModel(parameter, Array.Empty <object>()) { Action = actionModel, }; actionModel.Parameters.Add(parameterModel); var context = new ApplicationModelProviderContext(new[] { controllerModel.ControllerType }); context.Result.Controllers.Add(controllerModel); var provider = GetProvider(); // Act provider.OnProvidersExecuting(context); // Assert // Verify some of the side-effects of executing API behavior conventions. Assert.True(actionModel.ApiExplorer.IsVisible); Assert.NotEmpty(actionModel.Filters.OfType <ModelStateInvalidFilterFactory>()); Assert.NotEmpty(actionModel.Filters.OfType <ClientErrorResultFilterFactory>()); Assert.Equal(BindingSource.Body, parameterModel.BindingInfo.BindingSource); }
public void CopyConstructor_DoesDeepCopyOfOtherModels() { // Arrange var action = new ActionModel(typeof(TestController).GetMethod(nameof(TestController.Edit)), new List <object>()); var parameter = new ParameterModel(action.ActionMethod.GetParameters()[0], new List <object>()); parameter.Action = action; action.Parameters.Add(parameter); var route = new AttributeRouteModel(new HttpGetAttribute("api/Products")); action.Selectors.Add(new SelectorModel() { AttributeRouteModel = route }); var apiExplorer = action.ApiExplorer; apiExplorer.IsVisible = false; apiExplorer.GroupName = "group1"; // Act var action2 = new ActionModel(action); // Assert Assert.NotSame(action.Parameters, action2.Parameters); Assert.NotNull(action2.Parameters); Assert.Single(action2.Parameters); Assert.NotSame(parameter, action2.Parameters[0]); Assert.NotSame(apiExplorer, action2.ApiExplorer); Assert.NotSame(action.Selectors, action2.Selectors); Assert.NotNull(action2.Selectors); Assert.Single(action2.Selectors); Assert.NotSame(action.Selectors[0], action2.Selectors[0]); Assert.NotSame(route, action2.Selectors[0].AttributeRouteModel); Assert.NotSame(action, action2.Parameters[0].Action); Assert.Same(action2, action2.Parameters[0].Action); }
public void Apply(ParameterModel parameter) { parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo(); parameter.BindingInfo.BinderModelName = "ChangedParameter"; }
public void CopyConstructor_CopiesAllProperties() { // Arrange var parameter = new ParameterModel(typeof(TestController).GetMethod("Edit").GetParameters()[0], new List <object>() { new FromBodyAttribute() }); parameter.Action = new ActionModel(typeof(TestController).GetMethod("Edit"), new List <object>()); parameter.BindingInfo = new BindingInfo() { BindingSource = BindingSource.Body }; parameter.ParameterName = "id"; parameter.Properties.Add(new KeyValuePair <object, object>("test key", "test value")); // Act var parameter2 = new ParameterModel(parameter); // Assert foreach (var property in typeof(ParameterModel).GetProperties()) { if (property.Name.Equals("BindingInfo")) { // This test excludes other mutable objects on purpose because we deep copy them. continue; } var value1 = property.GetValue(parameter); var value2 = property.GetValue(parameter2); 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 <object, object>).IsAssignableFrom(property.PropertyType)) { Assert.Equal(value1, value2); // Ensure non-default value Assert.NotEmpty((IDictionary <object, object>)value1); } else if (property.PropertyType.GetTypeInfo().IsValueType || Nullable.GetUnderlyingType(property.PropertyType) != null) { Assert.Equal(value1, value2); // Ensure non-default value Assert.NotEqual(value1, Activator.CreateInstance(property.PropertyType)); } else { Assert.Same(value1, value2); // Ensure non-default value Assert.NotNull(value1); } } }
private bool CanUseFormBodyBinding(ActionModel action, ParameterModel parameter) { if (_configuration.Value.FormBodyBindingIgnoredTypes.Any(t => t.IsAssignableFrom(parameter.ParameterInfo.ParameterType))) { return false; } foreach (var selector in action.Selectors) { if (selector.ActionConstraints == null) { continue; } foreach (var actionConstraint in selector.ActionConstraints) { var httpMethodActionConstraint = actionConstraint as HttpMethodActionConstraint; if (httpMethodActionConstraint == null) { continue; } if (httpMethodActionConstraint.HttpMethods.All(hm => hm.IsIn("GET", "DELETE", "TRACE", "HEAD"))) { return false; } } } return true; }
public void Apply(ParameterModel model) { model.BindingInfo = model.BindingInfo ?? new BindingInfo(); model.BindingInfo.BindingSource = BindingSource.Custom; model.BindingInfo.BinderModelName = "CoolMetadata"; }