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); } }
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); } } }
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); } } } }