public void HttpMethodProviderAttributes_ReturnsCorrectHttpMethodSequence(
     IActionHttpMethodProvider httpMethodProvider,
     IEnumerable<string> expectedHttpMethods)
 {
     // Act & Assert
     Assert.Equal(expectedHttpMethods, httpMethodProvider.HttpMethods);
 }
Exemple #2
0
 public void HttpMethodProviderAttributes_ReturnsCorrectHttpMethodSequence(
     IActionHttpMethodProvider httpMethodProvider,
     IEnumerable <string> expectedHttpMethods)
 {
     // Act & Assert
     Assert.Equal(expectedHttpMethods, httpMethodProvider.HttpMethods);
 }
Exemple #3
0
        protected virtual string GetActionName(MethodInfo method)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            IActionHttpMethodProvider actionHttpMethodProvider = method.GetCustomAttributes().OfType <IActionHttpMethodProvider>()
                                                                 .ExtendedSingle($"Finding IActionHttpMethodProvider on method {method.Name} on type {method.DeclaringType?.Name}");

            if (actionHttpMethodProvider is FunctionAttribute)
            {
                return(method.Name);
            }
            else if (actionHttpMethodProvider is ActionAttribute)
            {
                return(method.Name);
            }
            else if (actionHttpMethodProvider is GetAttribute)
            {
                return(nameof(HttpMethod.Get));
            }
            else if (actionHttpMethodProvider is CreateAttribute)
            {
                return(nameof(HttpMethod.Post));
            }
            else if (actionHttpMethodProvider is UpdateAttribute)
            {
                return(nameof(HttpMethod.Put));
            }
            else if (actionHttpMethodProvider is PartialUpdateAttribute)
            {
                return("Patch");
            }
            else if (actionHttpMethodProvider is DeleteAttribute)
            {
                return(nameof(HttpMethod.Delete));
            }

            throw new InvalidOperationException($"Invalid actionHttpMethodProvider type: {actionHttpMethodProvider.GetType().Name}");
        }
        private void BuildControllerOperations <TDto>(ODataModelBuilder odataModelBuilder, TypeInfo apiController)
            where TDto : class
        {
            string controllerName = GetControllerName(apiController);
            EntitySetConfiguration <TDto> entitySet = odataModelBuilder.EntitySet <TDto>(controllerName);

            foreach (MethodInfo method in apiController.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
            {
                IActionHttpMethodProvider actionHttpMethodProvider =
                    method.GetCustomAttributes().OfType <FunctionAttribute>().Cast <IActionHttpMethodProvider>()
                    .Union(method.GetCustomAttributes().OfType <ActionAttribute>().Cast <IActionHttpMethodProvider>())
                    .ExtendedSingleOrDefault($"Finding ${nameof(IActionHttpMethodProvider)} attribute in {method.Name}");

                if (actionHttpMethodProvider != null)
                {
                    bool isFunction = actionHttpMethodProvider is FunctionAttribute;
                    bool isAction   = actionHttpMethodProvider is ActionAttribute;

                    if (!isFunction && !isAction)
                    {
                        continue;
                    }

                    List <DefaultAutoODataModelBuilderParameterInfo> operationParameters = new List <DefaultAutoODataModelBuilderParameterInfo>();

                    if (isFunction)
                    {
                        foreach (ParameterInfo parameter in method.GetParameters())
                        {
                            if (parameter.ParameterType.GetTypeInfo() == typeof(CancellationToken).GetTypeInfo() || typeof(ODataQueryOptions).IsAssignableFrom(parameter.ParameterType.GetTypeInfo()))
                            {
                                continue;
                            }
                            operationParameters.Add(new DefaultAutoODataModelBuilderParameterInfo {
                                Name = parameter.Name, Type = parameter.ParameterType.GetTypeInfo()
                            });
                        }
                    }
                    else if (isAction)
                    {
                        ParameterInfo parameter = method
                                                  .GetParameters()
                                                  .ExtendedSingleOrDefault($"Finding parameter of {method.Name}", p => p.ParameterType.GetTypeInfo() != typeof(CancellationToken).GetTypeInfo() && !typeof(ODataQueryOptions).IsAssignableFrom(p.ParameterType.GetTypeInfo()));

                        if (parameter != null)
                        {
                            foreach (PropertyInfo prop in parameter.ParameterType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                            {
                                operationParameters.Add(new DefaultAutoODataModelBuilderParameterInfo {
                                    Name = prop.Name, Type = prop.PropertyType.GetTypeInfo()
                                });
                            }
                        }
                    }

                    OperationConfiguration operationConfiguration = null;

                    if (isAction)
                    {
                        operationConfiguration = entitySet.EntityType.Collection.Action(method.Name);
                    }
                    else if (isFunction)
                    {
                        operationConfiguration = entitySet.EntityType.Collection.Function(method.Name);
                    }

                    foreach (DefaultAutoODataModelBuilderParameterInfo operationParameter in operationParameters)
                    {
                        TypeInfo parameterType = operationParameter.Type;

                        if (operationParameter.Type.GetTypeInfo() != typeof(string).GetTypeInfo() &&
                            typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(operationParameter.Type))
                        {
                            if (parameterType.IsArray)
                            {
                                throw new InvalidOperationException($"Use IEnumerable<{parameterType.GetElementType().GetTypeInfo().Name}> instead of {parameterType.GetElementType().GetTypeInfo().Name}[] for parameter {operationParameter.Name} of {operationParameter.Name} in {controllerName} controller");
                            }

                            if (parameterType.IsGenericType)
                            {
                                parameterType = parameterType.GetGenericArguments().ExtendedSingle($"Finding parameter type from generic arguments of {parameterType.Name}").GetTypeInfo();
                            }

                            ParameterConfiguration parameter = (ParameterConfiguration)_collectionParameterMethodInfo
                                                               .MakeGenericMethod(parameterType)
                                                               .Invoke(operationConfiguration, new object[] { operationParameter.Name });
                            parameter.Nullable = operationParameter.IsOptional;
                        }
                        else
                        {
                            operationConfiguration.Parameter(parameterType, operationParameter.Name).Nullable = operationParameter.IsOptional;
                        }
                    }

                    TypeInfo type = method.ReturnType.GetTypeInfo();

                    if (type.Name != "Void" && type.Name != typeof(Task).GetTypeInfo().Name)
                    {
                        operationConfiguration.ReturnNullable = false;

                        bool isCollection = false;

                        if (typeof(Task).GetTypeInfo().IsAssignableFrom(type))
                        {
                            if (type.IsGenericType)
                            {
                                type = type.GetGenericArguments().ExtendedSingle($"Finding Return type of {method.Name}").GetTypeInfo();
                            }
                        }

                        if (typeof(SingleResult).GetTypeInfo().IsAssignableFrom(type))
                        {
                            if (type.IsGenericType)
                            {
                                type = type.GetGenericArguments().ExtendedSingle($"Finding Return type of {method.Name}").GetTypeInfo();
                            }
                        }

                        if (typeof(string) != type && typeof(IEnumerable).IsAssignableFrom(type))
                        {
                            if (type.IsGenericType)
                            {
                                type = type.GetGenericArguments().ExtendedSingle($"Finding Return type of {method.Name}").GetTypeInfo();
                            }
                            else if (type.IsArray)
                            {
                                type = type.GetElementType().GetTypeInfo();
                            }
                            isCollection = true;
                        }

                        if (DtoMetadataWorkspace.Current.IsDto(type))
                        {
                            type = DtoMetadataWorkspace.Current.GetFinalDtoType(type);

                            if (isCollection == true)
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).ReturnsCollectionFromEntitySet <TDto>(controllerName);
                                }
                                else
                                {
                                    ((FunctionConfiguration)operationConfiguration).ReturnsCollectionFromEntitySet <TDto>(controllerName);
                                }
                            }
                            else
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).ReturnsFromEntitySet <TDto>(controllerName);
                                }
                                else if (isFunction)
                                {
                                    ((FunctionConfiguration)operationConfiguration).ReturnsFromEntitySet <TDto>(controllerName);
                                }
                            }
                        }
                        else
                        {
                            if (isCollection == false)
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).Returns(type);
                                }
                                else if (isFunction)
                                {
                                    ((FunctionConfiguration)operationConfiguration).Returns(type);
                                }
                            }
                            else
                            {
                                operationConfiguration.GetType()
                                .GetTypeInfo()
                                .GetMethod("ReturnsCollection")
                                .MakeGenericMethod(type)
                                .Invoke(operationConfiguration, Array.Empty <object>());
                            }
                        }
                    }
                    else
                    {
                        if (isFunction)
                        {
                            throw new InvalidOperationException($"Function {method.Name} in {apiController.Name} must have a return type, use action instead");
                        }

                        operationConfiguration.ReturnNullable = true;
                    }
                }
            }
        }
        public override ILookup <string, HttpActionDescriptor> GetActionMapping(HttpControllerDescriptor controllerDescriptor)
        {
            ILookup <string, HttpActionDescriptor> actionMappings = base.GetActionMapping(controllerDescriptor);

            List <HttpActionDescriptorAndKey> actionMappingsList = new List <HttpActionDescriptorAndKey>();

            foreach (IGrouping <string, HttpActionDescriptor> aMaps in actionMappings)
            {
                foreach (HttpActionDescriptor httpActionDescriptor in aMaps)
                {
                    IActionHttpMethodProvider actionHttpMethodProvider =
                        httpActionDescriptor.GetCustomAttributes <IActionHttpMethodProvider>()
                        .FirstOrDefault();

                    string actionName = aMaps.Key;

                    if (actionHttpMethodProvider != null)
                    {
                        if (actionHttpMethodProvider is GetAttribute)
                        {
                            actionName = "Get";
                        }
                        else if (actionHttpMethodProvider is PartialUpdateAttribute)
                        {
                            actionName = "Patch";
                            if (httpActionDescriptor.ReturnType.GetTypeInfo() == typeof(void).GetTypeInfo() || httpActionDescriptor.ReturnType.GetTypeInfo() == typeof(Task).GetTypeInfo())
                            {
                                throw new InvalidOperationException("Patch | PartialUpdate must have a return type other than Task or void");
                            }
                        }
                        else if (actionHttpMethodProvider is CreateAttribute)
                        {
                            actionName = "Post";
                            if (httpActionDescriptor.ReturnType.GetTypeInfo() == typeof(void).GetTypeInfo() || httpActionDescriptor.ReturnType == typeof(Task).GetTypeInfo())
                            {
                                throw new InvalidOperationException("Post | Create must have a return type other than Task or void");
                            }
                        }
                        else if (actionHttpMethodProvider is UpdateAttribute)
                        {
                            actionName = "Put";
                            if (httpActionDescriptor.ReturnType.GetTypeInfo() == typeof(void).GetTypeInfo() || httpActionDescriptor.ReturnType == typeof(Task).GetTypeInfo())
                            {
                                throw new InvalidOperationException("Put | Update must have a return type other than Task or void");
                            }
                        }
                        else if (actionHttpMethodProvider is DeleteAttribute)
                        {
                            actionName = "Delete";
                        }

                        _actionNameFieldName.SetValue(httpActionDescriptor, actionName);
                    }

                    actionMappingsList.Add(new HttpActionDescriptorAndKey
                    {
                        Key = actionName,
                        HttpActionDescriptor = httpActionDescriptor
                    });
                }
            }

            return(actionMappingsList.ToLookup(httpActionDescriptorAndKey => httpActionDescriptorAndKey.Key, httpActionDescriptorAndKey => httpActionDescriptorAndKey.HttpActionDescriptor));
        }
Exemple #6
0
 private static HttpMethod getHttpMethod(IActionHttpMethodProvider httpVerb)
 {
     return(httpVerb.HttpMethods.FirstOrDefault());
 }
        private void BuildControllerOperations <TDto>(ODataModelBuilder odataModelBuilder, TypeInfo apiController)
            where TDto : class
        {
            string controllerName = GetControllerName(apiController);
            EntitySetConfiguration <TDto> entitySet = odataModelBuilder.EntitySet <TDto>(controllerName);

            foreach (MethodInfo method in apiController.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
            {
                IActionHttpMethodProvider actionHttpMethodProvider =
                    method.GetCustomAttributes().OfType <IActionHttpMethodProvider>()
                    .ExtendedSingleOrDefault($"Finding ${nameof(IActionHttpMethodProvider)} attribute in {method.Name}");

                if (actionHttpMethodProvider is DeleteAttribute || actionHttpMethodProvider is UpdateAttribute || actionHttpMethodProvider is PartialUpdateAttribute)
                {
                    if (!method.GetParameters().Any(p => p.Name == "key"))
                    {
                        string dtoTypeName       = typeof(TDto).Name;
                        string keyColumnTypeName = DtoMetadataWorkspace.Current.GetKeyColums(typeof(TDto).GetTypeInfo()).ExtendedSingle($"Getting key columns for {dtoTypeName}").PropertyType.Name;
                        string methodDeclartion  = null;
                        if (actionHttpMethodProvider is DeleteAttribute)
                        {
                            methodDeclartion = $"public virtual async Task Delete({keyColumnTypeName} key, CancellationToken cancellationToken)";
                        }
                        else if (actionHttpMethodProvider is PartialUpdateAttribute)
                        {
                            methodDeclartion = $"public virtual async Task<{dtoTypeName}> PartialUpdate({keyColumnTypeName} key, Delta<{dtoTypeName}>, CancellationToken cancellationToken)";
                        }
                        else if (actionHttpMethodProvider is UpdateAttribute)
                        {
                            methodDeclartion = $"public virtual async Task<{dtoTypeName}> Update({keyColumnTypeName} key, {dtoTypeName}, CancellationToken cancellationToken)";
                        }
                        throw new InvalidOperationException($"{apiController.Name}.{method.Name} must have a signature 'like' followings: {methodDeclartion}");
                    }
                }

                if (actionHttpMethodProvider != null)
                {
                    bool isFunction = actionHttpMethodProvider is FunctionAttribute;
                    bool isAction   = actionHttpMethodProvider is ActionAttribute;

                    TypeInfo returnType = method.ReturnType.GetTypeInfo();

                    if (typeof(Task).GetTypeInfo().IsAssignableFrom(returnType))
                    {
                        if (returnType.IsGenericType)
                        {
                            returnType = returnType.GetGenericArguments().ExtendedSingle($"Finding Return type of {method.Name}").GetTypeInfo();
                        }
                    }

                    if (DtoMetadataWorkspace.Current.IsDto(returnType))
                    {
                        throw new InvalidOperationException($"Use SingleResult<{returnType.Name}> to return one {returnType.Name} in {apiController.Name}.{method.Name}");
                    }

                    if (!isFunction && !isAction)
                    {
                        continue;
                    }

                    List <DefaultAutoODataModelBuilderParameterInfo> operationParameters = new List <DefaultAutoODataModelBuilderParameterInfo>();

                    if (isFunction)
                    {
                        foreach (ParameterInfo parameter in method.GetParameters())
                        {
                            TypeInfo parameterType = parameter.ParameterType.GetTypeInfo();
                            if (parameterType == typeof(CancellationToken).GetTypeInfo() || typeof(ODataQueryOptions).IsAssignableFrom(parameterType))
                            {
                                continue;
                            }
                            if (DtoMetadataWorkspace.Current.IsDto(parameterType) || DtoMetadataWorkspace.Current.IsComplexType(parameterType) || IsIEnumerable(parameterType))
                            {
                                // some types which are known to be problematic in functions if you accept them in function parameters. This types list is not complete for sure!
                                throw new InvalidOperationException($"Parameter {parameter.Name} of type {parameter.ParameterType.Name} is not allowed in {apiController.Name}.{method.Name} function.");
                            }
                            operationParameters.Add(new DefaultAutoODataModelBuilderParameterInfo {
                                Name = parameter.Name, Type = parameterType
                            });
                        }
                    }
                    else if (isAction)
                    {
                        ParameterInfo parameter = method
                                                  .GetParameters()
                                                  .ExtendedSingleOrDefault($"Finding parameter of {apiController.Name}.{method.Name}. It's expected to see 0 or 1 parameter only.", p => p.ParameterType.GetTypeInfo() != typeof(CancellationToken).GetTypeInfo() && !typeof(ODataQueryOptions).IsAssignableFrom(p.ParameterType.GetTypeInfo()));

                        if (parameter != null)
                        {
                            TypeInfo parameterType = parameter.ParameterType.GetTypeInfo();

                            if (DtoMetadataWorkspace.Current.IsDto(parameterType) || DtoMetadataWorkspace.Current.IsComplexType(parameterType) || IsIEnumerable(parameterType))
                            {
                                operationParameters.Add(new DefaultAutoODataModelBuilderParameterInfo {
                                    Name = parameter.Name, Type = parameterType
                                });
                            }
                            else if (Nullable.GetUnderlyingType(parameterType) != null || parameterType.IsPrimitive || typeof(string).GetTypeInfo() == parameterType || parameter.ParameterType == typeof(DateTime).GetTypeInfo() || parameter.ParameterType == typeof(DateTimeOffset).GetTypeInfo() || parameter.ParameterType.IsEnum)
                            {
                                // some types which are known to be problematic in actions if you accept them in action parameters directly without any container class. This types list is not complete for sure!
                                throw new InvalidOperationException($"Allowed parameter types for {apiController.Name}.{method.Name} action: | Dto | Complex Type | Classes like pulic class {method.Name}Args {{ public {parameter.ParameterType.Name} {parameter.Name} {{ get; set; }} }} | IEnumerable<T> (For example IEnumerable<int> or IEnumerable<MyDtoClass> | You may not define a parameter of type {parameter.ParameterType.Name}.");
                            }
                            else
                            {
                                foreach (PropertyInfo prop in parameter.ParameterType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                                {
                                    operationParameters.Add(new DefaultAutoODataModelBuilderParameterInfo {
                                        Name = prop.Name, Type = prop.PropertyType.GetTypeInfo()
                                    });
                                }
                            }
                        }
                    }

                    OperationConfiguration operationConfiguration = null;

                    if (isAction)
                    {
                        operationConfiguration = entitySet.EntityType.Collection.Action(method.Name);
                    }
                    else if (isFunction)
                    {
                        operationConfiguration = entitySet.EntityType.Collection.Function(method.Name);
                    }

                    foreach (DefaultAutoODataModelBuilderParameterInfo operationParameter in operationParameters)
                    {
                        TypeInfo parameterType = operationParameter.Type;

                        if (IsIEnumerable(operationParameter.Type))
                        {
                            if (parameterType.IsArray)
                            {
                                throw new InvalidOperationException($"Use IEnumerable<{parameterType.GetElementType().GetTypeInfo().Name}> instead of {parameterType.GetElementType().GetTypeInfo().Name}[] for parameter {operationParameter.Name} of {operationParameter.Name} in {controllerName} controller");
                            }

                            if (parameterType.IsGenericType)
                            {
                                parameterType = parameterType.GetGenericArguments().ExtendedSingle($"Finding parameter type from generic arguments of {parameterType.Name}").GetTypeInfo();
                            }

                            ParameterConfiguration parameter = (ParameterConfiguration)_collectionParameterMethodInfo
                                                               .MakeGenericMethod(parameterType)
                                                               .Invoke(operationConfiguration, new object[] { operationParameter.Name });
                            parameter.Nullable = operationParameter.IsOptional;
                        }
                        else
                        {
                            operationConfiguration.Parameter(parameterType, operationParameter.Name).Nullable = operationParameter.IsOptional;
                        }
                    }

                    if (returnType.Name != "Void" && returnType.Name != typeof(Task).GetTypeInfo().Name)
                    {
                        operationConfiguration.ReturnNullable = false;

                        if (typeof(SingleResult).GetTypeInfo().IsAssignableFrom(returnType))
                        {
                            if (returnType.IsGenericType)
                            {
                                returnType = returnType.GetGenericArguments().ExtendedSingle($"Finding Return type of {method.Name}").GetTypeInfo();
                            }
                        }

                        bool isCollection = false;

                        if (IsIEnumerable(returnType))
                        {
                            if (returnType.IsGenericType)
                            {
                                returnType = returnType.GetGenericArguments().ExtendedSingle($"Finding Return type of {method.Name}").GetTypeInfo();
                            }
                            else if (returnType.IsArray)
                            {
                                returnType = returnType.GetElementType().GetTypeInfo();
                            }
                            isCollection = true;
                        }

                        if (DtoMetadataWorkspace.Current.IsDto(returnType))
                        {
                            returnType = DtoMetadataWorkspace.Current.GetFinalDtoType(returnType);

                            if (isCollection == true)
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).ReturnsCollectionFromEntitySet <TDto>(controllerName);
                                }
                                else
                                {
                                    ((FunctionConfiguration)operationConfiguration).ReturnsCollectionFromEntitySet <TDto>(controllerName);
                                }
                            }
                            else
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).ReturnsFromEntitySet <TDto>(controllerName);
                                }
                                else if (isFunction)
                                {
                                    ((FunctionConfiguration)operationConfiguration).ReturnsFromEntitySet <TDto>(controllerName);
                                }
                            }
                        }
                        else
                        {
                            if (isCollection == false)
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).Returns(returnType);
                                }
                                else if (isFunction)
                                {
                                    ((FunctionConfiguration)operationConfiguration).Returns(returnType);
                                }
                            }
                            else
                            {
                                operationConfiguration.GetType()
                                .GetTypeInfo()
                                .GetMethod("ReturnsCollection")
                                .MakeGenericMethod(returnType)
                                .Invoke(operationConfiguration, Array.Empty <object>());
                            }
                        }
                    }
                    else
                    {
                        if (isFunction)
                        {
                            throw new InvalidOperationException($"Function {method.Name} in {apiController.Name} must have a return type, use action instead");
                        }

                        operationConfiguration.ReturnNullable = true;
                    }
                }
            }
        }
        private void BuildControllerOperations <TDto>(ODataModelBuilder modelBuilder, TypeInfo apiController)
            where TDto : class
        {
            TypeInfo dtoType        = typeof(TDto).GetTypeInfo();
            string   controllerName = GetControllerName(apiController);
            EntitySetConfiguration <TDto> entitySet = modelBuilder.EntitySet <TDto>(controllerName);

            foreach (MethodInfo method in apiController.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
            {
                IActionHttpMethodProvider actionHttpMethodProvider =
                    method.GetCustomAttributes().OfType <FunctionAttribute>().Cast <IActionHttpMethodProvider>()
                    .Union(method.GetCustomAttributes().OfType <ActionAttribute>().Cast <IActionHttpMethodProvider>())
                    .SingleOrDefault();

                if (actionHttpMethodProvider != null)
                {
                    bool isFunction = actionHttpMethodProvider is FunctionAttribute;
                    bool isAction   = actionHttpMethodProvider is ActionAttribute;

                    if (!isFunction && !isAction)
                    {
                        continue;
                    }

                    List <ParameterAttribute> actionParameters =
                        method.GetCustomAttributes <ParameterAttribute>().ToList();

                    OperationConfiguration operationConfiguration = null;

                    if (isAction)
                    {
                        operationConfiguration = entitySet.EntityType.Collection.Action(method.Name);
                    }
                    else if (isFunction)
                    {
                        operationConfiguration = entitySet.EntityType.Collection.Function(method.Name);
                    }

                    foreach (ParameterAttribute actionParameter in actionParameters)
                    {
                        if (actionParameter.Type.GetTypeInfo() != typeof(string).GetTypeInfo() &&
                            typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(actionParameter.Type.GetTypeInfo()))
                        {
                            TypeInfo parameterType = actionParameter.Type.GetTypeInfo();

                            if (parameterType.IsArray)
                            {
                                throw new InvalidOperationException($"Use IEnumerable<{parameterType.GetElementType().GetTypeInfo().Name}> instead of {parameterType.GetElementType().GetTypeInfo().Name}[] for parameter {actionParameter.Name} of {actionParameter.Name} in {controllerName} controller");
                            }

                            if (parameterType.IsGenericType)
                            {
                                parameterType = parameterType.GetGenericArguments().Single().GetTypeInfo();
                            }

                            ParameterConfiguration parameter = (ParameterConfiguration)_collectionParameterMethodInfo
                                                               .MakeGenericMethod(parameterType)
                                                               .Invoke(operationConfiguration, new object[] { actionParameter.Name });

                            parameter.OptionalParameter = actionParameter.IsOptional;
                        }
                        else
                        {
                            operationConfiguration.Parameter(actionParameter.Type, actionParameter.Name)
                            .OptionalParameter =
                                actionParameter.IsOptional;
                        }
                    }

                    TypeInfo type = method.ReturnType.GetTypeInfo();

                    if (type.Name != "Void" && type.Name != typeof(Task).GetTypeInfo().Name)
                    {
                        operationConfiguration.OptionalReturn = false;

                        bool isCollection = false;

                        if (typeof(Task).GetTypeInfo().IsAssignableFrom(type))
                        {
                            if (type.IsGenericType)
                            {
                                type = type.GetGenericArguments().Single().GetTypeInfo();
                            }
                        }

                        if (typeof(string) != type && typeof(IEnumerable).IsAssignableFrom(type))
                        {
                            if (type.IsGenericType)
                            {
                                type = type.GetGenericArguments().Single().GetTypeInfo();
                            }
                            else if (type.IsArray)
                            {
                                type = type.GetElementType().GetTypeInfo();
                            }
                            isCollection = true;
                        }

                        if (IsDto(type))
                        {
                            type = GetFinalDtoType(type);

                            if (isCollection == true)
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).ReturnsCollectionFromEntitySet <TDto>(controllerName);
                                }
                                else
                                {
                                    ((FunctionConfiguration)operationConfiguration).ReturnsCollectionFromEntitySet <TDto>(controllerName);
                                }
                            }
                            else
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).ReturnsFromEntitySet <TDto>(controllerName);
                                }
                                else if (isFunction)
                                {
                                    ((FunctionConfiguration)operationConfiguration).ReturnsFromEntitySet <TDto>(controllerName);
                                }
                            }
                        }
                        else
                        {
                            if (isCollection == false)
                            {
                                if (isAction)
                                {
                                    ((ActionConfiguration)operationConfiguration).Returns(type);
                                }
                                else if (isFunction)
                                {
                                    ((FunctionConfiguration)operationConfiguration).Returns(type);
                                }
                            }
                            else
                            {
                                operationConfiguration.GetType()
                                .GetTypeInfo()
                                .GetMethod("ReturnsCollection")
                                .MakeGenericMethod(type)
                                .Invoke(operationConfiguration, new object[] { });
                            }
                        }
                    }
                    else
                    {
                        if (isFunction)
                        {
                            throw new InvalidOperationException("Function must have a return type, use action instead");
                        }

                        operationConfiguration.OptionalReturn = true;
                    }
                }
            }
        }
Exemple #9
0
 internal ApiAccessPolicy(Type type, IActionHttpMethodProvider action)
 {
     this.Type    = type;
     this.LoginId = Conversion.TryCastLong(HttpContext.Current.User.Identity.Name);
 }