コード例 #1
0
ファイル: RouteTemplateWriter.cs プロジェクト: yelau/Mvc
        private static string ToString(TemplatePart templatePart)
        {
            if (templatePart.IsParameter)
            {
                var partText = "{";
                if (templatePart.IsCatchAll)
                {
                    partText += "*";
                }
                partText += templatePart.Name;
                foreach (var item in templatePart.InlineConstraints)
                {
                    partText += ":";
                    partText += item.Constraint;
                }
                if (templatePart.DefaultValue != null)
                {
                    partText += "=";
                    partText += templatePart.DefaultValue;
                }
                if (templatePart.IsOptional)
                {
                    partText += "?";
                }
                partText += "}";

                return(partText);
            }
            else
            {
                return(templatePart.Text);
            }
        }
コード例 #2
0
        public override string ParseTemplate(TemplatePart template, ParseTemplateContext context)
        {
            int    versionrecordid = template.Record.ContentItemRecord.Versions.Where(x => x.Published).FirstOrDefault().Id;
            string key             = _shellSettings.Name + versionrecordid.ToString();
            // var tr = new RazorTemplateManager();
            var layout          = template.Layout;
            var templateContent = template.Text;
            //var viewBag = context.ViewBag;
            string layoutString = null;

            if (layout != null)
            {
                key         += "_" + template.Layout.Record.ContentItemRecord.Versions.Where(x => x.Published).FirstOrDefault().Id;
                layoutString = layout.Text;
                //  _razorTemplateManager.AddLayout("Layout" + key, layout.Text);
                templateContent = "@{ Layout = \"Layout" + key + "\"; }\r\n" + templateContent;
            }

            try {
                var tmpl = _razorTemplateManager.RunString(key, templateContent, context.Model, (Dictionary <string, object>)context.ViewBag, layoutString);
                return(tmpl);
            }
            catch (Exception ex) {
                Logger.Log(LogLevel.Error, ex, "Failed to parse the {0} Razor template with layout {1}", template.Title, layout != null ? layout.Title : "[none]");
                return(BuildErrorContent(ex, template, layout));
            }
        }
        public void Parse_ComplexSegment_OptionalParameterFollowingPeriod_PeriodAfterSlash()
        {
            // Arrange
            var template = "{p2}/.{p3?}";

            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p2",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[1].Parts.Add(TemplatePart.CreateLiteral("."));
            expected.Segments[1].Parts.Add(TemplatePart.CreateParameter("p3",
                                                                        false,
                                                                        true,
                                                                        null,
                                                                        null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);
            expected.Parameters.Add(expected.Segments[1].Parts[1]);

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
        public void Parse_ComplexSegment_PLP()
        {
            // Arrange
            var template = "{p1}-cool-{p2}";

            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p1",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);
            expected.Segments[0].Parts.Add(TemplatePart.CreateLiteral("cool-"));
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p2",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[0].Parts[2]);

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
            private bool Equals(TemplatePart x, TemplatePart y)
            {
                if (x.IsLiteral != y.IsLiteral ||
                    x.IsParameter != y.IsParameter ||
                    x.IsCatchAll != y.IsCatchAll ||
                    x.IsOptional != y.IsOptional ||
                    !String.Equals(x.Name, y.Name, StringComparison.Ordinal) ||
                    !String.Equals(x.Name, y.Name, StringComparison.Ordinal) ||
                    (x.InlineConstraints == null && y.InlineConstraints != null) ||
                    (x.InlineConstraints != null && y.InlineConstraints == null))
                {
                    return(false);
                }

                if (x.InlineConstraints == null && y.InlineConstraints == null)
                {
                    return(true);
                }

                if (x.InlineConstraints.Count() != y.InlineConstraints.Count())
                {
                    return(false);
                }

                foreach (var xconstraint in x.InlineConstraints)
                {
                    if (!y.InlineConstraints.Any <InlineConstraint>(
                            c => string.Equals(c.Constraint, xconstraint.Constraint)))
                    {
                        return(false);
                    }
                }

                return(true);
            }
コード例 #6
0
    private static string GenerateParameterValue(TemplatePart part)
    {
        var text   = Guid.NewGuid().ToString();
        var length = Math.Min(text.Length, Math.Max(5, part.Name.Length));

        return(text.Substring(0, length));
    }
コード例 #7
0
        public void ParameterPart_ParameterNameAndDefaultAndParameterKindAndEnumerableOfParameterPolicies_ShouldMakeCopyOfParameterPolicies()
        {
            // Arrange (going through hoops to get an enumerable of RoutePatternParameterPolicyReference)
            const string name         = "Id";
            var          defaults     = new { a = "13", };
            var          x            = new InlineConstraint("x");
            var          y            = new InlineConstraint("y");
            var          z            = new InlineConstraint("z");
            var          constraints  = new[] { x, y, z };
            var          templatePart = TemplatePart.CreateParameter("t", false, false, null, constraints);
            var          routePatternParameterPart = (RoutePatternParameterPart)templatePart.ToRoutePatternPart();
            var          policies = routePatternParameterPart.ParameterPolicies.ToList();

            // Act
            var parameterPart = RoutePatternFactory.ParameterPart(name, defaults, RoutePatternParameterKind.Standard, policies);

            policies[0] = null;
            policies.RemoveAt(1);

            // Assert
            Assert.NotNull(parameterPart.ParameterPolicies);
            Assert.Equal(3, parameterPart.ParameterPolicies.Count);
            Assert.NotNull(parameterPart.ParameterPolicies[0]);
            Assert.NotNull(parameterPart.ParameterPolicies[1]);
            Assert.NotNull(parameterPart.ParameterPolicies[2]);
        }
コード例 #8
0
        public static TemplatePart ParseRouteParameter([NotNull] string routeParameter)
        {
            var isCatchAll = routeParameter.StartsWith("*", StringComparison.Ordinal);
            var isOptional = routeParameter.EndsWith("?", StringComparison.Ordinal);

            routeParameter = isCatchAll ? routeParameter.Substring(1) : routeParameter;
            routeParameter = isOptional ? routeParameter.Substring(0, routeParameter.Length - 1) : routeParameter;

            var parameterMatch = _parameterRegex.Match(routeParameter);

            if (!parameterMatch.Success)
            {
                return(TemplatePart.CreateParameter(name: string.Empty,
                                                    isCatchAll: isCatchAll,
                                                    isOptional: isOptional,
                                                    defaultValue: null,
                                                    inlineConstraints: null));
            }

            var parameterName = parameterMatch.Groups["parameterName"].Value;

            // Add the default value if present
            var defaultValueGroup = parameterMatch.Groups["defaultValue"];
            var defaultValue      = GetDefaultValue(defaultValueGroup);

            // Register inline constraints if present
            var constraintGroup   = parameterMatch.Groups["constraint"];
            var inlineConstraints = GetInlineConstraints(constraintGroup);

            return(TemplatePart.CreateParameter(parameterName,
                                                isCatchAll,
                                                isOptional,
                                                defaultValue,
                                                inlineConstraints));
        }
コード例 #9
0
        public void Formats_template_parameters_correctly(string expected, string template, bool isCatchAll, bool isOptional)
        {
            var templatePart = TemplatePart.CreateParameter(template, isCatchAll, isOptional, defaultValue: null, inlineConstraints: null);

            var result = templatePart.ToTemplatePartString();

            result.Should().Be(expected);
        }
コード例 #10
0
        public void If_not_parameter_return_text()
        {
            var expected     = "test";
            var templatePart = TemplatePart.CreateLiteral(expected);

            var result = templatePart.ToTemplatePartString();

            result.Should().Be(expected);
        }
コード例 #11
0
 public static string ToPlaceholder(this TemplatePart part)
 {
     if (part.IsParameter)
     {
         return("{" + (part.IsCatchAll ? "*" : string.Empty) + part.Name + (part.IsOptional ? "?" : string.Empty) + "}");
     }
     else
     {
         return(part.Text);
     }
 }
コード例 #12
0
 private static ApiParameterDescription CreateParameterFromTemplate(TemplatePart templateParameter)
 {
     return(new ApiParameterDescription
     {
         Source = ApiParameterSource.Path,
         IsOptional = IsOptionalParameter(templateParameter),
         Name = templateParameter.Name,
         ParameterDescriptor = null,
         Constraint = templateParameter.InlineConstraint,
         DefaultValue = templateParameter.DefaultValue,
     });
 }
コード例 #13
0
 private ApiParameterDescription CreateParameterFromTemplate(TemplatePart templateParameter)
 {
     return(new ApiParameterDescription
     {
         Source = ApiParameterSource.Path,
         IsOptional = IsOptionalParameter(templateParameter),
         Name = templateParameter.Name,
         ParameterDescriptor = null,
         Constraints = GetConstraints(_constraintResolver, templateParameter.InlineConstraints),
         DefaultValue = templateParameter.DefaultValue,
     });
 }
コード例 #14
0
        public void Can_format_template_segements()
        {
            var expected = "{p}";
            var segments = new List <TemplateSegment> {
                new TemplateSegment()
            };

            segments[0].Parts.Add(TemplatePart.CreateParameter("p", false, false, defaultValue: null, inlineConstraints: null));

            var result = segments[0].ToTemplateSegmentString();

            result.Should().Be(expected);
        }
コード例 #15
0
        public void Configure(IApplicationBuilder app)
        {
            //We are building a url template from scratch, segment by segemtn, oldskool
            var segment = new TemplateSegment();

            segment.Parts.Add(TemplatePart.CreateLiteral("page"));

            var segment2 = new TemplateSegment();

            segment2.Parts.Add(
                TemplatePart.CreateParameter("title",
                                             isCatchAll: true,
                                             isOptional: true,
                                             defaultValue: null,
                                             inlineConstraints: new InlineConstraint[] {})
                );

            var segments = new TemplateSegment [] {
                segment,
                segment2
            };

            var template        = new RouteTemplate("page", segments.ToList());
            var templateMatcher = new TemplateMatcher(template, new RouteValueDictionary());

            app.Use(async(context, next) => {
                await context.Response.WriteAsync("We are using two segments, one with Literal Template Part ('page') and the other with Parameter Template Part ('title')");
                await context.Response.WriteAsync("\n\n");
                await next.Invoke();
            });
            app.Use(async(context, next) => {
                var path1     = "/page/what";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path1, routeData);
                await context.Response.WriteAsync($"{path1} is match? {isMatch1} => route data value for 'title' is {routeData["title"]} \n");
                await next.Invoke();
            });

            app.Use(async(context, next) => {
                var path1     = "/page/the/old/man/and/the/sea";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path1, routeData);
                await context.Response.WriteAsync($"{path1} is match? {isMatch1} => route data value for 'title' is {routeData["title"]} \n");
                await next.Invoke();
            });

            app.Run(async context =>
            {
                await context.Response.WriteAsync("");
            });
        }
コード例 #16
0
            private bool Equals(TemplatePart x, TemplatePart y)
            {
                if (x.IsLiteral != y.IsLiteral ||
                    x.IsParameter != y.IsParameter ||
                    x.IsCatchAll != y.IsCatchAll ||
                    x.IsOptional != y.IsOptional ||
                    !String.Equals(x.Name, y.Name, StringComparison.Ordinal) ||
                    !String.Equals(x.Name, y.Name, StringComparison.Ordinal))
                {
                    return(false);
                }


                return(true);
            }
コード例 #17
0
        public void Configure(IApplicationBuilder app)
        {
            //We are building a url template from scratch, segment by segemtn, oldskool
            var segment = new TemplateSegment();

            segment.Parts.Add(TemplatePart.CreateLiteral("page"));

            var segment2 = new TemplateSegment();

            segment2.Parts.Add(TemplatePart.CreateParameter("id",
                                                            isCatchAll: false,
                                                            isOptional: false,
                                                            defaultValue: null,
                                                            inlineConstraints: new InlineConstraint[] { new InlineConstraint("int") }));

            var segments = new TemplateSegment[] {
                segment,
                segment2
            };

            var template        = new RouteTemplate("page", segments.ToList());
            var templateMatcher = new TemplateMatcher(template, new RouteValueDictionary());

            app.Use(async(context, next) =>
            {
                await context.Response.WriteAsync("We are using one segment with two parts, one Literal Template Part ('page') and the other with Parameter Template Part ('id').");
                await context.Response.WriteAsync("It is the equivalent of /page/{id:int}");
                await context.Response.WriteAsync("\n\n");
                await next.Invoke();
            });

            app.Use(async(context, next) =>
            {
                var path1     = "/page/10";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path1, routeData);
                await context.Response.WriteAsync($"{path1} is match? {isMatch1} => route data value for 'id' is {routeData["id"]} \n");
                await next.Invoke();
            });

            app.Use(async(context, next) =>
            {
                var path      = "/page/a";
                var routeData = new RouteValueDictionary();//This dictionary will be populated by the parameter template part (in this case "title")
                var isMatch1  = templateMatcher.TryMatch(path, routeData);
                await context.Response.WriteAsync($"{path} is match? {isMatch1} - as you can see TemplateMatcher does not give a damn about InlineConstraint. It is by design. \n");
            });
        }
        public void Parse_SingleLiteral()
        {
            // Arrange
            var template = "cool";

            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateLiteral("cool"));

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
コード例 #19
0
        public static string ToTemplatePartString(this TemplatePart templatePart)
        {
            if (templatePart.IsParameter)
            {
                return(string.Join("", new []
                {
                    "{",
                    templatePart.IsCatchAll ? "*" : string.Empty,
                    templatePart.Name,
                    templatePart.IsOptional ? "?" : string.Empty,
                    "}"
                }).ToLower());
            }

            return(templatePart.Text.ToLower());
        }
コード例 #20
0
        public void Parse_OptionalParameter()
        {
            // Arrange
            var template = "{p?}";

            var expected = new RouteTemplate(new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p", false, true, defaultValue: null, inlineConstraint: null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);

            // Act
            var actual = TemplateParser.Parse(template, _inlineConstraintResolver);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
コード例 #21
0
        private ApiParameterDescription CreateParameterFromTemplateAndParameterDescriptor(
            TemplatePart templateParameter,
            ParameterDescriptor parameter)
        {
            var resourceParameter = new ApiParameterDescription
            {
                Source              = ApiParameterSource.Path,
                IsOptional          = parameter.IsOptional && IsOptionalParameter(templateParameter),
                Name                = parameter.Name,
                ParameterDescriptor = parameter,
                Constraints         = GetConstraints(_constraintResolver, templateParameter.InlineConstraints),
                DefaultValue        = templateParameter.DefaultValue,
                Type                = parameter.ParameterType,
            };

            return(resourceParameter);
        }
コード例 #22
0
        public IParserEngine SelectParser(TemplatePart template)
        {
            var           parserId = template.DefaultParserIdSelected;
            IParserEngine parser   = null;

            if (!string.IsNullOrWhiteSpace(parserId))
            {
                parser = GetParser(parserId);
            }

            if (parser == null)
            {
                parserId = _services.WorkContext.CurrentSite.As <SiteSettingsPart>().DefaultParserIdSelected;
                parser   = GetParser(parserId);
            }

            return(parser ?? _parsers.First());
        }
コード例 #23
0
        private ApiParameterRouteInfo CreateRouteInfo(TemplatePart routeParameter)
        {
            var constraints = new List <IRouteConstraint>();

            if (routeParameter.InlineConstraints != null)
            {
                foreach (var constraint in routeParameter.InlineConstraints)
                {
                    constraints.Add(_constraintResolver.ResolveConstraint(constraint.Constraint));
                }
            }

            return(new ApiParameterRouteInfo()
            {
                Constraints = constraints,
                DefaultValue = routeParameter.DefaultValue,
                IsOptional = routeParameter.IsOptional || routeParameter.DefaultValue != null,
            });
        }
コード例 #24
0
        private ApiParameterDescription GetParameter(
            ParameterDescriptor parameterDescriptor,
            TemplatePart templateParameter)
        {
            // This is a placeholder based on currently available functionality for parameters. See #886.
            ApiParameterDescription parameterDescription = null;

            if (templateParameter != null && parameterDescriptor == null)
            {
                // The parameter is part of the route template but not part of the ActionDescriptor.

                // For now if a parameter is part of the template we will asume its value comes from the path.
                // We will be more accurate when we implement #886.
                parameterDescription = CreateParameterFromTemplate(templateParameter);
            }
            else if (templateParameter != null && parameterDescriptor != null)
            {
                // The parameter is part of the route template and part of the ActionDescriptor.
                parameterDescription = CreateParameterFromTemplateAndParameterDescriptor(
                    templateParameter,
                    parameterDescriptor);
            }
            else if (templateParameter == null && parameterDescriptor != null)
            {
                // The parameter is part of the ActionDescriptor but is not part of the route template.
                parameterDescription = CreateParameterFromParameterDescriptor(parameterDescriptor);
            }
            else
            {
                // We will never call this method with templateParameter == null && parameterDescriptor == null
                Debug.Assert(parameterDescriptor != null);
            }

            if (parameterDescription.Type != null)
            {
                parameterDescription.ModelMetadata = _modelMetadataProvider.GetMetadataForType(
                    modelAccessor: null,
                    modelType: parameterDescription.Type);
            }

            return(parameterDescription);
        }
コード例 #25
0
        public void Parse_MultipleLiterals()
        {
            // Arrange
            var template = "cool/awesome/super";

            var expected = new RouteTemplate(new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateLiteral("cool"));
            expected.Segments.Add(new TemplateSegment());
            expected.Segments[1].Parts.Add(TemplatePart.CreateLiteral("awesome"));
            expected.Segments.Add(new TemplateSegment());
            expected.Segments[2].Parts.Add(TemplatePart.CreateLiteral("super"));

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
コード例 #26
0
        public override string ParseTemplate(TemplatePart template, ParseTemplateContext context)
        {
            var layout          = template.Layout;
            var templateContent = new StringBuilder(template.Text);

            //var viewBag = context.ViewBag;

            if (layout != null)
            {
                templateContent = new StringBuilder(layout.Text.Replace(LayoutBeacon, templateContent.ToString()));
            }

            //if (viewBag != null) {
            //    var variables = viewBag as IEnumerable<KeyValuePair<string, string>>;
            //    if (variables != null) {
            //        templateContent = variables.Aggregate(templateContent, (current, variable) => current.Replace(string.Format("[{0}]", variable.Key), variable.Value));
            //    }
            //}

            return(templateContent.ToString());
        }
コード例 #27
0
        public void Configure(IApplicationBuilder app)
        {
            var apiSegment = new TemplateSegment();

            apiSegment.Parts.Add(TemplatePart.CreateLiteral("api"));

            var serviceNameSegment = new TemplateSegment();

            serviceNameSegment.Parts.Add(
                TemplatePart.CreateParameter("serviceName",
                                             isCatchAll: false,
                                             isOptional: true,
                                             defaultValue: null,
                                             inlineConstraints: new InlineConstraint[] { })
                );

            var segments = new TemplateSegment[] {
                apiSegment,
                serviceNameSegment
            };

            var routeTemplate   = new RouteTemplate("default", segments.ToList());
            var templateMatcher = new TemplateMatcher(routeTemplate, new RouteValueDictionary());

            app.Use(async(context, next) =>
            {
                context.Response.Headers.Add("Content-type", "text/html");
                var requestPath = context.Request.Path;
                var routeData   = new RouteValueDictionary();
                var isMatch     = templateMatcher.TryMatch(requestPath, routeData);
                await context.Response.WriteAsync($"Request Path is <i>{requestPath}</i><br/>Match state is <b>{isMatch}</b><br/>Requested service name is {routeData["serviceName"]}");
                await next.Invoke();
            });

            app.Run(async context =>
            {
                await context.Response.WriteAsync("");
            });
        }
コード例 #28
0
        private static string BuildErrorContent(Exception ex, TemplatePart templatePart, TemplatePart layout)
        {
            var sb = new StringBuilder();
            var currentException = ex;

            sb.AppendLine("Error On Template");
            while (currentException != null)
            {
                sb.AppendLine(currentException.Message);
                currentException = currentException.InnerException;
            }

            sb.AppendFormat("\r\nTemplate ({0}):\r\n", templatePart.Title);
            sb.AppendLine(templatePart.Text);

            if (layout != null)
            {
                sb.AppendFormat("\r\nLayout ({0}):\r\n", layout.Title);
                sb.AppendLine(layout.Text);
            }
            return(sb.ToString());
        }
        public void Parse_MultipleParameters()
        {
            // Arrange
            var template = "{p1}/{p2}/{*p3}";

            var expected = new RouteTemplate(template, new List <TemplateSegment>());

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[0].Parts.Add(TemplatePart.CreateParameter("p1",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[0].Parts[0]);

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[1].Parts.Add(TemplatePart.CreateParameter("p2",
                                                                        false,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[1].Parts[0]);

            expected.Segments.Add(new TemplateSegment());
            expected.Segments[2].Parts.Add(TemplatePart.CreateParameter("p3",
                                                                        true,
                                                                        false,
                                                                        defaultValue: null,
                                                                        inlineConstraints: null));
            expected.Parameters.Add(expected.Segments[2].Parts[0]);

            // Act
            var actual = TemplateParser.Parse(template);

            // Assert
            Assert.Equal <RouteTemplate>(expected, actual, new TemplateEqualityComparer());
        }
コード例 #30
0
        private void GetParameters(
            ApiDescription apiDescription,
            IList <ParameterDescriptor> parameterDescriptors,
            IList <TemplatePart> templateParameters)
        {
            if (parameterDescriptors != null)
            {
                foreach (var parameter in parameterDescriptors)
                {
                    // Process together parameters that appear on the path template and on the
                    // action descriptor and do not come from the body.
                    TemplatePart templateParameter = null;
                    if (parameter.BinderMetadata as IFormatterBinderMetadata == null)
                    {
                        templateParameter = templateParameters
                                            .FirstOrDefault(p => p.Name.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase));

                        if (templateParameter != null)
                        {
                            templateParameters.Remove(templateParameter);
                        }
                    }

                    apiDescription.ParameterDescriptions.Add(GetParameter(parameter, templateParameter));
                }
            }

            if (templateParameters.Count > 0)
            {
                // Process parameters that only appear on the path template if any.
                foreach (var templateParameter in templateParameters)
                {
                    var parameterDescription = GetParameter(parameterDescriptor: null, templateParameter: templateParameter);
                    apiDescription.ParameterDescriptions.Add(parameterDescription);
                }
            }
        }