public void Accept_RejectsActionMatchWithMissingParameter() { // Arrange var action = new ActionDescriptor(); action.Parameters = new List<ParameterDescriptor>() { new ParameterDescriptor() { BindingInfo = new BindingInfo() { BindingSource = (new FromUriAttribute()).BindingSource, }, Name = "id", ParameterType = typeof(int), }, }; var constraint = new OverloadActionConstraint(); var context = new ActionConstraintContext(); context.Candidates = new List<ActionSelectorCandidate>() { new ActionSelectorCandidate(action, new [] { constraint }), }; context.CurrentCandidate = context.Candidates[0]; context.RouteContext = CreateRouteContext(); // Act & Assert Assert.False(constraint.Accept(context)); }
public bool Accept(ActionConstraintContext context) { return string.Equals( context.RouteContext.RouteData.Values["country"].ToString(), _countryCode, StringComparison.OrdinalIgnoreCase); }
public bool Accept(ActionConstraintContext context) { int version; if (int.TryParse(GetVersion(context.RouteContext.HttpContext.Request), out version)) { return (_minVersion == null || _minVersion <= version) && (_maxVersion == null || _maxVersion >= version); } else { return false; } }
public bool Accept(ActionConstraintContext context) { var candidates = context.Candidates.Select(c => new { Action = c, Parameters = GetOverloadableParameters(c), }); // Combined route value keys and query string keys. These are the values available for overload selection. var requestKeys = GetCombinedKeys(context.RouteContext); // Group candidates by the highest number of keys, and then process them until we find an action // with all parameters satisfied. foreach (var group in candidates.GroupBy(c => c.Parameters?.Count ?? 0).OrderByDescending(g => g.Key)) { var foundMatch = false; foreach (var candidate in group) { var allFound = true; if (candidate.Parameters != null) { foreach (var parameter in candidate.Parameters) { if (!requestKeys.Contains(parameter.Prefix)) { if (candidate.Action.Action == context.CurrentCandidate.Action) { return false; } allFound = false; break; } } } if (allFound) { foundMatch = true; } } if (foundMatch) { return group.Any(c => c.Action.Action == context.CurrentCandidate.Action); } } return false; }
public bool Accept(ActionConstraintContext context) { //Initialize the context, this will be called a few times but the initialize logic // only executes once. There might be a nicer way to do this but the RouteContext and // other request scoped instances are not available yet. _umbCtx.Initialize(context.RouteContext.RouteData); if (_umbCtx.HasContent == false) return false; //NOTE: This was for testing at some point! //if (((ControllerActionDescriptor)context.CurrentCandidate.Action) // .ControllerName == "TestSurface") //{ // return true; //} return false; }
public void Accept_AcceptsActionWithSatisfiedParameters() { // Arrange var action = new ActionDescriptor(); action.Parameters = new List<ParameterDescriptor>() { new ParameterDescriptor() { BindingInfo = new BindingInfo() { BindingSource = (new FromUriAttribute()).BindingSource, }, Name = "id", ParameterType = typeof(int), }, new ParameterDescriptor() { BindingInfo = new BindingInfo() { BindingSource = (new FromUriAttribute()).BindingSource, }, Name = "quantity", ParameterType = typeof(int), }, }; var constraint = new OverloadActionConstraint(); var context = new ActionConstraintContext(); context.Candidates = new List<ActionSelectorCandidate>() { new ActionSelectorCandidate(action, new [] { constraint }), }; context.CurrentCandidate = context.Candidates[0]; context.RouteContext = CreateRouteContext("?quantity=5", new { id = 17 }); // Act & Assert Assert.True(constraint.Accept(context)); }
public bool Accept(ActionConstraintContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (_httpMethods.Count == 0) { return(true); } var request = context.RouteContext.HttpContext.Request; var method = request.Method; if (request.Headers.ContainsKey(OriginHeader)) { // Update the http method if it is preflight request. var accessControlRequestMethod = request.Headers[AccessControlRequestMethod]; if (string.Equals( request.Method, PreflightHttpMethod, StringComparison.Ordinal) && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) { method = accessControlRequestMethod; } } for (var i = 0; i < _httpMethods.Count; i++) { var supportedMethod = _httpMethods[i]; if (string.Equals(supportedMethod, method, StringComparison.Ordinal)) { return(true); } } return(false); }
public bool Accept(ActionConstraintContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (_httpMethods.Count == 0) { return true; } var request = context.RouteContext.HttpContext.Request; var method = request.Method; if (request.Headers.ContainsKey(OriginHeader)) { // Update the http method if it is preflight request. var accessControlRequestMethod = request.Headers[AccessControlRequestMethod]; if (string.Equals( request.Method, PreflightHttpMethod, StringComparison.OrdinalIgnoreCase) && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) { method = accessControlRequestMethod; } } for (var i = 0; i < _httpMethods.Count; i++) { var supportedMethod = _httpMethods[i]; if (string.Equals(supportedMethod, method, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; }
private IReadOnlyList<ActionSelectorCandidate> EvaluateActionConstraints( RouteContext context, IReadOnlyList<ActionSelectorCandidate> candidates, int? startingOrder) { // Find the next group of constraints to process. This will be the lowest value of // order that is higher than startingOrder. int? order = null; // Perf: Avoid allocations for (var i = 0; i < candidates.Count; i++) { var candidate = candidates[i]; if (candidate.Constraints != null) { for (var j = 0; j < candidate.Constraints.Count; j++) { var constraint = candidate.Constraints[j]; if ((startingOrder == null || constraint.Order > startingOrder) && (order == null || constraint.Order < order)) { order = constraint.Order; } } } } // If we don't find a 'next' then there's nothing left to do. if (order == null) { return candidates; } // Since we have a constraint to process, bisect the set of actions into those with and without a // constraint for the 'current order'. var actionsWithConstraint = new List<ActionSelectorCandidate>(); var actionsWithoutConstraint = new List<ActionSelectorCandidate>(); var constraintContext = new ActionConstraintContext(); constraintContext.Candidates = candidates; constraintContext.RouteContext = context; // Perf: Avoid allocations for (var i = 0; i < candidates.Count; i++) { var candidate = candidates[i]; var isMatch = true; var foundMatchingConstraint = false; if (candidate.Constraints != null) { constraintContext.CurrentCandidate = candidate; for (var j = 0; j < candidate.Constraints.Count; j++) { var constraint = candidate.Constraints[j]; if (constraint.Order == order) { foundMatchingConstraint = true; if (!constraint.Accept(constraintContext)) { isMatch = false; _logger.LogVerbose( "Action '{ActionDisplayName}' with id '{ActionId}' did not match the " + "constraint '{ActionConstraint}'", candidate.Action.DisplayName, candidate.Action.Id, constraint); break; } } } } if (isMatch && foundMatchingConstraint) { actionsWithConstraint.Add(candidate); } else if (isMatch) { actionsWithoutConstraint.Add(candidate); } } // If we have matches with constraints, those are 'better' so try to keep processing those if (actionsWithConstraint.Count > 0) { var matches = EvaluateActionConstraints(context, actionsWithConstraint, order); if (matches?.Count > 0) { return matches; } } // If the set of matches with constraints can't work, then process the set without constraints. if (actionsWithoutConstraint.Count == 0) { return null; } else { return EvaluateActionConstraints(context, actionsWithoutConstraint, order); } }
public bool Accept(ActionConstraintContext context) { return Pass; }
private IReadOnlyList<ActionSelectorCandidate> EvaluateActionConstraints( RouteContext context, IReadOnlyList<ActionSelectorCandidate> candidates, int? startingOrder) { // Find the next group of constraints to process. This will be the lowest value of // order that is higher than startingOrder. int? order = null; foreach (var candidate in candidates) { if (candidate.Constraints != null) { foreach (var constraint in candidate.Constraints) { if ((startingOrder == null || constraint.Order > startingOrder) && (order == null || constraint.Order < order)) { order = constraint.Order; } } } } // If we don't find a 'next' then there's nothing left to do. if (order == null) { return candidates; } // Since we have a constraint to process, bisect the set of actions into those with and without a // constraint for the 'current order'. var actionsWithConstraint = new List<ActionSelectorCandidate>(); var actionsWithoutConstraint = new List<ActionSelectorCandidate>(); var constraintContext = new ActionConstraintContext(); constraintContext.Candidates = candidates; constraintContext.RouteContext = context; foreach (var candidate in candidates) { var isMatch = true; var foundMatchingConstraint = false; if (candidate.Constraints != null) { constraintContext.CurrentCandidate = candidate; foreach (var constraint in candidate.Constraints) { if (constraint.Order == order) { foundMatchingConstraint = true; if (!constraint.Accept(constraintContext)) { isMatch = false; break; } } } } if (isMatch && foundMatchingConstraint) { actionsWithConstraint.Add(candidate); } else if (isMatch) { actionsWithoutConstraint.Add(candidate); } } // If we have matches with constraints, those are 'better' so try to keep processing those if (actionsWithConstraint.Count > 0) { var matches = EvaluateActionConstraints(context, actionsWithConstraint, order); if (matches?.Count > 0) { return matches; } } // If the set of matches with constraints can't work, then process the set without constraints. if (actionsWithoutConstraint.Count == 0) { return null; } else { return EvaluateActionConstraints(context, actionsWithoutConstraint, order); } }
public void Accept_AcceptsAction_WithFewerParameters_WhenOtherIsNotOverloaded() { // Arrange var action1 = new ActionDescriptor(); action1.Parameters = new List<ParameterDescriptor>() { new ParameterDescriptor() { BindingInfo = new BindingInfo() { BindingSource = (new FromUriAttribute()).BindingSource, }, Name = "id", ParameterType = typeof(int), }, }; var action2 = new ActionDescriptor(); action2.Parameters = new List<ParameterDescriptor>() { new ParameterDescriptor() { BindingInfo = new BindingInfo() { BindingSource = (new FromUriAttribute()).BindingSource, }, Name = "id", ParameterType = typeof(int), }, new ParameterDescriptor() { BindingInfo = new BindingInfo() { BindingSource = (new FromUriAttribute()).BindingSource, }, Name = "quantity", ParameterType = typeof(int), }, }; var optionalParameters = new HashSet<string>(); optionalParameters.Add("quantity"); action2.Properties.Add("OptionalParameters", optionalParameters); var constraint = new OverloadActionConstraint(); var context = new ActionConstraintContext(); context.Candidates = new List<ActionSelectorCandidate>() { new ActionSelectorCandidate(action1, new [] { constraint }), new ActionSelectorCandidate(action2, new IActionConstraint[] { }), }; context.CurrentCandidate = context.Candidates[0]; context.RouteContext = CreateRouteContext("?quantity=5", new { id = 17 }); // Act & Assert Assert.True(constraint.Accept(context)); }
public bool Accept(ActionConstraintContext context) { return false; }
/// <inheritdoc /> public bool Accept(ActionConstraintContext context) { return(IsValidForRequest(context.RouteContext, context.CurrentCandidate.Action)); }
public bool Accept(ActionConstraintContext context) { return _requestId == _requestIdService.RequestId; }
/// <inheritdoc /> public bool Accept(ActionConstraintContext context) { return IsValidForRequest(context.RouteContext, context.CurrentCandidate.Action); }