Example #1
0
        /// <summary>
        /// Creates a new <see cref="InlineConstraint"/> instance given a <see cref="RoutePatternParameterPolicyReference"/>.
        /// </summary>
        /// <param name="other">A <see cref="RoutePatternParameterPolicyReference"/> instance.</param>
        public InlineConstraint(RoutePatternParameterPolicyReference other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            Constraint = other.Content !;
        }
        private bool IsCustomPolicyReference(RoutePatternParameterPolicyReference policyReference)
        {
            if (policyReference.Content == null && policyReference.ParameterPolicy != null)
            {
                return(true);
            }

            bool isCustomPolicyReference = !(policyReference.Content.Equals("alpha") ||
                                             policyReference.Content.StartsWith("regex"));

            return(isCustomPolicyReference);
        }
        private bool PassPolicyReference(string term, RoutePatternParameterPolicyReference policy)
        {
            var isValid = false;

            if (string.IsNullOrEmpty(term) || policy == null)
            {
                return(false); // something is wrong here..?
            }

            if (policy.Content.StartsWith("regex"))
            {
                isValid = new Regex(policy.Content.Replace("regex", string.Empty)).IsMatch(term);
            }

            return(isValid);
        }
        /// <summary>
        /// Creates a parameter policy.
        /// </summary>
        /// <param name="parameter">The parameter the parameter policy is being created for.</param>
        /// <param name="reference">The reference to resolve.</param>
        /// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns>
        public IParameterPolicy Create(RoutePatternParameterPart parameter, RoutePatternParameterPolicyReference reference)
        {
            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }

            Debug.Assert(reference.ParameterPolicy != null || reference.Content != null);

            if (reference.ParameterPolicy != null)
            {
                return(Create(parameter, reference.ParameterPolicy));
            }

            if (reference.Content != null)
            {
                return(Create(parameter, reference.Content));
            }

            // Unreachable
            throw new NotSupportedException();
        }
Example #5
0
 public int GetHashCode(RoutePatternParameterPolicyReference obj)
 {
     throw new NotImplementedException();
 }
Example #6
0
 public bool Equals(RoutePatternParameterPolicyReference x, RoutePatternParameterPolicyReference y)
 {
     return
         (x.Content == y.Content &&
          x.ParameterPolicy == y.ParameterPolicy);
 }
        private bool IsValidRoutePolicy(ParameterDescriptor parameter, RoutePatternParameterPolicyReference policy)
        {
            var isValid = false;

            if (policy != null && string.IsNullOrEmpty(policy.Content) &&
                policy.ParameterPolicy is RegexRouteConstraint regexRouteConstraint)
            {
                var parameterType = parameter.ParameterType;
                if (parameterType.IsValueType)
                {
                    var regex            = regexRouteConstraint.Constraint;
                    var defaultTypeValue = Activator.CreateInstance(parameterType);
                    isValid = regex.IsMatch(defaultTypeValue.ToString());
                }
                else if (policy.ParameterPolicy is AlphaRouteConstraint && parameter.BindingInfo == null)
                {
                    isValid = true;
                }

                return(isValid);
            }

            switch (policy.Content)
            {
            case "alpha":
                isValid = parameter.ParameterType == typeof(string);
                break;

            case "int":
                isValid = parameter.ParameterType == typeof(int);
                break;

            case "bool":
                isValid = parameter.ParameterType == typeof(bool);
                break;

            case "datetime":
                isValid = parameter.ParameterType == typeof(DateTime);
                break;

            case "decimal":
                isValid = parameter.ParameterType == typeof(decimal);
                break;

            case "double":
                isValid = parameter.ParameterType == typeof(double);
                break;

            case "float":
                isValid = parameter.ParameterType == typeof(float);
                break;

            case "guid":
                isValid = parameter.ParameterType == typeof(Guid);
                break;

            case "long":
                isValid = parameter.ParameterType == typeof(long);
                break;
            }

            return(isValid);
        }
        public string ResolveRouteTemplate(ActionDescriptor actionDescriptor, SwaggerRoutingOptions options)
        {
            var routes           = ConventionalRoutingSwaggerGen.ROUTES;
            var template         = string.Empty;
            var templateDefaults = new Dictionary <string, string>();

            if (routes != null)
            {
                foreach (var route in routes)
                {
                    templateDefaults.Clear();
                    var isDefaultArea       = false;
                    var isDefaultController = false;
                    var isDefaultAction     = false;

                    if (route != null)
                    {
                        if (options?.IgnoreTemplateFunc != null)
                        {
                            var ignoreRoute = options.IgnoreTemplateFunc(route.RawText);
                            if (ignoreRoute)
                            {
                                continue;
                            }
                        }

                        var routeArea       = GetRouteArea(route, out bool isAreaParameter);
                        var routeController = GetRouteController(route, out var isControllerParameter);
                        var routeAction     = GetRouteAction(route, out bool isActionParameter);

                        var actionDescArea       = GetActionDescriptorArea(actionDescriptor);
                        var actionDescController = GetActionDescriptorController(actionDescriptor);
                        var actionDescAction     = GetActionDescriptorAction(actionDescriptor);

                        var routeMatchConfig = new MatchConfig(routeArea, routeController, routeAction)
                        {
                            IsAreaParameter       = isAreaParameter,
                            IsControllerParameter = isControllerParameter,
                            IsActionParameter     = isActionParameter
                        };

                        var actionMatchConfig = new MatchConfig(actionDescArea, actionDescController, actionDescAction);

                        if (MatchConfig.Match(routeMatchConfig, actionMatchConfig))
                        {
                            var paramIndex           = 0;
                            var actionParametersUsed = new List <string>();
                            foreach (var segment in route.PathSegments)
                            {
                                var firstPart     = segment.Parts.First();
                                var firstPartName = GetRoutePatternPartPropertyValue(firstPart, out bool firstPartIsOptional);

                                var hasConstraint = !firstPart.IsLiteral && route.ParameterPolicies != null &&
                                                    route.ParameterPolicies.Any(c => c.Key.Equals(firstPartName));

                                RoutePatternParameterPolicyReference policyReference = null;
                                bool passConstraint = false;
                                if (hasConstraint)
                                {
                                    policyReference = route.ParameterPolicies
                                                      .FirstOrDefault(policy => policy.Key.Equals(firstPartName))
                                                      .Value.FirstOrDefault();
                                }

                                if (firstPart.IsLiteral)
                                {
                                    template += $"{firstPartName}/";
                                }
                                else if (firstPartName.Equals("area"))
                                {
                                    if (string.IsNullOrEmpty(actionDescArea))
                                    {
                                        template = null;
                                        break;
                                    }

                                    if (hasConstraint)
                                    {
                                        passConstraint =
                                            PassPolicyReference(actionMatchConfig.Area, policyReference);

                                        if (!passConstraint)
                                        {
                                            template = null;
                                            break;
                                        }
                                    }

                                    if (!string.IsNullOrEmpty(actionMatchConfig.Area) && route.Defaults != null &&
                                        route.Defaults.TryGetValue("area", out var defaultArea) &&
                                        !string.IsNullOrEmpty(defaultArea?.ToString()))
                                    {
                                        isDefaultArea = actionMatchConfig.Area
                                                        .Equals(defaultArea.ToString(),
                                                                StringComparison.InvariantCultureIgnoreCase);
                                        if (isDefaultArea)
                                        {
                                            templateDefaults.Add("area", actionMatchConfig.Area);
                                        }
                                    }

                                    template += $"{actionMatchConfig.Area}/";
                                }
                                else if (firstPartName.Equals("controller"))
                                {
                                    if (hasConstraint && !IsCustomPolicyReference(policyReference))
                                    {
                                        passConstraint =
                                            PassPolicyReference(actionMatchConfig.Controller, policyReference);

                                        if (!passConstraint)
                                        {
                                            template = null;
                                            break;
                                        }
                                    }

                                    if (route.Defaults != null &&
                                        route.Defaults.TryGetValue("controller", out var defaultController) &&
                                        !string.IsNullOrEmpty(defaultController?.ToString()))
                                    {
                                        var configController = WithNoSuffix(actionMatchConfig.Controller, "Controller")
                                                               .ToLower();
                                        isDefaultController = configController.Equals(defaultController.ToString(),
                                                                                      StringComparison.InvariantCultureIgnoreCase);

                                        if (isDefaultController)
                                        {
                                            templateDefaults.Add("controller",
                                                                 $"{WithNoSuffix(actionMatchConfig.Controller, "Controller")}");
                                        }
                                    }

                                    template += $"{WithNoSuffix(actionMatchConfig.Controller, "Controller")}/";
                                }
                                else if (firstPartName.Equals("action"))
                                {
                                    if (hasConstraint)
                                    {
                                        passConstraint =
                                            PassPolicyReference(actionMatchConfig.Action, policyReference);

                                        if (!passConstraint)
                                        {
                                            template = null;
                                            break;
                                        }
                                    }

                                    if (route.Defaults != null &&
                                        route.Defaults.TryGetValue("action", out var defaultAction) &&
                                        !string.IsNullOrEmpty(defaultAction?.ToString()))
                                    {
                                        isDefaultAction = actionMatchConfig.Action
                                                          .Equals(defaultAction.ToString(),
                                                                  StringComparison.InvariantCultureIgnoreCase);
                                        if (isDefaultAction)
                                        {
                                            templateDefaults.Add("action", actionMatchConfig.Action);
                                        }
                                    }

                                    template += $"{actionMatchConfig.Action}/";
                                }

                                else if (firstPart.IsParameter)
                                {
                                    var hasActionDescParameter =
                                        HasActionDescriptorParameter(actionDescriptor, firstPartName,
                                                                     out var paramBindingInfo);

                                    if (hasActionDescParameter && hasConstraint)
                                    {
                                        var parameterInfo = actionDescriptor.Parameters.First(param =>
                                                                                              param.Name.Equals(firstPartName,
                                                                                                                StringComparison.InvariantCultureIgnoreCase));

                                        passConstraint =
                                            IsValidRoutePolicy(parameterInfo, policyReference);

                                        if (!passConstraint && parameterInfo.BindingInfo?.BindingSource.Id != "Query")
                                        {
                                            template = null;
                                            break;
                                        }

                                        if (parameterInfo?.BindingInfo?.BindingSource.Id == "Path")
                                        {
                                            templateDefaults.Clear();
                                        }
                                    }

                                    if (hasActionDescParameter && paramBindingInfo != null)
                                    {
                                        actionParametersUsed.Add(firstPartName);
                                        template += $"{{{firstPartName}{(firstPartIsOptional ? "?" : string.Empty)}}}/";
                                    }
                                    else if (!firstPartIsOptional)
                                    {
                                        var param = route.Parameters.FirstOrDefault(param =>
                                                                                    param.Name.Equals(firstPartName));
                                        if (hasConstraint && IsCustomPolicyReference(policyReference) ||
                                            route.Parameters.ToList().IndexOf(param) != route.Parameters.Count - 1)
                                        {
                                            template += $"{{{firstPartName}}}/";
                                        }
                                        else
                                        {
                                            template = null;
                                            break;
                                        }
                                    }
                                    else if (actionDescriptor.Parameters.Count > 0)
                                    {
                                        var httpMethod = actionDescriptor.ActionConstraints
                                                         .FirstOrDefault(c => c.GetType() == typeof(HttpMethodActionConstraint));

                                        if (httpMethod != null &&
                                            ((HttpMethodActionConstraint)httpMethod).HttpMethods.Count() == 1 &&
                                            ((HttpMethodActionConstraint)httpMethod).HttpMethods.First().Equals("GET"))
                                        {
                                            var unusedParameters = actionDescriptor.Parameters.Where(param =>
                                                                                                     !actionParametersUsed.Contains(param.Name));

                                            if (!string.IsNullOrEmpty(template) &&
                                                unusedParameters.All(param => param.BindingInfo == null))
                                            {
                                                break;
                                            }

                                            template = null;
                                            break;
                                        }
                                    }

                                    paramIndex++;
                                }
                            }
                        }

                        // exit on first route match
                        if (!string.IsNullOrEmpty(template))
                        {
                            break;
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(template))
            {
                template = template.TrimEnd('/');
            }

            if (!string.IsNullOrEmpty(template) && options.SkipDefaults && templateDefaults.Any())
            {
                template = SkipDefaultsFromTemplate(templateDefaults, template);
            }

            return(template);
        }