protected virtual async Task<ActionDescriptor> SelectBestCandidate( RouteContext context, List<ActionDescriptor> candidates) { var applicableCandiates = new List<ActionDescriptorCandidate>(); foreach (var action in candidates) { var isApplicable = true; var candidate = new ActionDescriptorCandidate() { Action = action, }; var actionContext = new ActionContext(context, action); var actionBindingContext = await _bindingProvider.GetActionBindingContextAsync(actionContext); foreach (var parameter in action.Parameters.Where(p => p.ParameterBindingInfo != null)) { if (!ValueProviderResult.CanConvertFromString(parameter.ParameterBindingInfo.ParameterType)) { continue; } if (await actionBindingContext.ValueProvider.ContainsPrefixAsync( parameter.ParameterBindingInfo.Prefix)) { candidate.FoundParameters++; if (parameter.IsOptional) { candidate.FoundOptionalParameters++; } } else if (!parameter.IsOptional) { isApplicable = false; break; } } if (isApplicable) { applicableCandiates.Add(candidate); } } if (applicableCandiates.Count == 0) { return null; } var mostParametersSatisfied = applicableCandiates .GroupBy(c => c.FoundParameters) .OrderByDescending(g => g.Key) .First(); var fewestOptionalParameters = mostParametersSatisfied .GroupBy(c => c.FoundOptionalParameters) .OrderBy(g => g.Key).First() .ToArray(); if (fewestOptionalParameters.Length > 1) { throw new InvalidOperationException("The actions are ambiguious."); } return fewestOptionalParameters[0].Action; }
protected virtual async Task <ActionDescriptor> SelectBestCandidate( RouteContext context, List <ActionDescriptor> candidates) { var applicableCandiates = new List <ActionDescriptorCandidate>(); foreach (var action in candidates) { var isApplicable = true; var candidate = new ActionDescriptorCandidate() { Action = action, }; var actionContext = new ActionContext(context, action); var actionBindingContext = await _bindingProvider.GetActionBindingContextAsync(actionContext); foreach (var parameter in action.Parameters.Where(p => p.ParameterBindingInfo != null)) { if (!ValueProviderResult.CanConvertFromString(parameter.ParameterBindingInfo.ParameterType)) { continue; } if (await actionBindingContext.ValueProvider.ContainsPrefixAsync( parameter.ParameterBindingInfo.Prefix)) { candidate.FoundParameters++; if (parameter.IsOptional) { candidate.FoundOptionalParameters++; } } else if (!parameter.IsOptional) { isApplicable = false; break; } } if (isApplicable) { applicableCandiates.Add(candidate); } } if (applicableCandiates.Count == 0) { return(null); } var mostParametersSatisfied = applicableCandiates .GroupBy(c => c.FoundParameters) .OrderByDescending(g => g.Key) .First(); var fewestOptionalParameters = mostParametersSatisfied .GroupBy(c => c.FoundOptionalParameters) .OrderBy(g => g.Key).First() .ToArray(); if (fewestOptionalParameters.Length > 1) { throw new InvalidOperationException("The actions are ambiguious."); } return(fewestOptionalParameters[0].Action); }