Beispiel #1
0
 public void OnProvidersExecuting(ApiDescriptionProviderContext context)
 {
     foreach (var parameter in context.Results.SelectMany(x => x.ParameterDescriptions).Where(x => x.Source.Id == "Query"))
     {
         parameter.Name = parameter.Name.ToLower();
     }
 }
Beispiel #2
0
        /// <summary>
        /// Sets the response type in the api description to a mapped type as configured in the mapping configuration or the filter itself.
        /// </summary>
        /// <param name="context">The context</param>
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            foreach (var apiDescription in context.Results)
            {
                var mapResultAttribute = apiDescription.ActionDescriptor.GetFilter <MapResultAttribute>();

                if (mapResultAttribute != null)
                {
                    foreach (var responseType in apiDescription.SupportedResponseTypes)
                    {
                        if (responseType.StatusCode != (int)HttpStatusCode.Created && responseType.StatusCode != (int)HttpStatusCode.OK)
                        {
                            break;
                        }

                        var sourceType = mapResultAttribute.SourceType ?? responseType.Type;
                        if (sourceType == null)
                        {
                            // I guess this shouldn't happen because it's kinda bad practice returning an Ok or Created without return type.
                            // Nevertheless, this isn't the AvoidBadPractices toolbox :-)
                            // Without this null check, the Helper.MapType function beneath would return an ArgumentNullException, which is also not something we would want.
                            break;
                        }

                        var destinationType = mapResultAttribute.DestinationType ?? Helper.MapType(sourceType, true);

                        responseType.Type = destinationType;
                    }
                }
            }
        }
Beispiel #3
0
 public void OnProvidersExecuting(ApiDescriptionProviderContext context)
 {
     foreach (var action in context.Actions.Select(FromActionDescription).OfType <ApiDescription>())
     {
         context.Results.Add(action);
     }
 }
 public void OnProvidersExecuting(ApiDescriptionProviderContext context)
 {
     foreach (ApiParameterDescription parameter in context.Results.SelectMany(x => x.ParameterDescriptions).Where(x => x.Source.Id == "Query" || x.Source.Id == "ModelBinding"))
     {
         parameter.Name = parameter.Name.ToSnakeCase();
     }
 }
Beispiel #5
0
        public ApiDescriptionProviderContext CreateContext(bool applyDefaultApiDescriptionProvider = true)
        {
            var getAllActionDescriptor = ActionDescriptorHelper.CreateActionDescriptor("GetAll", typeof(ValuesController));
            var getActionDescriptor    = ActionDescriptorHelper.CreateActionDescriptor("Get", typeof(ValuesController));
            var addActionDescriptor    = ActionDescriptorHelper.CreateActionDescriptor("Add", typeof(ValuesController));
            var updateActionDescriptor = ActionDescriptorHelper.CreateActionDescriptor("Update", typeof(ValuesController));
            var deleteActionDescriptor = ActionDescriptorHelper.CreateActionDescriptor("Delete", typeof(ValuesController));

            var actionDescriptorList = new List <ActionDescriptor>(new[] {
                getAllActionDescriptor,
                getActionDescriptor,
                addActionDescriptor,
                updateActionDescriptor,
                deleteActionDescriptor
            }).AsReadOnly();
            var context = new ApiDescriptionProviderContext(actionDescriptorList);

            if (applyDefaultApiDescriptionProvider)
            {
                var defaultApiDescriptionProvider = ApiDescriptionProviderHelper.CreateDefaultApiDescriptionProvider();
                defaultApiDescriptionProvider.OnProvidersExecuting(context);
            }

            return(context);
        }
        private static ApiDescriptionGroupCollection GetApiDescriptionGroups(Type controllerType)
        {
            var options = Mock.Of <IOptions <MvcOptions> >(m => m.Value == new MvcOptions());
            var applicationPartManager = new ApplicationPartManager();

            applicationPartManager.FeatureProviders.Add(new TestControllerFeatureProvider(controllerType));

            var actionDescriptorProvider = new ControllerActionDescriptorProvider(
                applicationPartManager,
                new IApplicationModelProvider[]
            {
                new DefaultApplicationModelProvider(options, new EmptyModelMetadataProvider()),
                new MakeApiExplorerVisibleProvider(),
            },
                options);

            var actionDescriptorProviderContext = new ActionDescriptorProviderContext();

            actionDescriptorProvider.OnProvidersExecuting(actionDescriptorProviderContext);

            var apiDescriptionProvider = new DefaultApiDescriptionProvider(options, Mock.Of <IInlineConstraintResolver>(),
                                                                           new EmptyModelMetadataProvider(), new ActionResultTypeMapper());

            var apiDescriptionProviderContext = new ApiDescriptionProviderContext(actionDescriptorProviderContext.Results.ToArray());

            apiDescriptionProvider.OnProvidersExecuting(apiDescriptionProviderContext);

            var groups = apiDescriptionProviderContext.Results.GroupBy(a => a.GroupName)
                         .Select(g => new ApiDescriptionGroup(g.Key, g.ToArray()))
                         .ToArray();

            return(new ApiDescriptionGroupCollection(groups, version: 1));
        }
        private IReadOnlyList <ApiDescription> GetApiDescriptions()
        {
            var actionDescriptors = this.CreateActionDescriptors();
            var context           = new ApiDescriptionProviderContext(actionDescriptors);

            var options = new MvcOptions();

            options.InputFormatters.Add(
                new JsonInputFormatter(Mock.Of <ILogger>(), new JsonSerializerSettings(), ArrayPool <char> .Shared, new DefaultObjectPoolProvider(), false)
                );
            options.OutputFormatters.Add(new JsonOutputFormatter(new JsonSerializerSettings(), ArrayPool <char> .Shared));

            var constraintResolver = new Mock <IInlineConstraintResolver>();

            constraintResolver.Setup(i => i.ResolveConstraint("int")).Returns(new IntRouteConstraint());

            var provider = new DefaultApiDescriptionProvider(
                Options.Create(options),
                constraintResolver.Object,
                CreateModelMetadataProvider()
                , new ActionResultTypeMapper());

            provider.OnProvidersExecuting(context);
            provider.OnProvidersExecuted(context);
            return(new ReadOnlyCollection <ApiDescription>(context.Results));
        }
Beispiel #8
0
        public void OnProvidersExecuted(ApiDescriptionProviderContext context)
        {
            var typeProvider = new DynamicTypeBuilder(typeBindingRepo);

            foreach (var route in voyagerRoutes)
            {
                var descriptor = new ApiDescription
                {
                    HttpMethod       = route.Method,
                    ActionDescriptor = new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor
                    {
                        RouteValues = new Dictionary <string, string>()
                    },
                    RelativePath = route.Template,
                };
                var validBindingSources = new[] { BindingSource.Form, BindingSource.Query, BindingSource.Path };
                foreach (var property in typeBindingRepo.GetProperties(route.RequestType))
                {
                    if (validBindingSources.Contains(property.BindingSource))
                    {
                        descriptor.ParameterDescriptions.Add(new ApiParameterDescription
                        {
                            Name   = property.Name.ToLower(),
                            Type   = property.Property.PropertyType,
                            Source = property.BindingSource,
                            ParameterDescriptor = new Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor {
                                Name = property.Description
                            }
                        });
                    }
                }

                var requestBodyType = typeProvider.CreateBodyType(route.RequestType);
                if (requestBodyType != null)
                {
                    var requestModel = modelMetadataProvider.GetMetadataForType(requestBodyType);
                    descriptor.ParameterDescriptions.Add(new ApiParameterDescription
                    {
                        Type          = requestBodyType,
                        Source        = BindingSource.Body,
                        ModelMetadata = requestModel
                    });
                }
                descriptor.ActionDescriptor.RouteValues["controller"] = GetTopRoute(route.Template);
                descriptor.SupportedRequestFormats.Add(new ApiRequestFormat {
                    MediaType = "application/json"
                });
                var responseType = GetResponseType(route.RequestType);
                if (responseType != null)
                {
                    var response = new ApiResponseType();
                    response.ApiResponseFormats.Add(new ApiResponseFormat {
                        MediaType = "application/json"
                    });
                    response.ModelMetadata = modelMetadataProvider.GetMetadataForType(responseType);
                    descriptor.SupportedResponseTypes.Add(response);
                }
                context.Results.Add(descriptor);
            }
        }
        private ApiDescriptionProviderContext GetApiDescriptions(IReadOnlyList <ActionDescriptor> actionDescriptors)
        {
            if (actionDescriptors == null)
            {
                return(new ApiDescriptionProviderContext(new List <ActionDescriptor>()));
            }

            foreach (var action in actionDescriptors)
            {
                // This is required in order for OnProvidersExecuting() to work
                var apiExplorerActionData = new ApiDescriptionActionData()
                {
                    GroupName = "Steeltoe"
                };

                action.SetProperty(apiExplorerActionData);
            }

            var context = new ApiDescriptionProviderContext(actionDescriptors);

            foreach (var provider in _apiDescriptionProviders)
            {
                provider.OnProvidersExecuting(context);
            }

            return(context);
        }
 /// <inheritdoc />
 public void OnProvidersExecuting([NotNull] ApiDescriptionProviderContext context)
 {
     if (context == null)
     {
         throw new ArgumentNullException(nameof(context));
     }
 }
Beispiel #11
0
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            foreach (var description in context.Results)
            {
                var relativePathSplit = description.RelativePath.Split('/');

                var newRelativePathBuilder = new StringBuilder();
                for (var i = 0; i < relativePathSplit.Length; i++)
                {
                    var portion = relativePathSplit[i];

                    if (!portion.StartsWith("{") || !portion.EndsWith("}"))
                    {
                        newRelativePathBuilder.Append(portion.ToLowerInvariant());
                    }
                    else
                    {
                        newRelativePathBuilder.Append(portion);
                    }

                    if (i < relativePathSplit.Length - 1)
                    {
                        newRelativePathBuilder.Append("/");
                    }
                }

                description.RelativePath = newRelativePathBuilder.ToString();
            }
        }
        /// <inheritdoc />
        /// <remarks>
        /// Removes the <see cref="ExceptionFilter"/> from unqualified candidates.
        /// </remarks>
        public void OnProvidersExecuted([NotNull] ApiDescriptionProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            foreach (ApiDescription description in context.Results)
            {
                if (description.HttpMethod == HttpMethod)
                {
                    continue;
                }

                ApiResponseType[] removals =
                    description.SupportedResponseTypes
                    .Where(x => ExceptionFilter.Equals(x))
                    .ToArray();

                foreach (ApiResponseType responseType in removals)
                {
                    description.SupportedResponseTypes.Remove(responseType);
                }
            }
        }
Beispiel #13
0
    public void OnProvidersExecuting(ApiDescriptionProviderContext context)
    {
        var endpoints = _endpointDataSource.Endpoints;

        foreach (var endpoint in endpoints)
        {
            if (endpoint is RouteEndpoint routeEndpoint)
            {
                var grpcMetadata = endpoint.Metadata.GetMetadata <GrpcJsonTranscodingMetadata>();

                if (grpcMetadata != null)
                {
                    var httpRule         = grpcMetadata.HttpRule;
                    var methodDescriptor = grpcMetadata.MethodDescriptor;

                    if (ServiceDescriptorHelpers.TryResolvePattern(grpcMetadata.HttpRule, out var pattern, out var verb))
                    {
                        var apiDescription = CreateApiDescription(routeEndpoint, httpRule, methodDescriptor, pattern, verb);

                        context.Results.Add(apiDescription);
                    }
                }
            }
        }
    }
Beispiel #14
0
        private IReadOnlyList <ApiDescription> GetApiDescriptions()
        {
            var context = new ApiDescriptionProviderContext(_actionDescriptors);

            var options = new MvcOptions();

            options.InputFormatters.Add(new JsonInputFormatter(new Mock <ILogger>().Object, new JsonSerializerSettings(), ArrayPool <char> .Shared, new DefaultObjectPoolProvider()));
            options.OutputFormatters.Add(new JsonOutputFormatter(new JsonSerializerSettings(), ArrayPool <char> .Shared));

            var optionsAccessor = new Mock <IOptions <MvcOptions> >();

            optionsAccessor.Setup(o => o.Value).Returns(options);

            var constraintResolver = new Mock <IInlineConstraintResolver>();

            constraintResolver.Setup(i => i.ResolveConstraint("int")).Returns(new IntRouteConstraint());

            var provider = new DefaultApiDescriptionProvider(
                optionsAccessor.Object,
                constraintResolver.Object,
                CreateDefaultProvider()
                );

            provider.OnProvidersExecuting(context);
            provider.OnProvidersExecuted(context);
            return(new ReadOnlyCollection <ApiDescription>(context.Results));
        }
    /// <inheritdoc />
    public void OnProvidersExecuting(ApiDescriptionProviderContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        foreach (var action in context.Actions.OfType <ControllerActionDescriptor>())
        {
            if (action.AttributeRouteInfo != null && action.AttributeRouteInfo.SuppressPathMatching)
            {
                continue;
            }

            // ApiDescriptionActionData is only added to the ControllerActionDescriptor if
            // the action is marked as `IsVisible` to the ApiExplorer. This null-check is
            // effectively asserting if the endpoint should be generated into the final
            // OpenAPI metadata.
            var extensionData = action.GetProperty <ApiDescriptionActionData>();
            if (extensionData != null)
            {
                var httpMethods = GetHttpMethods(action);
                foreach (var httpMethod in httpMethods)
                {
                    context.Results.Add(CreateApiDescription(action, httpMethod, GetGroupName(action, extensionData)));
                }
            }
        }
    }
        private IReadOnlyList <ApiDescription> GetApiDescriptions()
        {
            var context = new ApiDescriptionProviderContext(_actionDescriptors);

            var options = new MvcOptions();

            options.OutputFormatters.Add(new JsonOutputFormatter());

            var optionsAccessor = new Mock <IOptions <MvcOptions> >();

            optionsAccessor.Setup(o => o.Value).Returns(options);

            var constraintResolver = new Mock <IInlineConstraintResolver>();

            constraintResolver.Setup(i => i.ResolveConstraint("int")).Returns(new IntRouteConstraint());

            var provider = new DefaultApiDescriptionProvider(
                optionsAccessor.Object,
                constraintResolver.Object,
                CreateModelMetadataProvider()
                );

            provider.OnProvidersExecuting(context);
            provider.OnProvidersExecuted(context);
            return(new ReadOnlyCollection <ApiDescription>(context.Results));
        }
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            // will reuse some properties created by default provider
            var existingDescriptions = context.Results
                                       .Where(x => x.ActionDescriptor.GetProperty <MethodMetadata>() != null)
                                       .ToDictionary(x => x.ActionDescriptor);

            // clean up after default provider
            foreach (var apiDescription in existingDescriptions)
            {
                context.Results.Remove(apiDescription.Value);
            }

            var jsonRpcActions = context.Actions.Where(x => x.GetProperty <MethodMetadata>() != null);

            foreach (var action in jsonRpcActions)
            {
                if (!existingDescriptions.TryGetValue(action, out var originalDescription))
                {
                    // action was excluded from Results, eg because ignored with [ApiExplorerSettings(IgnoreApi = true)]
                    continue;
                }
                var actionXmlDoc          = (originalDescription.ActionDescriptor as ControllerActionDescriptor).MethodInfo.GetXmlDocsElement();
                var methodMetadata        = action.GetProperty <MethodMetadata>();
                var actionName            = methodMatcher.GetActionName(methodMetadata);
                var defaultSerializerType = options.DefaultMethodOptions.RequestSerializer;

                var apiDescription = new ApiDescription()
                {
                    ActionDescriptor        = action,
                    HttpMethod              = HttpMethods.Post,
                    RelativePath            = GetUniquePath(originalDescription.RelativePath, actionName),
                    SupportedRequestFormats =
                    {
                        JsonRequestFormat
                    },
                    SupportedResponseTypes =
                    {
                        // Single because more than 1 response type is a complicated scenario, don't know how to deal with it
                        WrapResponseType(actionName, originalDescription.SupportedResponseTypes.SingleOrDefault()?.Type, methodMetadata)
                    },
                    GroupName  = Utils.GetSwaggerFriendlyDocumentName(methodMetadata.MethodOptions.RequestSerializer, defaultSerializerType),
                    Properties =
                    {
                        [ApiExplorerConstants.ActionNameProperty] = actionName,
                    }
                };

                foreach (var parameterDescription in GetParameterDescriptions(actionName, originalDescription, methodMetadata, actionXmlDoc))
                {
                    apiDescription.ParameterDescriptions.Add(parameterDescription);
                }

                context.Results.Add(apiDescription);
            }
        }
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            var endpoints = _endpointDataSource.Endpoints;

            foreach (var endpoint in endpoints)
            {
                if (endpoint is RouteEndpoint routeEndpoint)
                {
                    var apiDescription = CreateApiDescription(routeEndpoint);

                    context.Results.Add(apiDescription);
                }
            }
        }
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            var endpoints = _endpointDataSource.Endpoints;

            foreach (var endpoint in endpoints)
            {
                if (IsValidEndpoint(endpoint, out var routeEndpoint, out var methodModel, out var httpMethodAttribute))
                {
                    var apiDescription = CreateApiDescription(routeEndpoint, methodModel, httpMethodAttribute);

                    context.Results.Add(apiDescription);
                }
            }
        }
Beispiel #20
0
 /// <summary>
 /// Execute for second pass for OData API description.
 /// </summary>
 /// <param name="context">The ApiDescriptionProviderContext.</param>
 public void OnProvidersExecuted(ApiDescriptionProviderContext context)
 {
     foreach (var action in context?.Actions)
     {
         IODataRoutingMetadata odataMetadata = action.EndpointMetadata.OfType <IODataRoutingMetadata>().FirstOrDefault();
         if (odataMetadata != null)
         {
             ApiDescription apiDes = context.Results.FirstOrDefault(r => r.ActionDescriptor == action);
             if (apiDes != null)
             {
                 apiDes.RelativePath = odataMetadata.TemplateDisplayName;
             }
         }
     }
 }
        private ApiDescriptionProviderContext GetApiDescriptions(IReadOnlyList <ActionDescriptor> actionDescriptors)
        {
            if (actionDescriptors == null)
            {
                return(new ApiDescriptionProviderContext(new List <ActionDescriptor>()));
            }

            var context = new ApiDescriptionProviderContext(actionDescriptors);

            foreach (var provider in _apiDescriptionProviders)
            {
                provider.OnProvidersExecuting(context);
            }

            return(context);
        }
Beispiel #22
0
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            foreach (var apiDescription in context.Results)
            {
                if (apiDescription.SupportedRequestFormats.Any(x => x.MediaType == "application/json"))
                {
                    continue;
                }

                apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat()
                {
                    Formatter = null,
                    MediaType = "application/json"
                });
            }
        }
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            // Update the api description
            foreach (var apiDescription in context.Results)
            {
                var mapBodyAttribute = apiDescription.ActionDescriptor.GetCustomControllerActionAttribute <MapBodyAttribute>();

                if (mapBodyAttribute != null)
                {
                    var bodyParam = apiDescription.ParameterDescriptions.FirstOrDefault(x => x.Source.Id.Equals("Body"));
                    if (bodyParam != null)
                    {
                        bodyParam.Type = mapBodyAttribute.SourceType;
                    }
                }
            }
        }
        /// <summary>
        /// Sets the body parameter type in the api description to a mapped type specified in the MapFromBody filter.
        /// </summary>
        /// <param name="context">The context</param>
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            foreach (var apiDescription in context.Results)
            {
                ControllerParameterDescriptor mapFromBodyParameter;
                MapFromBodyAttribute          mapFromBodyAttribute;
                apiDescription.ActionDescriptor.GetMapFromBodyParameter(out mapFromBodyParameter, out mapFromBodyAttribute);

                if (mapFromBodyParameter != null && mapFromBodyAttribute != null)
                {
                    var resultParameter = apiDescription.ParameterDescriptions.FirstOrDefault(x => x.Source.Id.Equals("Body") && x.Name == mapFromBodyParameter.Name);
                    if (resultParameter != null)
                    {
                        resultParameter.Type = mapFromBodyAttribute.SourceType;
                    }
                }
            }
        }
Beispiel #25
0
        public void OnProvidersExecuted(ApiDescriptionProviderContext context)
        {
            var endpoints = _endpointDataSource.Endpoints;

            for (var i = 0; i < endpoints.Count; i++)
            {
                if (!(endpoints[i] is RouteEndpoint routeEndpoint))
                {
                    continue;
                }

                var apiDescription = ApiDescriptionGenerator.TryCreateApiDescription(routeEndpoint);
                if (apiDescription != null)
                {
                    context.Results.Add(apiDescription);
                }
            }
        }
Beispiel #26
0
        /// <inheritdoc />
        public void OnProvidersExecuting(ApiDescriptionProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            foreach (var result in context.Results)
            {
                foreach (var parameterDescription in result.ParameterDescriptions)
                {
                    if (typeof(IJsonPatchDocument).GetTypeInfo().IsAssignableFrom(parameterDescription.Type))
                    {
                        parameterDescription.Type          = typeof(Operation[]);
                        parameterDescription.ModelMetadata = _modelMetadataProvider.GetMetadataForType(typeof(Operation[]));
                    }
                }
            }
        }
Beispiel #27
0
    public void OnProvidersExecuting(ApiDescriptionProviderContext context)
    {
        foreach (var apiResponseType in GetApiResponseTypes())
        {
            foreach (var result in context.Results.Where(IsRemoteService))
            {
                var actionProducesResponseTypeAttributes =
                    ReflectionHelper.GetAttributesOfMemberOrDeclaringType <ProducesResponseTypeAttribute>(
                        result.ActionDescriptor.GetMethodInfo());
                if (actionProducesResponseTypeAttributes.Any(x => x.StatusCode == apiResponseType.StatusCode))
                {
                    continue;
                }

                result.SupportedResponseTypes.AddIfNotContains(x => x.StatusCode == apiResponseType.StatusCode,
                                                               () => apiResponseType);
            }
        }
    }
        protected internal ApplicationMappings GetApplicationMappings(HttpContext context)
        {
            IDictionary <string, IList <MappingDescription> > desc = new Dictionary <string, IList <MappingDescription> >();

            if (_actionDescriptorCollectionProvider != null)
            {
                ApiDescriptionProviderContext apiContext = GetApiDescriptions(_actionDescriptorCollectionProvider?.ActionDescriptors?.Items);
                desc = GetMappingDescriptions(apiContext);
            }

            if (_routeMappings != null)
            {
                AddRouteMappingsDescriptions(_routeMappings, desc);
            }

            var contextMappings = new ContextMappings(desc);

            return(new ApplicationMappings(contextMappings));
        }
Beispiel #29
0
    private ApiDescriptionGroupCollection GetCollection(ActionDescriptorCollection actionDescriptors)
    {
        var context = new ApiDescriptionProviderContext(actionDescriptors.Items);

        foreach (var provider in _apiDescriptionProviders)
        {
            provider.OnProvidersExecuting(context);
        }

        for (var i = _apiDescriptionProviders.Length - 1; i >= 0; i--)
        {
            _apiDescriptionProviders[i].OnProvidersExecuted(context);
        }

        var groups = context.Results
                     .GroupBy(d => d.GroupName)
                     .Select(g => new ApiDescriptionGroup(g.Key, g.ToArray()))
                     .ToArray();

        return(new ApiDescriptionGroupCollection(groups, actionDescriptors.Version));
    }
        private ApiDescriptionGroupCollection GetCollection(ActionDescriptorCollection actionDescriptors)
        {
            var context = new ApiDescriptionProviderContext(actionDescriptors.Items);

            foreach (var provider in _apiDescriptionProviders)
            {
                provider.OnProvidersExecuting(context);
            }

            for (var i = _apiDescriptionProviders.Length - 1; i >= 0; i--)
            {
                _apiDescriptionProviders[i].OnProvidersExecuted(context);
            }

            var groups = context.Results
                .GroupBy(d => d.GroupName)
                .Select(g => new ApiDescriptionGroup(g.Key, g.ToArray()))
                .ToArray();

            return new ApiDescriptionGroupCollection(groups, actionDescriptors.Version);
        }
 public void OnProvidersExecuted(ApiDescriptionProviderContext context)
 {
     foreach (ApiDescription desc in context.Results)
     {
         foreach (ApiParameterDescription param in desc.ParameterDescriptions)
         {
             // Mvc chokes on parameters with [Required] on them. Give it a hand.
             ControllerParameterDescriptor actionParam = desc.ActionDescriptor.Parameters
                                                         .OfType <ControllerParameterDescriptor>()
                                                         .FirstOrDefault(p => p.Name == param.Name);
             if (actionParam != null)
             {
                 if (actionParam.ParameterInfo.GetCustomAttributes()
                     .Any(a => a.GetType().Name == "RequiredAttribute"))
                 {
                     param.ModelMetadata = new SetRequiredModelMetadata(param.ModelMetadata);
                 }
             }
         }
     }
 }
        private IReadOnlyList<ApiDescription> GetApiDescriptions(
            ActionDescriptor action,
            List<MockFormatter> formatters)
        {
            var context = new ApiDescriptionProviderContext(new ActionDescriptor[] { action });

            var formattersProvider = new Mock<IOutputFormattersProvider>(MockBehavior.Strict);
            formattersProvider.Setup(fp => fp.OutputFormatters).Returns(formatters);

            var constraintResolver = new Mock<IInlineConstraintResolver>();
            constraintResolver.Setup(c => c.ResolveConstraint("int"))
                .Returns(new IntRouteConstraint());

            var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider();

            var provider = new DefaultApiDescriptionProvider(
                formattersProvider.Object,
                constraintResolver.Object,
                modelMetadataProvider);

            provider.OnProvidersExecuting(context);
            provider.OnProvidersExecuted(context);

            return new ReadOnlyCollection<ApiDescription>(context.Results);
        }