예제 #1
1
        public static RouteInfo RouteRequest(HttpConfiguration config, HttpRequestMessage request)
        {
            // create context
            var controllerContext = new HttpControllerContext(config, Substitute.For<IHttpRouteData>(), request);

            // get route data
            var routeData = config.Routes.GetRouteData(request);
            RemoveOptionalRoutingParameters(routeData.Values);

            request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData;
            controllerContext.RouteData = routeData;

            // get controller type
            var controllerDescriptor = new DefaultHttpControllerSelector(config).SelectController(request);
            controllerContext.ControllerDescriptor = controllerDescriptor;

            // get action name
            var actionMapping = new ApiControllerActionSelector().SelectAction(controllerContext);

            return new RouteInfo
            {
                Controller = controllerDescriptor.ControllerType,
                Action = actionMapping.ActionName
            };
        }
        public void TestRoute(string url, string verb, Type type, string actionName)
        {
            //Arrange
            url = url.Replace("{apiVersionNumber}", this.ApiVersionNumber);
            url = Host + url;

            //Act
            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(verb), url);

            IHttpControllerSelector controller = this.GetControllerSelector();
            IHttpActionSelector action = this.GetActionSelector();

            IHttpRouteData route = this.Config.Routes.GetRouteData(request);
            request.Properties[HttpPropertyKeys.HttpRouteDataKey] = route;
            request.Properties[HttpPropertyKeys.HttpConfigurationKey] = this.Config;

            HttpControllerDescriptor controllerDescriptor = controller.SelectController(request);

            HttpControllerContext context = new HttpControllerContext(this.Config, route, request)
            {
                ControllerDescriptor = controllerDescriptor
            };

            var actionDescriptor = action.SelectAction(context);

            //Assert
            Assert.NotNull(controllerDescriptor);
            Assert.NotNull(actionDescriptor);
            Assert.Equal(type, controllerDescriptor.ControllerType);
            Assert.Equal(actionName, actionDescriptor.ActionName);
        }
예제 #3
0
        public Task<HttpResponseMessage> ExecuteAsync(
            HttpControllerContext controllerContext, 
            CancellationToken cancellationToken) {

            var request = controllerContext.Request;

            if (request.Method == HttpMethod.Get) {

                var cars = new[] { "Car 1", "Car 2", "Car 3" };
                var response = request.CreateResponse(HttpStatusCode.OK, cars);

                //.NET v4.0 with TaskHelpers.Sources package
                //return TaskHelpers.FromResult(response);

                //.NET v4.5
                return Task.FromResult(response);
            }

            //.NET v4.0 with TaskHelpers.Sources package
            //return TaskHelpers.FromResult(
            //      request.CreateResponse(HttpStatusCode.MethodNotAllowed));

            //.NET v4.5
            return Task.FromResult(
                request.CreateResponse(HttpStatusCode.MethodNotAllowed));

        }
예제 #4
0
        /// <summary>
        /// Simulating the action selecting process. It mimics the ASP.NET Web API internal logic
        /// </summary>
        /// <param name="controllerContext">The controller context.</param>
        /// <returns>A structure contains the log of selecting process</returns>
        public ActionSelectionLog Simulate(HttpControllerContext controllerContext)
        {
            Initialize(controllerContext.ControllerDescriptor);

            ActionSelectionLog log = new ActionSelectionLog(_actionDescriptors);

            // If the action name exists in route data, filter the action descriptors based on action name.
            ReflectedHttpActionDescriptor[] actionsFoundByMethod = null;
            var routeData = controllerContext.Request.GetRouteData();
            string actionName;
            if (routeData.Values.TryGetValue("action", out actionName))
            {
                var actionsFound = _actionNameMapping[actionName].OfType<ReflectedHttpActionDescriptor>().ToArray();

                // Filter actions based on verb.
                actionsFoundByMethod = actionsFound
                    .Where(actionDescriptor => actionDescriptor.SupportedHttpMethods.Contains(controllerContext.Request.Method))
                    .ToArray();

                log.ActionName = actionName;
                log.MarkSelected(actionsFound, info => info.FoundByActionName = true);
                log.MarkOthersSelected(actionsFound, info => info.FoundByActionName = false);

                log.MarkSelected(actionsFound, info => info.FoundByActionNameWithRightVerb = false);
                log.MarkSelected(actionsFoundByMethod, info => info.FoundByActionNameWithRightVerb = true);
            }
            else
            {
                log.ActionName = string.Empty;

                // If action name doesn't exist, find actions based on HTTP verb.
                log.HttpMethod = controllerContext.Request.Method;

                if (string.IsNullOrEmpty(actionName))
                {
                    actionsFoundByMethod = FindActionsForVerb(log.HttpMethod);

                    log.MarkSelected(actionsFoundByMethod, info => info.FoundByVerb = true);
                }
            }

            // If no action is found at this stage a failure must happen.
            if (actionsFoundByMethod != null && actionsFoundByMethod.Length != 0)
            {
                // filter the actions by parameters matching
                var actionsFilterByParam = FindActionUsingRouteAndQueryParameters(
                    controllerContext,
                    actionsFoundByMethod,
                    !string.IsNullOrEmpty(actionName)).ToArray();
                log.MarkSelected(actionsFoundByMethod, info => info.FoundWithRightParam = false);
                log.MarkSelected(actionsFilterByParam, info => info.FoundWithRightParam = true);

                // filter the actions by selection filters
                var actionsFilterBySelectors = RunSelectionFilters(controllerContext, actionsFilterByParam).ToArray();
                log.MarkSelected(actionsFilterByParam, info => info.FoundWithSelectorsRun = false);
                log.MarkSelected(actionsFilterBySelectors, info => info.FoundWithSelectorsRun = true);
            }

            return log;
        }
        /// <summary>
        /// Selects the action for OData requests.
        /// </summary>
        /// <param name="odataPath">The OData path.</param>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="actionMap">The action map.</param>
        /// <returns>
        ///   <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected action
        /// </returns>
        public string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
        {
            if (odataPath == null)
            {
                throw Error.ArgumentNull("odataPath");
            }

            if (controllerContext == null)
            {
                throw Error.ArgumentNull("controllerContext");
            }

            if (actionMap == null)
            {
                throw Error.ArgumentNull("actionMap");
            }

            if (odataPath.PathTemplate == "~")
            {
                return "GetServiceDocument";
            }

            if (odataPath.PathTemplate == "~/$metadata")
            {
                return "GetMetadata";
            }

            return null;
        }
        public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
        {
            var action = base.SelectAction(odataPath, controllerContext, actionMap);
            if (action != null)
            {
                var routeValues = controllerContext.RouteData.Values;
                if (routeValues.ContainsKey(ODataRouteConstants.Key))
                {
                    var keyRaw = routeValues[ODataRouteConstants.Key] as string;
                    IEnumerable<string> compoundKeyPairs = keyRaw.Split(',');
                    if (compoundKeyPairs == null || !compoundKeyPairs.Any())
                    {
                        return action;
                    }

                    foreach (var compoundKeyPair in compoundKeyPairs)
                    {
                        string[] pair = compoundKeyPair.Split('=');
                        if (pair == null || pair.Length != 2)
                        {
                            continue;
                        }
                        var keyName = pair[0].Trim();
                        var keyValue = pair[1].Trim();

                        routeValues.Add(keyName, keyValue);
                    }
                }
            }

            return action;
        }
        public void Id_Invalid_string_Should_Return_BadRequest()
        {
            var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/post");
            request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());

            var httpControllerContext = new HttpControllerContext {
                 Request = request
            };

            var httpActionContext = new HttpActionContext {
                ControllerContext = httpControllerContext
            };

            httpActionContext.ModelState.AddModelError("id", "string is not a int");

            // Testing filter
            var filter = new ModelValidationFilterBase();
            filter.OnActionExecuting(httpActionContext);

            filter = new IdValidationFilterAttribute();
            filter.OnActionExecuting(httpActionContext);

            Assert.IsFalse(httpActionContext.ModelState.IsValid);
            Assert.IsTrue(httpActionContext.Response.StatusCode == HttpStatusCode.BadRequest);
            Assert.IsTrue(((Dictionary<string, IEnumerable<string>>) ((ObjectContent) (httpActionContext.Response.Content)).Value)["id"].FirstOrDefault() == "string is not a int");
        }
        public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
        {
            var controllerType = controllerContext.ControllerDescriptor.ControllerType;

            if (typeof(CustomersController) == controllerType)
            {
                if (odataPath.PathTemplate.Equals("~/entityset/key/navigation")) //POST OR GET
                {
                    controllerContext.RouteData.Values["orderID"] = ((KeySegment)odataPath.Segments[1]).Keys.Single().Value;
                    return controllerContext.Request.Method.ToString();
                }
            }
            else if (typeof(OrdersController) == controllerType)
            {
                if (odataPath.PathTemplate.Equals("~/entityset/key/navigation")) //POST OR GET
                {
                    controllerContext.RouteData.Values["customerID"] = ((KeySegment)odataPath.Segments[1]).Keys.Single().Value;
                    return controllerContext.Request.Method.ToString();
                }
                if (odataPath.PathTemplate.Equals("~/entityset/key/navigation/key")) //PATCH OR DELETE
                {
                    controllerContext.RouteData.Values["customerID"] = ((KeySegment)odataPath.Segments[1]).Keys.Single().Value;

                    controllerContext.RouteData.Values["key"] = ((KeySegment)odataPath.Segments[3]).Keys.Single().Value;
                    return controllerContext.Request.Method.ToString();
                }
            }

            return base.SelectAction(odataPath, controllerContext, actionMap);
        }
        /// <summary>
        /// 通过表达式执行方法,具体在 ReflectedHttpActionDescriptor 中实现
        /// </summary>
        /// <param name="controllerContext"></param>
        /// <param name="arguments"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override System.Threading.Tasks.Task<object> ExecuteAsync(HttpControllerContext controllerContext, System.Collections.Generic.IDictionary<string, object> arguments, System.Threading.CancellationToken cancellationToken)
        {
            dynamic generic = controllerContext.Controller;

            var applicationService = generic.ApplicationService;
            controllerContext.Controller = controllerContext.Controller = applicationService;
            return base
                .ExecuteAsync(controllerContext, arguments, cancellationToken)
                .ContinueWith(task =>
                {
                    try
                    {
                        if (task.Result == null)
                        {

                            return new AjaxResponse();
                        }

                        if (task.Result is AjaxResponse)
                        {
                            return task.Result;
                        }

                        return new AjaxResponse(task.Result);
                    }
                    catch (Exception ex)
                    {

                        throw ex;
                    }
                }, cancellationToken);
        }
        protected virtual ReflectedHttpActionDescriptor ProcessAcceptHeader(HttpControllerContext context,
                                                                              IEnumerable<ReflectedHttpActionDescriptor>
                                                                                  actionDescriptors)
        {
            // GET calls that can be resolved by Accept which has a Non-Canonical Media Type
            // only if it is the first item in Accept Header
            // use of 5LMT header parameters also supported
            if (context.Request.Method.Method == "GET" && context.Request.Headers.Accept.Count > 0)
            {
                var extendedMediaType = context.Request.Headers.Accept.First()
                    .ExtractFiveLevelsOfMediaType(FiveLevelsOfMediaTypeFormatter.DefaultNonCanonicalMediaTypePattern);

                if (extendedMediaType != null && !string.IsNullOrEmpty(extendedMediaType.DomainModel))
                {
                    var matches = actionDescriptors.Where(x => x.MethodInfo.ReturnType.Name ==
                        _domainNameToTypeNameMapper(extendedMediaType.DomainModel)).ToArray();

                    if (matches.Length == 1)
                        return matches.First();

                    if (matches.Length > 1)
                    {

                        var theMatchBasedOnVersion = matches.FirstOrDefault(x => _versionChecker(x, extendedMediaType.Version));
                        if (theMatchBasedOnVersion != null)
                            return theMatchBasedOnVersion;
                    }
                }
            }

            return null;
        }
        protected virtual ReflectedHttpActionDescriptor ProcessRequestContentHeader(HttpControllerContext context,
                                   IEnumerable<ReflectedHttpActionDescriptor> actionDescriptors)
        {
            // normally for POST and PUT that we resolve with content type
            if (context.Request.Content != null && context.Request.Content.Headers.ContentType != null)
            {
                var extendedMedaType = context.Request.Content.Headers.ContentType.ExtractFiveLevelsOfMediaType();
                if (extendedMedaType != null)
                {
                    var candidate = actionDescriptors.FirstOrDefault(x =>
                                                                     x.MethodInfo.GetParameters()
                                                                      .Any(p =>
                                                                           p.ParameterType.Name
                                                                            .Equals(
                                                                                _domainNameToTypeNameMapper(extendedMedaType.DomainModel),
                                                                                StringComparison
                                                                                    .CurrentCultureIgnoreCase)));
                    if (candidate != null)
                        return candidate;
                };

            }

            return null;
        }
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            var action = base.SelectAction(controllerContext);

            if (!controllerContext.Request.IsCurrentUserBetaTester() || DateTime.Now.Second % 2 == 0)
            {
                // Send the user to the 'normal' action
                return action;
            }
            else
            {
                // This user is in the beta program and was selected to see a different version of the action.

                HttpActionDescriptor betaAction;
                if (!_betaActions.TryGetValue(action, out betaAction))
                {
                    betaAction = CreateBetaAction(action);
                    _betaActions.TryAdd(action, betaAction);
                }

                if (betaAction == null)
                {
                    return action;
                }
                else
                {
                    return betaAction;
                }
            }
        }
        protected override void Initialize(HttpControllerContext controllerContext)
        {
            var hub = ((IHub)this);

            var hubName = this.GetType().FullName;
            var hubManager = _resolver.Resolve<IHubManager>();
            var descriptor = hubManager.EnsureHub(hubName);

            var user = controllerContext.Request.GetUserPrincipal();

            // Response parameter is null here because outgoing broadcast messages will always go
            // via the SignalR intrinsics, and method return values via the Web API intrinsics.
            var hostContext = new HostContext(new WebApiRequest(controllerContext.Request), null, user);
            var connectionId = hostContext.Request.QueryString["connectionId"];
            hub.Context = new HubContext(hostContext, connectionId);

            var connection = _resolver.Resolve<IConnectionManager>().GetConnection<HubDispatcher>();
            var state = new TrackingDictionary();
            var agent = new ClientAgent(connection, descriptor.Name);
            hub.Caller = new SignalAgent(connection, connectionId, descriptor.Name, state);
            hub.Agent = agent;
            hub.GroupManager = agent;

            base.Initialize(controllerContext);
        }
        public void WrapperResolvesAuthenticationFilterFromDependencyScope()
        {
            var builder = new ContainerBuilder();
            builder.Register<ILogger>(c => new Logger()).InstancePerDependency();
            var activationCount = 0;
            builder.Register<IAutofacAuthenticationFilter>(c => new TestAuthenticationFilter(c.Resolve<ILogger>()))
                .AsWebApiAuthenticationFilterFor<TestController>(c => c.Get())
                .InstancePerRequest()
                .OnActivated(e => activationCount++);
            var container = builder.Build();

            var resolver = new AutofacWebApiDependencyResolver(container);
            var configuration = new HttpConfiguration { DependencyResolver = resolver };
            var requestMessage = new HttpRequestMessage();
            requestMessage.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, configuration);
            var contollerContext = new HttpControllerContext { Request = requestMessage };
            var controllerDescriptor = new HttpControllerDescriptor { ControllerType = typeof(TestController) };
            var methodInfo = typeof(TestController).GetMethod("Get");
            var actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, methodInfo);
            var actionContext = new HttpActionContext(contollerContext, actionDescriptor);
            var context = new HttpAuthenticationContext(actionContext, Thread.CurrentPrincipal);
            var metadata = new FilterMetadata
            {
                ControllerType = typeof(TestController),
                FilterScope = FilterScope.Action,
                MethodInfo = methodInfo
            };
            var wrapper = new AuthenticationFilterWrapper(metadata);

            wrapper.OnAuthenticate(context);
            Assert.That(activationCount, Is.EqualTo(1));
        }
예제 #15
0
        /// <summary>
        /// Selects the appropriate action based on the parsed OData URI.
        /// </summary>
        /// <param name="odataPath">Parsed OData URI</param>
        /// <param name="controllerContext">Context for HttpController</param>
        /// <param name="actionMap">Mapping from action names to HttpActions</param>
        /// <returns>String corresponding to controller action name</returns>
        public string SelectAction(
            ODataPath odataPath,
            HttpControllerContext controllerContext,
            ILookup<string, HttpActionDescriptor> actionMap)
        {
            // TODO GitHubIssue#44 : implement action selection for $ref, navigation scenarios, etc.
            Ensure.NotNull(odataPath, "odataPath");
            Ensure.NotNull(controllerContext, "controllerContext");
            Ensure.NotNull(actionMap, "actionMap");

            if (!(controllerContext.Controller is RestierController))
            {
                // RESTier cannot select action on controller which is not RestierController.
                return null;
            }

            HttpMethod method = controllerContext.Request.Method;

            if (method == HttpMethod.Get && !IsMetadataPath(odataPath))
            {
                return MethodNameOfGet;
            }

            ODataPathSegment lastSegment = odataPath.Segments.LastOrDefault();
            if (lastSegment != null && lastSegment.SegmentKind == ODataSegmentKinds.UnboundAction)
            {
                return MethodNameOfPostAction;
            }

            // Let WebAPI select default action
            return null;
        }
     protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
     {
 
         /*
 
             Use any of these to enforce your rules;
 	
             http://msdn.microsoft.com/en-us/library/system.web.http.apicontroller%28v=vs.108%29.aspx
 	
             Public property	Configuration	Gets or sets the HttpConfiguration of the current ApiController.
             Public property	ControllerContext	Gets the HttpControllerContext of the current ApiController.
             Public property	ModelState	Gets the model state after the model binding process.
             Public property	Request	Gets or sets the HttpRequestMessage of the current ApiController.
             Public property	Url	Returns an instance of a UrlHelper, which is used to generate URLs to other APIs.
             Public property	User	Returns the current principal associated with this request. 
         */        
     
 		  base.Initialize();
 		  
 		  bool iDontLikeYou = true; /* Your rules here */
 			if (iDontLikeYou)
 			{
 				throw new HttpResponseException(new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.NotFound));
 			}
 		  
 	
     }
        public void ExecuteBindingAsync_CallsGetPerRequestFormatterInstance_BeforeBinding()
        {
            // Arrange
            Mock<HttpParameterDescriptor> parameter = new Mock<HttpParameterDescriptor>();
            Mock<MediaTypeFormatter> formatter = new Mock<MediaTypeFormatter>();
            MediaTypeFormatter perRequestFormatter = new Mock<MediaTypeFormatter>().Object;

            MockPerRequestParameterBinding binding = new MockPerRequestParameterBinding(parameter.Object, new[] { formatter.Object });

            HttpRequestMessage request = new HttpRequestMessage();
            request.Content = new StringContent("{}");
            request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/something");
            HttpControllerContext controllercontext = new HttpControllerContext { Request = request };
            HttpActionContext actionContext = new HttpActionContext(controllercontext, new Mock<HttpActionDescriptor>().Object);

            MediaTypeFormatter formatterUsedForPrameterBinding = null;
            binding.CreateInnerBindingFunc = (formatters) =>
                {
                    formatterUsedForPrameterBinding = formatters.Single();
                    return new VoidParameterBinding();
                };

            formatter
                .Setup(f => f.GetPerRequestFormatterInstance(parameter.Object.ParameterType, request, request.Content.Headers.ContentType))
                .Returns(perRequestFormatter);

            // Act
            binding.ExecuteBindingAsync(new Mock<ModelMetadataProvider>().Object, actionContext, new CancellationToken());

            // Assert
            Assert.Same(formatterUsedForPrameterBinding, perRequestFormatter);
        }
        /// <summary>
        /// Selects the action for OData requests.
        /// </summary>
        /// <param name="odataPath">The OData path.</param>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="actionMap">The action map.</param>
        /// <returns>
        ///   <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected action
        /// </returns>
        public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
        {
            if (odataPath == null)
            {
                throw Error.ArgumentNull("odataPath");
            }

            if (controllerContext == null)
            {
                throw Error.ArgumentNull("controllerContext");
            }

            if (actionMap == null)
            {
                throw Error.ArgumentNull("actionMap");
            }

            if (odataPath.PathTemplate == "~/entityset/key" ||
                odataPath.PathTemplate == "~/entityset/key/cast")
            {
                HttpMethod httpMethod = controllerContext.Request.Method;
                string httpMethodName;

                switch (httpMethod.ToString().ToUpperInvariant())
                {
                    case "GET":
                        httpMethodName = "Get";
                        break;
                    case "PUT":
                        httpMethodName = "Put";
                        break;
                    case "PATCH":
                    case "MERGE":
                        httpMethodName = "Patch";
                        break;
                    case "DELETE":
                        httpMethodName = "Delete";
                        break;
                    default:
                        return null;
                }

                Contract.Assert(httpMethodName != null);

                IEdmEntityType entityType = odataPath.EdmType as IEdmEntityType;

                // e.g. Try GetCustomer first, then fallback on Get action name
                string actionName = actionMap.FindMatchingAction(
                    httpMethodName + entityType.Name,
                    httpMethodName);

                if (actionName != null)
                {
                    KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment;
                    controllerContext.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value;
                    return actionName;
                }
            }
            return null;
        }
        public override System.Threading.Tasks.Task<object> ExecuteAsync(HttpControllerContext controllerContext, System.Collections.Generic.IDictionary<string, object> arguments, System.Threading.CancellationToken cancellationToken)
        {
            return base
                .ExecuteAsync(controllerContext, arguments, cancellationToken)
                .ContinueWith(task =>
                {
                    try
                    {
                        if (task.Result == null)
                        {
                            return new AjaxResponse();
                        }

                        if (task.Result is AjaxResponse)
                        {
                            return task.Result;
                        }
                        
                        return new AjaxResponse(task.Result);
                    }
                    catch (AggregateException ex)
                    {
                        ex.InnerException.ReThrow();
                        throw; // The previous line will throw, but we need this to makes compiler happy
                    }
                });
        }
예제 #20
0
        public override async Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            InnerInitialization(controllerContext);
            var authorizer = (MixedModeRequestAuthorizer)controllerContext.Configuration.Properties[typeof(MixedModeRequestAuthorizer)];
            var result = new HttpResponseMessage();
            if (InnerRequest.Method.Method != "OPTIONS")
            {
                result = await RequestManager.HandleActualRequest(this, controllerContext, async () =>
                {
                    RequestManager.SetThreadLocalState(ReadInnerHeaders, DatabaseName);
                    return await ExecuteActualRequest(controllerContext, cancellationToken, authorizer);
                }, httpException =>
                {
                    var response = GetMessageWithObject(new { Error = httpException.Message }, HttpStatusCode.ServiceUnavailable);

                    var timeout = httpException.InnerException as TimeoutException;
                    if (timeout != null)
                    {
                        response.Headers.Add("Raven-Database-Load-In-Progress", DatabaseName);
                    }
                    return response;
                });
            }

            RequestManager.AddAccessControlHeaders(this, result);
            RequestManager.ResetThreadLocalState();

            return result;
        }
예제 #21
0
        private async Task<HttpResponseMessage> ExecuteActualRequest(HttpControllerContext controllerContext, CancellationToken cancellationToken,
            MixedModeRequestAuthorizer authorizer)
        {
            if (SkipAuthorizationSinceThisIsMultiGetRequestAlreadyAuthorized == false)
            {
                HttpResponseMessage authMsg;
                if (authorizer.TryAuthorize(this, out authMsg) == false)
                    return authMsg;
            }

            if (IsInternalRequest == false)
                RequestManager.IncrementRequestCount();

            if (DatabaseName != null && await DatabasesLandlord.GetDatabaseInternal(DatabaseName) == null)
            {
                var msg = "Could not find a database named: " + DatabaseName;
                return GetMessageWithObject(new { Error = msg }, HttpStatusCode.ServiceUnavailable);
            }

            var sp = Stopwatch.StartNew();

            var result = await base.ExecuteAsync(controllerContext, cancellationToken);
            sp.Stop();
            AddRavenHeader(result, sp);

            return result;
        }
        /// <summary>
        /// 返回  HttpActionDescriptor
        /// </summary>
        /// <param name="controllerContext">controller 上下文</param>
        /// <returns></returns>
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            object controllerInfoObj;
            if (!controllerContext.ControllerDescriptor.Properties.TryGetValue("_DynamicApiControllerInfo", out controllerInfoObj))
            {
                return base.SelectAction(controllerContext);
            }

            var controllerInfo = controllerInfoObj as DynamicApiControllerInfo;
            if (controllerInfo == null)
            {
                throw new Exception(controllerInfoObj.GetType().Name + "并不是一个 DynamicApiControllerInfo, 初始化 ControllerDescriptor 有误 !!");
            }

            //得到 action
            var serviceNameWithAction = (controllerContext.RouteData.Values["serviceNameWithAction"] as string);
            if (serviceNameWithAction == null)
            {
                return base.SelectAction(controllerContext);
            }

            var actionName = DynamicApiServiceNameHelper.GetActionNameInServiceNameWithAction(serviceNameWithAction);

            return GetActionByActionName(
                controllerContext,
                controllerInfo,
                actionName
                );
        }
예제 #23
0
        /// <summary>
        /// Creates a ClientContext token for the incoming WebAPI request. This is done by 
        /// - looking up the servicesToken
        /// - extracting the cacheKey 
        /// - get the AccessToken from cache. If the AccessToken is expired a new one is requested using the refresh token
        /// - creation of a ClientContext object based on the AccessToken
        /// </summary>
        /// <param name="httpControllerContext">Information about the HTTP request that reached the WebAPI controller</param>
        /// <returns>A valid ClientContext object</returns>
        public static ClientContext GetClientContext(HttpControllerContext httpControllerContext)
        {
            if (httpControllerContext == null)
                throw new ArgumentNullException("httpControllerContext");

            string cacheKey = GetCacheKeyValue(httpControllerContext);

            if (!String.IsNullOrEmpty(cacheKey))
            {
                WebAPIContexCacheItem cacheItem = WebAPIContextCache.Instance.Get(cacheKey);

                //request a new access token from ACS whenever our current access token will expire in less than 1 hour
                if (cacheItem.AccessToken.ExpiresOn < (DateTime.Now.AddHours(-1)))
                {
                    Uri targetUri = new Uri(cacheItem.SharePointServiceContext.HostWebUrl);
                    OAuth2AccessTokenResponse accessToken = TokenHelper.GetAccessToken(cacheItem.RefreshToken, TokenHelper.SharePointPrincipal, targetUri.Authority, TokenHelper.GetRealmFromTargetUrl(targetUri));
                    cacheItem.AccessToken = accessToken;
                    //update the cache
                    WebAPIContextCache.Instance.Put(cacheKey, cacheItem);
                    LoggingUtility.Internal.TraceInformation((int)EventId.ServicesTokenRefreshed, CoreResources.Services_TokenRefreshed, cacheKey, cacheItem.SharePointServiceContext.HostWebUrl);
                }
                 
                return TokenHelper.GetClientContextWithAccessToken(cacheItem.SharePointServiceContext.HostWebUrl, cacheItem.AccessToken.AccessToken);
            }
            else
            {
                LoggingUtility.Internal.TraceWarning((int)EventId.ServicesNoCachedItem, CoreResources.Services_CookieWithCachKeyNotFound);
                throw new Exception("The cookie with the cachekey was not found...nothing can be retrieved from cache, so no clientcontext can be created.");
            }            
        }
        /// <summary>
        /// This class is called by Web API system to select action method from given controller.
        /// </summary>
        /// <param name="controllerContext">Controller context</param>
        /// <returns>Action to be used</returns>
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            object controllerInfoObj;
            if (controllerContext.ControllerDescriptor.Properties.TryGetValue("__AbpDynamicApiControllerInfo", out  controllerInfoObj))
            {
                //Get controller information which is selected by AbpHttpControllerSelector.
                var controllerInfo = controllerInfoObj as DynamicApiControllerInfo;
                if (controllerInfo == null)
                {
                    throw new Exception("__AbpDynamicApiControllerInfo in ControllerDescriptor.Properties is not a " + typeof(DynamicApiControllerInfo).FullName + " class.");
                }

                //Get action name
                var serviceNameWithAction = (controllerContext.RouteData.Values["serviceNameWithAction"] as string);
                if (serviceNameWithAction != null)
                {
                    var actionName = DynamicApiServiceNameHelper.GetActionNameInServiceNameWithAction(serviceNameWithAction);

                    //Get action information
                    if (!controllerInfo.Actions.ContainsKey(actionName))
                    {
                        throw new Exception("There is no action " + actionName + " defined for api controller " + controllerInfo.ServiceName);
                    }

                    return new DynamicHttpActionDescriptor(controllerContext.ControllerDescriptor, controllerInfo.Actions[actionName].Method, controllerInfo.Actions[actionName].Filters);
                }
            }

            return base.SelectAction(controllerContext);
        }
예제 #25
0
 public static HttpActionContext CreateActionContext(HttpControllerContext controllerContext = null, HttpActionDescriptor actionDescriptor = null)
 {
     HttpControllerContext context = controllerContext ?? CreateControllerContext();
     HttpActionDescriptor descriptor = actionDescriptor ?? CreateActionDescriptor();
     descriptor.ControllerDescriptor = context.ControllerDescriptor;
     return new HttpActionContext(context, descriptor);
 }
 protected override void Initialize(HttpControllerContext controllerContext)
 {
     base.Initialize(controllerContext);
     storageAccount = CloudStorageAccount.Parse("UseDevelopmentStorage=true");
     var tableClient = storageAccount.CreateCloudTableClient();
     table = tableClient.GetTableReference("people");
 }
        /// <summary>
        /// This class is called by Web API system to select action method from given controller.
        /// </summary>
        /// <param name="controllerContext">Controller context</param>
        /// <returns>Action to be used</returns>
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            //TODO: If method is not supplied, try to guess the method by Http Verb and parameters ?

            object controllerInfoObj;
            if (controllerContext.ControllerDescriptor.Properties.TryGetValue("__AbpDynamicApiControllerInfo", out  controllerInfoObj))
            {
                //Get controller information which is selected by AbpHttpControllerSelector.
                var controllerInfo = controllerInfoObj as DynamicApiControllerInfo;
                if (controllerInfo == null)
                {
                    throw new AbpException("__AbpDynamicApiControllerInfo in ControllerDescriptor.Properties is not a " + typeof(DynamicApiControllerInfo).FullName + " class.");
                }

                //Get action name
                var actionName = (controllerContext.RouteData.Values["action"] as string);
                if (string.IsNullOrWhiteSpace(actionName))
                {
                    throw new AbpException("There is no action specified.");
                }

                //Get action information
                actionName = (controllerContext.RouteData.Values["action"] as string).ToPascalCase();
                if (!controllerInfo.Actions.ContainsKey(actionName))
                {
                    throw new AbpException("There is no action " + actionName + " defined for api controller " + controllerInfo.Name);
                }

                return new DyanamicHttpActionDescriptor(controllerContext.ControllerDescriptor, controllerInfo.Actions[actionName].Method);
            }

            return base.SelectAction(controllerContext);
        }
예제 #28
0
        private async Task<HttpResponseMessage> ExecuteActualRequest(HttpControllerContext controllerContext, CancellationToken cancellationToken,
            MixedModeRequestAuthorizer authorizer)
        {
            HttpResponseMessage authMsg;
            if (authorizer.TryAuthorize(this, out authMsg) == false)
                return authMsg;

            if (IsInternalRequest == false)
                RequestManager.IncrementRequestCount();

            var fileSystemInternal = await CountersLandlord.GetCounterInternal(CountersName);
            if (fileSystemInternal == null)
            {
                var msg = "Could not find a counters named: " + CountersName;
                return GetMessageWithObject(new { Error = msg }, HttpStatusCode.ServiceUnavailable);
            }

            var sp = Stopwatch.StartNew();

            var result = await base.ExecuteAsync(controllerContext, cancellationToken);
            sp.Stop();
            AddRavenHeader(result, sp);

            return result;
        }
예제 #29
0
        private static string GetHttpRouteHelper(HttpControllerContext controllerContext, string routeName, IDictionary<string, object> routeValues)
        {
            if (routeValues == null)
            {
                // If no route values were passed in at all we have to create a new dictionary
                // so that we can add the extra "httproute" key.
                routeValues = new Dictionary<string, object>();
                routeValues.Add(HttpRoute.HttpRouteKey, true);
            }
            else
            {
                if (!routeValues.ContainsKey(HttpRoute.HttpRouteKey))
                {
                    // Copy the dictionary so that we can add the extra "httproute" key used by all Web API routes to
                    // disambiguate them from other MVC routes.
                    routeValues = new Dictionary<string, object>(routeValues);
                    routeValues.Add(HttpRoute.HttpRouteKey, true);
                }
            }

            IHttpVirtualPathData vpd = controllerContext.Configuration.Routes.GetVirtualPath(
                controllerContext: controllerContext,
                name: routeName,
                values: routeValues);
            if (vpd == null)
            {
                return null;
            }
            return vpd.VirtualPath;
        }
예제 #30
0
		public override async Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
		{
			InnerInitialization(controllerContext);
			DocumentDatabase db;
            try
            {
                db = await DatabasesLandlord.GetDatabaseInternal(DatabaseName);
            }
            catch (Exception e)
            {
                return GetMessageWithObject(new
                {
                    Error = "Could not open database named: " + DatabaseName + ", " + e.Message
                }, HttpStatusCode.ServiceUnavailable);
            }
			if (db == null)
			{
				return GetMessageWithObject(new
				{
					Error = "Could not open database named: " + DatabaseName + ", database does not exists" 
				}, HttpStatusCode.ServiceUnavailable);
			}
			if (db.Configuration == null || db.Configuration.ActiveBundles == null ||
				!db.Configuration.ActiveBundles.Any(activeBundleName => activeBundleName.Equals(BundleName,StringComparison.InvariantCultureIgnoreCase)))
			{
				return GetMessageWithObject(new
				{
					Error = "Could not figure out what to do"
				}, HttpStatusCode.BadRequest);
			}

			return await base.ExecuteAsync(controllerContext, cancellationToken);
		}
        private static HttpActionDescriptor GetActionDescriptorByCurrentHttpVerb(HttpControllerContext controllerContext, DynamicApiControllerInfo controllerInfo)
        {
            //Check if there is only one action with the current http verb
            var actionsByVerb = controllerInfo.Actions.Values
                .Where(action => action.Verb.IsEqualTo(controllerContext.Request.Method))
                .ToArray();

            if (actionsByVerb.Length == 0)
            {
                throw new OwException(
                    "There is no action" +
                    " defined for api controller " + controllerInfo.ServiceName +
                    " with an http verb: " + controllerContext.Request.Method
                    );
            }

            if (actionsByVerb.Length > 1)
            {
                throw new OwException(
                    "There are more than one action" +
                    " defined for api controller " + controllerInfo.ServiceName +
                    " with an http verb: " + controllerContext.Request.Method
                    );
            }

            //Return the single action by the current http verb
            return new DynamicHttpActionDescriptor(controllerContext.ControllerDescriptor, actionsByVerb[0].Method, actionsByVerb[0].Filters);
        }
 /// <summary>
 /// Executes the described action and returns a <see cref="Task{T}"/> that once completed will
 /// contain the return value of the action.
 /// </summary>
 /// <param name="controllerContext">The context.</param>
 /// <param name="arguments">The arguments.</param>
 /// <returns>A <see cref="Task{T}"/> that once completed will contain the return value of the action.</returns>
 public abstract Task <object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary <string, object> arguments);
예제 #33
0
            private List <ReflectedHttpActionDescriptor> FindActionUsingRouteAndQueryParameters(HttpControllerContext controllerContext, ReflectedHttpActionDescriptor[] actionsFound)
            {
                IDictionary <string, object> routeValues         = controllerContext.RouteData.Values;
                HashSet <string>             routeParameterNames = new HashSet <string>(routeValues.Keys, StringComparer.OrdinalIgnoreCase);

                routeParameterNames.Remove(RouteKeys.ControllerKey);
                routeParameterNames.Remove(RouteKeys.ActionKey);

                HttpRequestMessage request = controllerContext.Request;
                Uri  requestUri            = request.RequestUri;
                bool hasQueryParameters    = requestUri != null && !String.IsNullOrEmpty(requestUri.Query);
                bool hasRouteParameters    = routeParameterNames.Count != 0;

                List <ReflectedHttpActionDescriptor> matches = new List <ReflectedHttpActionDescriptor>(actionsFound.Length);

                if (hasRouteParameters || hasQueryParameters)
                {
                    var combinedParameterNames = new HashSet <string>(routeParameterNames, StringComparer.OrdinalIgnoreCase);
                    if (hasQueryParameters)
                    {
                        foreach (var queryNameValuePair in request.GetQueryNameValuePairs())
                        {
                            combinedParameterNames.Add(queryNameValuePair.Key);
                        }
                    }

                    // action parameters is a subset of route parameters and query parameters
                    for (int i = 0; i < actionsFound.Length; i++)
                    {
                        ReflectedHttpActionDescriptor descriptor = actionsFound[i];
                        if (IsSubset(_actionParameterNames[descriptor], combinedParameterNames))
                        {
                            matches.Add(descriptor);
                        }
                    }
                    if (matches.Count > 1)
                    {
                        // select the results that match the most number of required parameters
                        matches = matches
                                  .GroupBy(descriptor => _actionParameterNames[descriptor].Length)
                                  .OrderByDescending(g => g.Key)
                                  .First()
                                  .ToList();
                    }
                }
                else
                {
                    // return actions with no parameters
                    for (int i = 0; i < actionsFound.Length; i++)
                    {
                        ReflectedHttpActionDescriptor descriptor = actionsFound[i];
                        if (_actionParameterNames[descriptor].Length == 0)
                        {
                            matches.Add(descriptor);
                        }
                    }
                }
                return(matches);
            }
예제 #34
0
            public HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
            {
                string actionName;
                bool   useActionName = controllerContext.RouteData.Values.TryGetValue(ActionRouteKey, out actionName);

                ReflectedHttpActionDescriptor[] actionsFoundByHttpMethods;

                HttpMethod incomingMethod = controllerContext.Request.Method;

                // First get an initial candidate list.
                if (useActionName)
                {
                    // We have an explicit {action} value, do traditional binding. Just lookup by actionName
                    ReflectedHttpActionDescriptor[] actionsFoundByName = _actionNameMapping[actionName].ToArray();

                    // Throws HttpResponseException with NotFound status because no action matches the Name
                    if (actionsFoundByName.Length == 0)
                    {
                        throw new HttpResponseException(controllerContext.Request.CreateErrorResponse(
                                                            HttpStatusCode.NotFound,
                                                            Error.Format(SRResources.ResourceNotFound, controllerContext.Request.RequestUri),
                                                            Error.Format(SRResources.ApiControllerActionSelector_ActionNameNotFound, _controllerDescriptor.ControllerName, actionName)));
                    }

                    // This filters out any incompatible verbs from the incoming action list
                    actionsFoundByHttpMethods = actionsFoundByName.Where(actionDescriptor => actionDescriptor.SupportedHttpMethods.Contains(incomingMethod)).ToArray();
                }
                else
                {
                    // No {action} parameter, infer it from the verb.
                    actionsFoundByHttpMethods = FindActionsForVerb(incomingMethod);
                }

                // Throws HttpResponseException with MethodNotAllowed status because no action matches the Http Method
                if (actionsFoundByHttpMethods.Length == 0)
                {
                    throw new HttpResponseException(controllerContext.Request.CreateErrorResponse(
                                                        HttpStatusCode.MethodNotAllowed,
                                                        Error.Format(SRResources.ApiControllerActionSelector_HttpMethodNotSupported, incomingMethod)));
                }

                // Make sure the action parameter matches the route and query parameters. Overload resolution logic is applied when needed.
                IEnumerable <ReflectedHttpActionDescriptor> actionsFoundByParams = FindActionUsingRouteAndQueryParameters(controllerContext, actionsFoundByHttpMethods, useActionName);

                List <ReflectedHttpActionDescriptor> selectedActions = RunSelectionFilters(controllerContext, actionsFoundByParams);

                actionsFoundByHttpMethods = null;
                actionsFoundByParams      = null;

                switch (selectedActions.Count)
                {
                case 0:
                    // Throws HttpResponseException with NotFound status because no action matches the request
                    throw new HttpResponseException(controllerContext.Request.CreateErrorResponse(
                                                        HttpStatusCode.NotFound,
                                                        Error.Format(SRResources.ResourceNotFound, controllerContext.Request.RequestUri),
                                                        Error.Format(SRResources.ApiControllerActionSelector_ActionNotFound, _controllerDescriptor.ControllerName)));

                case 1:
                    return(selectedActions[0]);

                default:
                    // Throws exception because multiple actions match the request
                    string ambiguityList = CreateAmbiguousMatchList(selectedActions);
                    throw Error.InvalidOperation(SRResources.ApiControllerActionSelector_AmbiguousMatch, ambiguityList);
                }
            }
예제 #35
0
 protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
 {
     base.Initialize(controllerContext);
 }
예제 #36
0
            private ReflectedHttpActionDescriptor[] GetInitialCandidateList(HttpControllerContext controllerContext, bool ignoreVerbs = false)
            {
                HttpMethod     incomingMethod = controllerContext.Request.Method;
                IHttpRouteData routeData      = controllerContext.RouteData;

                IHttpRoute route = routeData.Route;

                ReflectedHttpActionDescriptor[] actions;
                if (route != null)
                {
                    // Attribute routing gives the action selector an explicit initial candidate list.
                    actions = routeData.GetDirectRouteActions();
                    if (actions != null)
                    {
                        if (!ignoreVerbs)
                        {
                            actions = FindActionsForVerbWorker(incomingMethod, actions);
                        }

                        return(actions);
                    }
                }

                string actionName;

                if (routeData.Values.TryGetValue(RouteKeys.ActionKey, out actionName))
                {
                    // We have an explicit {action} value, do traditional binding. Just lookup by actionName
                    ReflectedHttpActionDescriptor[] actionsFoundByName = _standardActionNameMapping[actionName].ToArray();

                    // Throws HttpResponseException with NotFound status because no action matches the Name
                    if (actionsFoundByName.Length == 0)
                    {
                        throw new HttpResponseException(controllerContext.Request.CreateErrorResponse(
                                                            HttpStatusCode.NotFound,
                                                            Error.Format(SRResources.ResourceNotFound, controllerContext.Request.RequestUri),
                                                            Error.Format(SRResources.ApiControllerActionSelector_ActionNameNotFound, _controllerDescriptor.ControllerName, actionName)));
                    }

                    if (ignoreVerbs)
                    {
                        actions = actionsFoundByName;
                    }
                    else
                    {
                        actions = FilterIncompatibleVerbs(incomingMethod, actionsFoundByName);
                    }
                }
                else
                {
                    if (ignoreVerbs)
                    {
                        actions = _standardActionDescriptors;
                    }
                    else
                    {
                        // No direct routing or {action} parameter, infer it from the verb.
                        actions = FindActionsForVerb(incomingMethod);
                    }
                }

                return(actions);
            }
 /// <summary>
 /// Executes the described action and returns a <see cref="Task{T}"/> that once completed will
 /// contain the return value of the action.
 /// </summary>
 /// <param name="controllerContext">The context.</param>
 /// <param name="arguments">The arguments.</param>
 /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
 /// <returns>A <see cref="Task{T}"/> that once completed will contain the return value of the action.</returns>
 public abstract Task <object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary <string, object> arguments, CancellationToken cancellationToken);
예제 #38
0
        private object ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary <string, object> parameters, HttpControllerContext controllerContext)
        {
            object value;

            if (!parameters.TryGetValue(parameterInfo.Name, out value))
            {
                // the key should always be present, even if the parameter value is null
                throw new HttpResponseException(controllerContext.Request.CreateErrorResponse(
                                                    HttpStatusCode.BadRequest,
                                                    SRResources.BadRequest,
                                                    Error.Format(SRResources.ReflectedActionDescriptor_ParameterNotInDictionary,
                                                                 parameterInfo.Name, parameterInfo.ParameterType, MethodInfo, MethodInfo.DeclaringType)));
            }

            if (value == null && !TypeHelper.TypeAllowsNullValue(parameterInfo.ParameterType))
            {
                // tried to pass a null value for a non-nullable parameter type
                throw new HttpResponseException(controllerContext.Request.CreateErrorResponse(
                                                    HttpStatusCode.BadRequest,
                                                    SRResources.BadRequest,
                                                    Error.Format(SRResources.ReflectedActionDescriptor_ParameterCannotBeNull,
                                                                 parameterInfo.Name, parameterInfo.ParameterType, MethodInfo, MethodInfo.DeclaringType)));
            }

            if (value != null && !parameterInfo.ParameterType.IsInstanceOfType(value))
            {
                // value was supplied but is not of the proper type
                throw new HttpResponseException(controllerContext.Request.CreateErrorResponse(
                                                    HttpStatusCode.BadRequest,
                                                    SRResources.BadRequest,
                                                    Error.Format(SRResources.ReflectedActionDescriptor_ParameterValueHasWrongType,
                                                                 parameterInfo.Name, MethodInfo, MethodInfo.DeclaringType, value.GetType(), parameterInfo.ParameterType)));
            }

            return(value);
        }
예제 #39
0
            private IEnumerable <ReflectedHttpActionDescriptor> FindActionUsingRouteAndQueryParameters(HttpControllerContext controllerContext, IEnumerable <ReflectedHttpActionDescriptor> actionsFound, bool hasActionRouteKey)
            {
                IDictionary <string, object> routeValues         = controllerContext.RouteData.Values;
                HashSet <string>             routeParameterNames = new HashSet <string>(routeValues.Keys, StringComparer.OrdinalIgnoreCase);

                routeParameterNames.Remove(ControllerRouteKey);
                if (hasActionRouteKey)
                {
                    routeParameterNames.Remove(ActionRouteKey);
                }

                HttpRequestMessage request = controllerContext.Request;
                Uri  requestUri            = request.RequestUri;
                bool hasQueryParameters    = requestUri != null && !String.IsNullOrEmpty(requestUri.Query);
                bool hasRouteParameters    = routeParameterNames.Count != 0;

                if (hasRouteParameters || hasQueryParameters)
                {
                    var combinedParameterNames = new HashSet <string>(routeParameterNames, StringComparer.OrdinalIgnoreCase);
                    if (hasQueryParameters)
                    {
                        foreach (var queryNameValuePair in request.GetQueryNameValuePairs())
                        {
                            combinedParameterNames.Add(queryNameValuePair.Key);
                        }
                    }

                    // action parameters is a subset of route parameters and query parameters
                    actionsFound = actionsFound.Where(descriptor => IsSubset(_actionParameterNames[descriptor], combinedParameterNames));

                    if (actionsFound.Count() > 1)
                    {
                        // select the results that match the most number of required parameters
                        actionsFound = actionsFound
                                       .GroupBy(descriptor => _actionParameterNames[descriptor].Length)
                                       .OrderByDescending(g => g.Key)
                                       .First();
                    }
                }
                else
                {
                    // return actions with no parameters
                    actionsFound = actionsFound.Where(descriptor => _actionParameterNames[descriptor].Length == 0);
                }

                return(actionsFound);
            }