public bool Accept(ActionConstraintContext context) { var versionValue = context.RouteContext.RouteData.Values["version"]; if (versionValue == null) return false; return _acceptedVersions.Contains(versionValue.ToString()); }
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)); }
private static ActionConstraintContext CreateActionConstraintContext(HttpMethodConstraint constraint) { var context = new ActionConstraintContext(); var actionSelectorCandidate = new ActionSelectorCandidate(new ActionDescriptor(), new List<IActionConstraint> { constraint }); context.Candidates = new List<ActionSelectorCandidate> { actionSelectorCandidate }; context.CurrentCandidate = context.Candidates[0]; return context; }
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) { var requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(_requestHeaderToMatch)) { return(false); } var parsedRequestMediaType = new MediaType(requestHeaders[_requestHeaderToMatch]); foreach (var mediaType in _mediaTypes) { var parsedMediaType = new MediaType(mediaType); if (parsedRequestMediaType.Equals(parsedMediaType)) { return(true); } } return(false); }
public void ActionConstraint_Accept_ForNoRequestType_ReturnsTrueForAllConstraints(string contentType) { // Arrange var constraint1 = new ConsumesAttribute("application/json"); var actionWithConstraint = new ActionDescriptor() { FilterDescriptors = new List <FilterDescriptor>() { new FilterDescriptor(constraint1, FilterScope.Action) } }; var constraint2 = new ConsumesAttribute("text/xml"); var actionWithConstraint2 = new ActionDescriptor() { FilterDescriptors = new List <FilterDescriptor>() { new FilterDescriptor(constraint2, FilterScope.Action) } }; var actionWithoutConstraint = new ActionDescriptor(); var context = new ActionConstraintContext(); context.Candidates = new List <ActionSelectorCandidate>() { new ActionSelectorCandidate(actionWithConstraint, new [] { constraint1 }), new ActionSelectorCandidate(actionWithConstraint2, new [] { constraint2 }), }; context.RouteContext = CreateRouteContext(contentType: contentType); // Act & Assert context.CurrentCandidate = context.Candidates[0]; Assert.True(constraint1.Accept(context)); context.CurrentCandidate = context.Candidates[1]; Assert.True(constraint2.Accept(context)); }
public bool Accept(ActionConstraintContext context) { var versionCandidates = GetDistinctVersionCandidates(context); if (versionCandidates.Count > 1) { var message = GetMultipleCandidatesExceptionMessage(versionCandidates); throw new InvalidOperationException(message); } if (!versionCandidates.Any()) { return(IsDefault); } var candidate = versionCandidates.First(); var isMatchingVersion = candidate.Equals(Version, StringComparison.InvariantCultureIgnoreCase); return(isMatchingVersion); }
public void AcceptNoArgumentsInQueryStringWhenNoneExpected() { var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>(); 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(""); var accepted = constraint.Accept(context); Assert.True(accepted); }
/// <inheritdoc /> public override bool Accept(ActionConstraintContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.RouteContext.RouteData.TryGetWebHookReceiverName(out var receiverName)) { var pingMetadata = _pingMetadata.FirstOrDefault(metadata => metadata.IsApplicable(receiverName)); return(Accept(context, _eventName, pingMetadata?.PingEventName)); } var message = string.Format( CultureInfo.CurrentCulture, Resources.EventConstraints_NoReceiverName, typeof(WebHookMultipleEventNamesConstraint), typeof(WebHookReceiverExistsConstraint)); throw new InvalidOperationException(message); }
public bool Accept(ActionConstraintContext context) { var requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(_requestHeaderToMatch)) { return(false); } foreach (var mediaType in _mediaTypes) { var mediaTypeMatches = string.Equals(requestHeaders[_requestHeaderToMatch].ToString(), mediaType, StringComparison.OrdinalIgnoreCase); if (mediaTypeMatches) { return(true); } } return(false); }
/// <inheritdoc /> public bool Accept(ActionConstraintContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (!context.RouteContext.RouteData.TryGetWebHookReceiverName(out var receiverName)) { return(false); } if (!_receiverMetadata.Any(receiver => receiver.IsApplicable(receiverName))) { return(false); } context.RouteContext.RouteData.Values[WebHookConstants.ReceiverExistsKeyName] = true; return(true); }
public void ActionConstraint_Accept_ForNoMatchingCandidates_SelectsTheFirstCandidate(string contentType) { // Arrange var constraint1 = new ConsumesAttribute("application/json", "text/xml"); var action1 = new ActionDescriptor() { FilterDescriptors = new List <FilterDescriptor>() { new FilterDescriptor(constraint1, FilterScope.Action) } }; var constraint2 = new Mock <ITestActionConsumeConstraint>(); var action2 = new ActionDescriptor() { FilterDescriptors = new List <FilterDescriptor>() { new FilterDescriptor(constraint2.Object, FilterScope.Action) } }; constraint2.Setup(o => o.Accept(It.IsAny <ActionConstraintContext>())) .Returns(false); var context = new ActionConstraintContext(); context.Candidates = new List <ActionSelectorCandidate>() { new ActionSelectorCandidate(action1, new [] { constraint1 }), new ActionSelectorCandidate(action2, new [] { constraint2.Object }), }; context.CurrentCandidate = context.Candidates[0]; context.RouteContext = CreateRouteContext(contentType: contentType); // Act & Assert Assert.True(constraint1.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.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); }
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.RouteContext.RouteData.Values.ContainsKey("appId")) { return(true); } var css = context.RouteContext.HttpContext.RequestServices.GetService <CssThemeManager>(); if (css?.DomainToAppMapping is List <PoliciesSettings.DomainToAppMappingItem> mapping) { var matchedDomainMapping = css.DomainToAppMapping.FirstOrDefault(item => item.Domain.Equals(context.RouteContext.HttpContext.Request.Host.Host, StringComparison.InvariantCultureIgnoreCase)); if (matchedDomainMapping is PoliciesSettings.DomainToAppMappingItem) { if (!(AppType is AppType appType)) { return(false); } if (appType != matchedDomainMapping.AppType) { return(false); } context.RouteContext.RouteData.Values.Add("appId", matchedDomainMapping.AppId); return(true); } if (AppType == css.RootAppType) { context.RouteContext.RouteData.Values.Add("appId", css.RootAppId); return(true); } return(AppType is null); } else { return(AppType is null); } }
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 bool Accept(ActionConstraintContext context) { IHeaderDictionary requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(_requestHeaderToMatch)) { return(false); } MediaType parsedRequestMediaType = new MediaType(requestHeaders[_requestHeaderToMatch]); // if one of the media types matches, return true foreach (var mediaType in _mediaTypes) { MediaType parsedMatchingMediaType = new MediaType(mediaType); if (parsedRequestMediaType.Equals(parsedMatchingMediaType)) { return(true); } } return(false); }
public void Accept_AcceptsActionWithUnsatisfiedOptionalParameter() { // Arrange var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>() { new ParameterDescriptor() { BinderMetadata = new FromUriAttribute(), Name = "id", ParameterType = typeof(int), }, new ParameterDescriptor() { BinderMetadata = new FromUriAttribute() { IsOptional = true }, 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("?store=5", new { id = 17 }); // Act & Assert Assert.True(constraint.Accept(context)); }
public bool Accept(ActionConstraintContext context) { IHeaderDictionary requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(c_requestHeaderToMatch)) { return(false); } // if one of the media types matches, return true foreach (string mediaType in c_mediaTypes) { bool mediaTypeMatches = string.Equals(requestHeaders[c_requestHeaderToMatch].ToString(), mediaType, StringComparison.OrdinalIgnoreCase); if (mediaTypeMatches) { return(true); } } return(false); }
private static bool ActionConstaint(ActionDescriptor actionDescriptor, HttpContext httpContext, RouteValueDictionary values, String httpMethod) { if (actionDescriptor.ActionConstraints == null) { if (actionDescriptor is ControllerActionDescriptor controllerActionDescriptor) { return(String.Compare(controllerActionDescriptor.ActionName, httpMethod, StringComparison.OrdinalIgnoreCase) == 0); } else { return(false); } } var candidate = new ActionSelectorCandidate(actionDescriptor, Array.Empty <IActionConstraint>()); var constraintContext = new ActionConstraintContext() { CurrentCandidate = candidate }; if (constraintContext.RouteContext == null) { constraintContext.RouteContext = new RouteContext(httpContext) { RouteData = new RouteData(values) } } ; for (int i = 0; i < actionDescriptor.ActionConstraints.Count; i++) { if (actionDescriptor.ActionConstraints[i] is IActionConstraint actionConstraint && actionConstraint.Accept(constraintContext)) { return(true); } } return(false); }
public bool Accept(ActionConstraintContext context) { var requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(_requestHeaderToMatch)) { return(false); } foreach (var mediaTypes in _mediaTypes) { var headerValues = requestHeaders[_requestHeaderToMatch].ToString().Split(',').ToList(); foreach (var headerValue in headerValues) { if (string.Equals(headerValue, mediaTypes, StringComparison.OrdinalIgnoreCase)) { return(true); } } } return(false); }
public bool Accept(ActionConstraintContext context) { if (context.RouteContext.RouteData.Values.ContainsKey("appId")) { return(true); } var settingsRepository = context.RouteContext.HttpContext.RequestServices.GetService <ISettingsRepository>(); var policies = settingsRepository.GetPolicies().GetAwaiter().GetResult(); if (policies?.DomainToAppMapping is { } mapping) { var matchedDomainMapping = mapping.FirstOrDefault(item => item.Domain.Equals(context.RouteContext.HttpContext.Request.Host.Host, StringComparison.InvariantCultureIgnoreCase)); if (matchedDomainMapping != null) { if (!(AppType is { } appType)) { return(false); } if (appType != matchedDomainMapping.AppType) { return(false); } context.RouteContext.RouteData.Values.Add("appId", matchedDomainMapping.AppId); return(true); } if (AppType == policies.RootAppType) { context.RouteContext.RouteData.Values.Add("appId", policies.RootAppId); return(true); } return(AppType is null); } return(AppType is null); }
public override bool Accept(ActionConstraintContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var methods = (ReadOnlyCollection <string>)HttpMethods; if (methods.Count == 0) { return(true); } var request = context.RouteContext.HttpContext.Request; // Perf: Check http method before accessing the Headers collection. if (Http.HttpMethods.IsOptions(request.Method) && request.Headers.ContainsKey(OriginHeader) && request.Headers.TryGetValue(AccessControlRequestMethod, out var accessControlRequestMethod) && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) { // Read interface .Count once rather than per iteration var methodsCount = methods.Count; for (var i = 0; i < methodsCount; i++) { var supportedMethod = methods[i]; if (string.Equals(supportedMethod, accessControlRequestMethod, StringComparison.OrdinalIgnoreCase)) { return(true); } } return(false); } return(base.Accept(context)); }
/// <inheritdoc /> public bool Accept(ActionConstraintContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (!context.RouteContext.RouteData.TryGetWebHookReceiverName( context.CurrentCandidate.Action, out var receiverName)) { return(false); } if (_bodyTypeMetadata == null) { if (_metadataProvider.GetBodyTypeMetadata(receiverName) == null) { // Received a request for (say) https://{host}/api/webhooks/incoming/mine but the "mine" receiver // is not configured. But, probably not a misconfiguration in this application. // WebHookMetadataProvier detects "incomplete" receivers i.e. those with some metadata // services but lacking an IWebHookBodyTypeMetadataService implementation. return(false); } } else { if (!_bodyTypeMetadata.IsApplicable(receiverName)) { // Received a request for (say) https://{host}/api/webhooks/incoming/their but this action is // configured for the "mine" receiver. return(false); } } context.RouteContext.RouteData.Values[WebHookConstants.ReceiverExistsKeyName] = true; return(true); }
public bool Accept(ActionConstraintContext context) { var requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(_requestHeaderToMatch)) { return(false); } // if one of the media types matches, return true foreach (var version in _versions) { var versionMatches = string.Equals(requestHeaders[_requestHeaderToMatch].ToString(), version, StringComparison.OrdinalIgnoreCase); if (versionMatches) { return(true); } } return(false); }
public void RejectMultiValueStringWithoutCollection() { var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>() { CreateArgument("argument_string", typeof(string), new FromQueryAttribute()) }; 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("?argument_string=abc&argument_string=def&argument_string=xyz"); var accepted = constraint.Accept(context); Assert.False(accepted); }
public void RejectFromQueryArgumentWithWrongName() { var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>() { CreateArgument("argument_int", typeof(int), new FromQueryAttribute()) }; 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("?wrong_name=3"); var accepted = constraint.Accept(context); Assert.False(accepted); }
public bool Accept(ActionConstraintContext context) { var requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(_requestHeaderToMatch)) { return(false); } string[] requestHeaderMediaTypes = requestHeaders[_requestHeaderToMatch].ToString().Split(','); foreach (string expectedMediaType in _expectedMediaTypes) { foreach (string requestHeaderMediaTypeValue in requestHeaderMediaTypes) { if (expectedMediaType.Equals(requestHeaderMediaTypeValue, StringComparison.OrdinalIgnoreCase)) { return(true); } } } return(false); }
public void AcceptMultiValueIntInCollection() { var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>() { CreateArgument("argument_int", typeof(IEnumerable <int>), new FromQueryAttribute()) }; 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("?argument_int=1&argument_int=2&argument_int=3"); var accepted = constraint.Accept(context); Assert.True(accepted); }
/// <inheritdoc /> public bool Accept(ActionConstraintContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var routeContext = context.RouteContext; if (routeContext.RouteData.TryGetWebHookReceiverName(out var receiverName)) { var eventMetadata = _eventMetadata.FirstOrDefault(metadata => metadata.IsApplicable(receiverName)); if (eventMetadata != null) { return(Accept(eventMetadata, routeContext)); } // This receiver does not have IWebHookEventMetadata and that's fine. return(true); } // ??? Should we throw if this is reached? Should be impossible given WebHookReceiverExistsConstraint. return(false); }
/// <summary> /// 判断该方法是否能处理这个请求 /// </summary> /// <param name="context">上下文</param> /// <returns>是否能处理这个请求</returns> public bool Accept(ActionConstraintContext context) { //判断 Header 中是否含有 _requestHeaderToMatch(key) var requestHeaders = context.RouteContext.HttpContext.Request.Headers; if (!requestHeaders.ContainsKey(_requestHeaderToMatch)) { return(false); } //如果含有该 key,判断 value 是否包含在支持的媒体类型集合中 var parsedRequestMediaType = new MediaType(requestHeaders[_requestHeaderToMatch]); foreach (var mediaType in _mediaTypes) { var parsedMediaType = new MediaType(mediaType); if (parsedRequestMediaType.Equals(parsedMediaType)) { return(true); } } return(false); }
public void RejectQueryStringArgumentWithoutBinderMetadata() { var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>() { CreateArgument("argument_int", typeof(int), null) }; 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("?argument_int=3"); var accepted = constraint.Accept(context); Assert.False(accepted); }
public void AcceptArgumentWithDifferentCasingInActionParameter() { var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>() { CreateArgument("Argument_Int", typeof(int), new FromQueryAttribute()) }; 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("?argument_int=3"); var accepted = constraint.Accept(context); Assert.True(accepted); }
public void AcceptIntValueWhenStringExpected() { var action = new ActionDescriptor(); action.Parameters = new List <ParameterDescriptor>() { CreateArgument("argument_string", typeof(string), new FromQueryAttribute()) }; 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("?argument_string=3"); var accepted = constraint.Accept(context); Assert.True(accepted); }
public bool Accept(ActionConstraintContext context) { return _requestId == _requestIdService.RequestId; }
public void Accept_UnrecognizedMediaType_SelectsTheCandidateWithoutConstraintIfPresent(string contentType) { // Arrange var actionWithoutConstraint = new ActionDescriptor(); var constraint1 = new ConsumesAttribute("application/json"); var actionWithConstraint = new ActionDescriptor() { FilterDescriptors = new List<FilterDescriptor>() { new FilterDescriptor(constraint1, FilterScope.Action) } }; var constraint2 = new ConsumesAttribute("text/xml"); var actionWithConstraint2 = new ActionDescriptor() { FilterDescriptors = new List<FilterDescriptor>() { new FilterDescriptor(constraint2, FilterScope.Action) } }; var context = new ActionConstraintContext(); context.Candidates = new List<ActionSelectorCandidate>() { new ActionSelectorCandidate(actionWithConstraint, new [] { constraint1 }), new ActionSelectorCandidate(actionWithConstraint2, new [] { constraint2 }), new ActionSelectorCandidate(actionWithoutConstraint, new List<IActionConstraint>()), }; context.RouteContext = CreateRouteContext(contentType: contentType); // Act & Assert context.CurrentCandidate = context.Candidates[0]; Assert.False(constraint1.Accept(context)); context.CurrentCandidate = context.Candidates[1]; Assert.False(constraint2.Accept(context)); }
public void Accept_ForNoRequestType_ReturnsTrueForAllConstraints(string contentType) { // Arrange var constraint1 = new ConsumesAttribute("application/json"); var actionWithConstraint = new ActionDescriptor() { FilterDescriptors = new List<FilterDescriptor>() { new FilterDescriptor(constraint1, FilterScope.Action) } }; var constraint2 = new ConsumesAttribute("text/xml"); var actionWithConstraint2 = new ActionDescriptor() { FilterDescriptors = new List<FilterDescriptor>() { new FilterDescriptor(constraint2, FilterScope.Action) } }; var actionWithoutConstraint = new ActionDescriptor(); var context = new ActionConstraintContext(); context.Candidates = new List<ActionSelectorCandidate>() { new ActionSelectorCandidate(actionWithConstraint, new [] { constraint1 }), new ActionSelectorCandidate(actionWithConstraint2, new [] { constraint2 }), }; context.RouteContext = CreateRouteContext(contentType: contentType); // Act & Assert context.CurrentCandidate = context.Candidates[0]; Assert.True(constraint1.Accept(context)); context.CurrentCandidate = context.Candidates[1]; Assert.True(constraint2.Accept(context)); }
public void Accept_MatchesForMachingRequestContentType(string contentType) { // Arrange var constraint = new ConsumesAttribute("application/json", "text/xml"); var action = new ActionDescriptor() { FilterDescriptors = new List<FilterDescriptor>() { new FilterDescriptor(constraint, FilterScope.Action) } }; var context = new ActionConstraintContext(); context.Candidates = new List<ActionSelectorCandidate>() { new ActionSelectorCandidate(action, new [] { constraint }), }; context.CurrentCandidate = context.Candidates[0]; context.RouteContext = CreateRouteContext(contentType: contentType); // Act & Assert Assert.True(constraint.Accept(context)); }
public bool Accept(ActionConstraintContext context) { // If this constraint is not closest to the action, it will be skipped. if (!IsApplicable(context.CurrentCandidate.Action)) { // Since the constraint is to be skipped, returning true here // will let the current candidate ignore this constraint and will // be selected based on other constraints for this action. return true; } MediaTypeHeaderValue requestContentType = null; MediaTypeHeaderValue.TryParse(context.RouteContext.HttpContext.Request.ContentType, out requestContentType); // If the request content type is null we need to act like pass through. // In case there is a single candidate with a constraint it should be selected. // If there are multiple actions with consumes action constraints this should result in ambiguous exception // unless there is another action without a consumes constraint. if (requestContentType == null) { var isActionWithoutConsumeConstraintPresent = context.Candidates.Any( candidate => candidate.Constraints == null || !candidate.Constraints.Any(constraint => constraint is IConsumesActionConstraint)); return !isActionWithoutConsumeConstraintPresent; } // Confirm the request's content type is more specific than a media type this action supports e.g. OK // if client sent "text/plain" data and this action supports "text/*". if (ContentTypes.Any(contentType => requestContentType.IsSubsetOf(contentType))) { return true; } var firstCandidate = context.Candidates[0]; if (firstCandidate != context.CurrentCandidate) { // If the current candidate is not same as the first candidate, // we need not probe other candidates to see if they apply. // Only the first candidate is allowed to probe other candidates and based on the result select itself. return false; } // Run the matching logic for all IConsumesActionConstraints we can find, and see what matches. // 1). If we have a unique best match, then only that constraint should return true. // 2). If we have multiple matches, then all constraints that match will return true // , resulting in ambiguity(maybe). // 3). If we have no matches, then we choose the first constraint to return true.It will later return a 415 foreach (var candidate in context.Candidates) { if (candidate == firstCandidate) { continue; } var tempContext = new ActionConstraintContext() { Candidates = context.Candidates, RouteContext = context.RouteContext, CurrentCandidate = candidate }; if (candidate.Constraints == null || candidate.Constraints.Count == 0 || candidate.Constraints.Any(constraint => constraint is IConsumesActionConstraint && constraint.Accept(tempContext))) { // There is someone later in the chain which can handle the request. // end the process here. return false; } } // There is no one later in the chain that can handle this content type return a false positive so that // later we can detect and return a 415. return true; }
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)); }
bool IActionConstraint.Accept(ActionConstraintContext context) { return(AcceptCore()); }
public void Accept_ForNoMatchingCandidates_SelectsTheFirstCandidate(string contentType) { // Arrange var constraint1 = new ConsumesAttribute("application/json", "text/xml"); var action1 = new ActionDescriptor() { FilterDescriptors = new List<FilterDescriptor>() { new FilterDescriptor(constraint1, FilterScope.Action) } }; var constraint2 = new Mock<ITestConsumeConstraint>(); var action2 = new ActionDescriptor() { FilterDescriptors = new List<FilterDescriptor>() { new FilterDescriptor(constraint2.Object, FilterScope.Action) } }; constraint2.Setup(o => o.Accept(It.IsAny<ActionConstraintContext>())) .Returns(false); var context = new ActionConstraintContext(); context.Candidates = new List<ActionSelectorCandidate>() { new ActionSelectorCandidate(action1, new [] { constraint1 }), new ActionSelectorCandidate(action2, new [] { constraint2.Object }), }; context.CurrentCandidate = context.Candidates[0]; context.RouteContext = CreateRouteContext(contentType: contentType); // Act & Assert Assert.True(constraint1.Accept(context)); }