void PopulateActionDescriptions(
            HttpActionDescriptor actionDescriptor,
            IHttpRoute route,
            ODataRouteBuilderContext routeBuilderContext,
            string relativePath,
            Collection <VersionedApiDescription> apiDescriptions,
            ApiVersion apiVersion)
        {
            Contract.Requires(actionDescriptor != null);
            Contract.Requires(route != null);
            Contract.Requires(relativePath != null);
            Contract.Requires(apiDescriptions != null);
            Contract.Requires(apiVersion != null);

            var documentation       = DocumentationProvider?.GetDocumentation(actionDescriptor);
            var responseDescription = CreateResponseDescriptionWithRoute(actionDescriptor, route);
            var responseType        = responseDescription.ResponseType ?? responseDescription.DeclaredType;
            var requestFormatters   = new List <MediaTypeFormatter>();
            var responseFormatters  = new List <MediaTypeFormatter>();
            var supportedMethods    = GetHttpMethodsSupportedByAction(route, actionDescriptor);
            var model      = actionDescriptor.GetApiVersionModel();
            var deprecated = !model.IsApiVersionNeutral && model.DeprecatedApiVersions.Contains(apiVersion);

            PopulateMediaTypeFormatters(actionDescriptor, routeBuilderContext.ParameterDescriptions, route, responseType, requestFormatters, responseFormatters);

            foreach (var method in supportedMethods)
            {
                var apiDescription = new VersionedApiDescription()
                {
                    Documentation       = documentation,
                    HttpMethod          = method,
                    RelativePath        = relativePath,
                    ActionDescriptor    = actionDescriptor,
                    Route               = route,
                    ResponseDescription = responseDescription,
                    ApiVersion          = apiVersion,
                    IsDeprecated        = deprecated,
                    Properties          = { [typeof(IEdmModel)] = routeBuilderContext.EdmModel },
                };

                if (routeBuilderContext.EntitySet != null)
                {
                    apiDescription.Properties[typeof(IEdmEntitySet)] = routeBuilderContext.EntitySet;
                }

                if (routeBuilderContext.Operation != null)
                {
                    apiDescription.Properties[typeof(IEdmOperation)] = routeBuilderContext.Operation;
                }

                apiDescription.ParameterDescriptions.AddRange(routeBuilderContext.ParameterDescriptions);
                apiDescription.SupportedRequestBodyFormatters.AddRange(requestFormatters);
                apiDescription.SupportedResponseFormatters.AddRange(responseFormatters);
                PopulateApiVersionParameters(apiDescription, apiVersion);
                apiDescriptions.Add(apiDescription);
            }
        }
Exemplo n.º 2
0
        void ExploreRouteActions(
            IHttpRoute route,
            HttpControllerDescriptor controllerDescriptor,
            IHttpActionSelector actionSelector,
            Collection <VersionedApiDescription> apiDescriptions,
            ApiVersion apiVersion)
        {
            Contract.Requires(route != null);
            Contract.Requires(controllerDescriptor != null);
            Contract.Requires(actionSelector != null);
            Contract.Requires(apiDescriptions != null);
            Contract.Requires(apiVersion != null);

            var actionMapping = actionSelector.GetActionMapping(controllerDescriptor);

            if (actionMapping == null)
            {
                return;
            }

            const string ActionRouteParameterName = null;

            foreach (var grouping in actionMapping)
            {
                foreach (var action in grouping)
                {
                    if (!ShouldExploreAction(ActionRouteParameterName, action, route, apiVersion))
                    {
                        continue;
                    }

                    var parameterDescriptions = CreateParameterDescriptions(action, route);
                    var context = new ODataRouteBuilderContext(
                        Configuration,
                        apiVersion,
                        (ODataRoute)route,
                        action,
                        parameterDescriptions,
                        ModelTypeBuilder,
                        Options);

                    if (context.IsRouteExcluded)
                    {
                        continue;
                    }

                    var relativePath = new ODataRouteBuilder(context).Build();

                    PopulateActionDescriptions(action, route, context, relativePath, apiDescriptions, apiVersion);
                }
            }
        }
Exemplo n.º 3
0
        void PopulateActionDescriptions(HttpActionDescriptor actionDescriptor, IHttpRoute route, string localPath, Collection <VersionedApiDescription> apiDescriptions, ApiVersion apiVersion)
        {
            var parameterDescriptions = CreateParameterDescriptions(actionDescriptor, route);
            var context = new ODataRouteBuilderContext(Configuration, localPath, (ODataRoute)route, actionDescriptor, parameterDescriptions);

            if (context.EdmModel.EntityContainer == null)
            {
                return;
            }

            var relativePath        = new ODataRouteBuilder(context).Build();
            var documentation       = DocumentationProvider?.GetDocumentation(actionDescriptor);
            var responseDescription = CreateResponseDescription(actionDescriptor);
            var responseType        = responseDescription.ResponseType ?? responseDescription.DeclaredType;
            var requestFormatters   = new List <MediaTypeFormatter>();
            var responseFormatters  = new List <MediaTypeFormatter>();
            var supportedMethods    = GetHttpMethodsSupportedByAction(route, actionDescriptor);
            var deprecated          = actionDescriptor.ControllerDescriptor.GetApiVersionModel().DeprecatedApiVersions.Contains(apiVersion);

            PopulateMediaTypeFormatters(actionDescriptor, parameterDescriptions, route, responseType, requestFormatters, responseFormatters);

            foreach (var method in supportedMethods)
            {
                var apiDescription = new VersionedApiDescription()
                {
                    Documentation       = documentation,
                    HttpMethod          = method,
                    RelativePath        = relativePath,
                    ActionDescriptor    = actionDescriptor,
                    Route               = route,
                    ResponseDescription = responseDescription,
                    ApiVersion          = apiVersion,
                    IsDeprecated        = deprecated,
                    Properties          =
                    {
                        [typeof(IEdmModel)] = context.EdmModel
                    }
                };

                apiDescription.ParameterDescriptions.AddRange(parameterDescriptions);
                apiDescription.SupportedRequestBodyFormatters.AddRange(requestFormatters);
                apiDescription.SupportedResponseFormatters.AddRange(responseFormatters);
                PopulateApiVersionParameters(apiDescription, apiVersion);
                apiDescriptions.Add(apiDescription);
            }
        }
 internal ODataRouteBuilder(ODataRouteBuilderContext context)
 {
     Contract.Requires(context != null);
     Context = context;
 }
        void ExploreRouteActions(
            IHttpRoute route,
            HttpControllerDescriptor controllerDescriptor,
            IHttpActionSelector actionSelector,
            Collection <VersionedApiDescription> apiDescriptions,
            ApiVersion apiVersion)
        {
            var actionMapping = actionSelector.GetActionMapping(controllerDescriptor);

            if (actionMapping == null)
            {
                return;
            }

            foreach (var grouping in actionMapping)
            {
                foreach (var action in grouping)
                {
                    if (!ShouldExploreAction(actionRouteParameterValue: string.Empty, action, route, apiVersion))
                    {
                        continue;
                    }

                    var parameterDescriptions = CreateParameterDescriptions(action, route, apiVersion);
                    var context = new ODataRouteBuilderContext(
                        Configuration,
                        apiVersion,
                        (ODataRoute)route,
                        action,
                        parameterDescriptions,
                        ModelTypeBuilder,
                        Options);

                    if (context.IsRouteExcluded)
                    {
                        continue;
                    }

                    var routeBuilder = new ODataRouteBuilder(context);
                    var relativePath = routeBuilder.Build();

                    if (routeBuilder.IsNavigationPropertyLink)
                    {
                        var routeTemplates = routeBuilder.ExpandNavigationPropertyLinkTemplate(relativePath);
                        var afterPrefix    = string.IsNullOrEmpty(context.RoutePrefix) ? 0 : context.RoutePrefix !.Length + 1;

                        for (var i = 0; i < routeTemplates.Count; i++)
                        {
                            relativePath = routeTemplates[i];

                            var queryParamAdded = false;

                            if (action.ActionName.StartsWith("DeleteRef", Ordinal))
                            {
                                var handler      = context.PathTemplateHandler;
                                var pathTemplate = handler.ParseTemplate(relativePath.Substring(afterPrefix), context.Services);
                                var template     = pathTemplate?.Segments.OfType <NavigationPropertyLinkSegmentTemplate>().FirstOrDefault();

                                if (template != null)
                                {
                                    var property = template.Segment.NavigationProperty;

                                    if (property.TargetMultiplicity() == EdmMultiplicity.Many)
                                    {
                                        routeBuilder.AddOrReplaceRefIdQueryParameter();
                                        queryParamAdded = true;
                                    }
                                }
                            }

                            PopulateActionDescriptions(action, route, context, relativePath, apiDescriptions, apiVersion);

                            if (queryParamAdded)
                            {
                                for (var j = 0; j < context.ParameterDescriptions.Count; j++)
                                {
                                    var parameter = context.ParameterDescriptions[j];

                                    if (parameter.Name == "$id" || parameter.Name == "id")
                                    {
                                        context.ParameterDescriptions.RemoveAt(j);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        PopulateActionDescriptions(action, route, context, relativePath, apiDescriptions, apiVersion);
                    }
                }
            }
        }