internal ODataRouteBuilderContext( HttpConfiguration configuration, ODataRoute route, HttpActionDescriptor actionDescriptor, IReadOnlyList <ApiParameterDescription> parameterDescriptions, ModelTypeBuilder modelTypeBuilder, ODataApiExplorerOptions options) { Contract.Requires(configuration != null); Contract.Requires(route != null); Contract.Requires(actionDescriptor != null); Contract.Requires(parameterDescriptions != null); Contract.Requires(modelTypeBuilder != null); Contract.Requires(options != null); serviceProvider = configuration.GetODataRootContainer(route); EdmModel = serviceProvider.GetRequiredService <IEdmModel>(); AssembliesResolver = configuration.Services.GetAssembliesResolver(); routeAttribute = actionDescriptor.GetCustomAttributes <ODataRouteAttribute>().FirstOrDefault(); RouteTemplate = routeAttribute?.PathTemplate; Route = route; ActionDescriptor = actionDescriptor; ParameterDescriptions = parameterDescriptions; Options = options; UrlKeyDelimiter = configuration.GetUrlKeyDelimiter(); var container = EdmModel.EntityContainer; if (container == null) { IsRouteExcluded = true; return; } EntitySet = container.FindEntitySet(actionDescriptor.ControllerDescriptor.ControllerName); Operation = container.FindOperationImports(actionDescriptor.ActionName).FirstOrDefault()?.Operation ?? EdmModel.FindDeclaredOperations(container.Namespace + "." + actionDescriptor.ActionName).FirstOrDefault(); ActionType = GetActionType(EntitySet, Operation); if (Operation?.IsAction() == true) { ConvertODataActionParametersToTypedModel(modelTypeBuilder, (IEdmAction)Operation); } }
void ConvertODataActionParametersToTypedModel(ModelTypeBuilder modelTypeBuilder, IEdmAction action) { Contract.Requires(modelTypeBuilder != null); Contract.Requires(action != null); var actionParameters = typeof(ODataActionParameters); var apiVersion = new Lazy <ApiVersion>(() => EdmModel.GetAnnotationValue <ApiVersionAnnotation>(EdmModel).ApiVersion); for (var i = 0; i < ParameterDescriptions.Count; i++) { var description = ParameterDescriptions[i]; var parameter = description.ParameterDescriptor; if (actionParameters.IsAssignableFrom(parameter.ParameterType)) { description.ParameterDescriptor = new ODataModelBoundParameterDescriptor(parameter, modelTypeBuilder.NewActionParameters(action, apiVersion.Value)); break; } } }
/// <summary> /// Initializes a new instance of the <see cref="ODataApiExplorer"/> class. /// </summary> /// <param name="configuration">The current <see cref="HttpConfiguration">HTTP configuration</see>.</param> /// <param name="options">The associated <see cref="ODataApiExplorerOptions">API explorer options</see>.</param> public ODataApiExplorer(HttpConfiguration configuration, ODataApiExplorerOptions options) : base(configuration, options) { Options = options; modelTypeBuilder = new ModelTypeBuilder(configuration.Services.GetAssembliesResolver().GetAssemblies()); }
internal static Type SubstituteIfNecessary(this Type type, IServiceProvider serviceProvider, IAssembliesResolver assembliesResolver, ModelTypeBuilder modelTypeBuilder) { Contract.Requires(serviceProvider != null); Contract.Requires(assembliesResolver != null); Contract.Requires(modelTypeBuilder != null); Contract.Ensures(Contract.Result <Type>() != null); var result = type.CanBeSubstituted(); if (!result.IsSupported) { return(type); } var innerType = result.InnerType; var model = serviceProvider.GetRequiredService <IEdmModel>(); var structuredType = innerType.GetStructuredType(model, assembliesResolver); if (structuredType == null) { return(type); } if (structuredType.IsEquivalentTo(innerType)) { return(type.IsDelta() ? innerType : type); } var apiVersion = model.GetAnnotationValue <ApiVersionAnnotation>(model).ApiVersion; innerType = modelTypeBuilder.NewStructuredType(structuredType, innerType, apiVersion); if (!type.IsDelta()) { foreach (var openType in result.OpenTypes) { innerType = openType.MakeGenericType(innerType); } } return(innerType); }