Exemple #1
0
 private void ExploreRouteActions(IHttpRoute route, string localPath, HttpControllerDescriptor controllerDescriptor, Collection <ApiDescription> apiDescriptions)
 {
     // exclude controllers that are marked with route attributes.
     if (!controllerDescriptor.HasRoutingAttribute())
     {
         ServicesContainer controllerServices = controllerDescriptor.Configuration.Services;
         ILookup <string, HttpActionDescriptor> actionMappings = controllerServices.GetActionSelector().GetActionMapping(controllerDescriptor);
         string actionVariableValue;
         if (actionMappings != null)
         {
             if (_actionVariableRegex.IsMatch(localPath))
             {
                 // unbound action variable, {action}
                 foreach (IGrouping <string, HttpActionDescriptor> actionMapping in actionMappings)
                 {
                     // expand {action} variable
                     actionVariableValue = actionMapping.Key;
                     string expandedLocalPath = _actionVariableRegex.Replace(localPath, actionVariableValue);
                     PopulateActionDescriptions(actionMapping, actionVariableValue, route, expandedLocalPath, apiDescriptions, controllerDescriptor);
                 }
             }
             else if (route.Defaults.TryGetValue(RouteValueKeys.Action, out actionVariableValue))
             {
                 // bound action variable, { action = "actionName" }
                 PopulateActionDescriptions(actionMappings[actionVariableValue], actionVariableValue, route, localPath, apiDescriptions, controllerDescriptor);
             }
             else
             {
                 // no {action} specified, e.g. {controller}/{id}
                 foreach (IGrouping <string, HttpActionDescriptor> actionMapping in actionMappings)
                 {
                     PopulateActionDescriptions(actionMapping, null, route, localPath, apiDescriptions, controllerDescriptor);
                 }
             }
         }
     }
 }
            public ActionSelectorCacheItem(HttpControllerDescriptor controllerDescriptor)
            {
                Contract.Assert(controllerDescriptor != null);

                // Initialize the cache entirely in the ctor on a single thread.
                _controllerDescriptor = controllerDescriptor;

                MethodInfo[] allMethods = _controllerDescriptor.ControllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public);
                MethodInfo[] validMethods = Array.FindAll(allMethods, IsValidActionMethod);

                _combinedCandidateActions = new CandidateAction[validMethods.Length];
                for (int i = 0; i < validMethods.Length; i++)
                {
                    MethodInfo method = validMethods[i];
                    ReflectedHttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(_controllerDescriptor, method);
                    _combinedCandidateActions[i] = new CandidateAction
                    {
                        ActionDescriptor = actionDescriptor
                    };
                    HttpActionBinding actionBinding = actionDescriptor.ActionBinding;

                    // Building an action parameter name mapping to compare against the URI parameters coming from the request. Here we only take into account required parameters that are simple types and come from URI.
                    _actionParameterNames.Add(
                        actionDescriptor,
                        actionBinding.ParameterBindings
                            .Where(binding => !binding.Descriptor.IsOptional && TypeHelper.CanConvertFromString(binding.Descriptor.ParameterType) && binding.WillReadUri())
                            .Select(binding => binding.Descriptor.Prefix ?? binding.Descriptor.ParameterName).ToArray());
                }

                if (controllerDescriptor.HasRoutingAttribute())
                {
                    // The controller has an attribute route; no actions are accessible via standard routing.
                    _standardCandidateActions = new CandidateAction[0];
                }
                else
                {
                    // The controller does not have an attribute route; some actions may be accessible via standard
                    // routing.
                    List<CandidateAction> standardCandidateActions = new List<CandidateAction>();

                    for (int i = 0; i < _combinedCandidateActions.Length; i++)
                    {
                        CandidateAction candidate = _combinedCandidateActions[i];
                        // Allow standard routes access inherited actions or actions without Route attributes.
                        if (((ReflectedHttpActionDescriptor)candidate.ActionDescriptor).MethodInfo.DeclaringType != controllerDescriptor.ControllerType
                            || !candidate.ActionDescriptor.HasRoutingAttribute())
                        {
                            standardCandidateActions.Add(candidate);
                        }
                    }

                    _standardCandidateActions = standardCandidateActions.ToArray();
                }

                _combinedActionNameMapping = _combinedCandidateActions.Select(c => c.ActionDescriptor).ToLookup(actionDesc => actionDesc.ActionName, StringComparer.OrdinalIgnoreCase);
                _standardActionNameMapping = _standardCandidateActions.Select(c => c.ActionDescriptor).ToLookup(actionDesc => actionDesc.ActionName, StringComparer.OrdinalIgnoreCase);

                // Bucket the action descriptors by common verbs.
                int len = _cacheListVerbKinds.Length;
                _cacheListVerbs = new CandidateAction[len][];
                for (int i = 0; i < len; i++)
                {
                    _cacheListVerbs[i] = FindActionsForVerbWorker(_cacheListVerbKinds[i]);
                }
            }