private IList <ApiParameterDescription> GetParameters(ApiParameterContext context) { // First, get parameters from the model-binding/parameter-binding side of the world. if (context.ActionDescriptor.Parameters != null) { foreach (var actionParameter in context.ActionDescriptor.Parameters) { var visitor = new PseudoModelBindingVisitor(context, actionParameter); ModelMetadata metadata = null; if (_mvcOptions.AllowValidatingTopLevelNodes && actionParameter is ControllerParameterDescriptor controllerParameterDescriptor && _modelMetadataProvider is ModelMetadataProvider provider) { // The default model metadata provider derives from ModelMetadataProvider // and can therefore supply information about attributes applied to parameters. metadata = provider.GetMetadataForParameter(controllerParameterDescriptor.ParameterInfo); } else { // For backward compatibility, if there's a custom model metadata provider that // only implements the older IModelMetadataProvider interface, access the more // limited metadata information it supplies. In this scenario, validation attributes // are not supported on parameters. metadata = _modelMetadataProvider.GetMetadataForType(actionParameter.ParameterType); } var bindingContext = ApiParameterDescriptionContext.GetContext( metadata, actionParameter.BindingInfo, propertyName: actionParameter.Name); visitor.WalkParameter(bindingContext); }
private IList <ApiParameterDescription> GetParameters(ApiParameterContext context) { // First, get parameters from the model-binding/parameter-binding side of the world. if (context.ActionDescriptor.Parameters != null) { foreach (var actionParameter in context.ActionDescriptor.Parameters) { var visitor = new PseudoModelBindingVisitor(context, actionParameter); var metadata = _modelMetadataProvider.GetMetadataForType(actionParameter.ParameterType); var bindingContext = ApiParameterDescriptionContext.GetContext( metadata, actionParameter.BindingInfo, propertyName: actionParameter.Name); visitor.WalkParameter(bindingContext); } } if (context.ActionDescriptor.BoundProperties != null) { foreach (var actionParameter in context.ActionDescriptor.BoundProperties) { var visitor = new PseudoModelBindingVisitor(context, actionParameter); var modelMetadata = context.MetadataProvider.GetMetadataForProperty( containerType: context.ActionDescriptor.ControllerTypeInfo.AsType(), propertyName: actionParameter.Name); var bindingContext = ApiParameterDescriptionContext.GetContext( modelMetadata, actionParameter.BindingInfo, propertyName: actionParameter.Name); visitor.WalkParameter(bindingContext); } } for (var i = context.Results.Count - 1; i >= 0; i--) { // Remove any 'hidden' parameters. These are things that can't come from user input, // so they aren't worth showing. if (!context.Results[i].Source.IsFromRequest) { context.Results.RemoveAt(i); } } // Next, we want to join up any route parameters with those discovered from the action's parameters. var routeParameters = new Dictionary <string, ApiParameterRouteInfo>(StringComparer.OrdinalIgnoreCase); foreach (var routeParameter in context.RouteParameters) { routeParameters.Add(routeParameter.Name, CreateRouteInfo(routeParameter)); } foreach (var parameter in context.Results) { if (parameter.Source == BindingSource.Path || parameter.Source == BindingSource.ModelBinding || parameter.Source == BindingSource.Custom) { ApiParameterRouteInfo routeInfo; if (routeParameters.TryGetValue(parameter.Name, out routeInfo)) { parameter.RouteInfo = routeInfo; routeParameters.Remove(parameter.Name); if (parameter.Source == BindingSource.ModelBinding && !parameter.RouteInfo.IsOptional) { // If we didn't see any information about the parameter, but we have // a route parameter that matches, let's switch it to path. parameter.Source = BindingSource.Path; } } } } // Lastly, create a parameter representation for each route parameter that did not find // a partner. foreach (var routeParameter in routeParameters) { context.Results.Add(new ApiParameterDescription() { Name = routeParameter.Key, RouteInfo = routeParameter.Value, Source = BindingSource.Path, }); } return(context.Results); }