Beispiel #1
0
        public void ToRoutePatternPathSegment()
        {
            // Arrange
            var literalPartA    = RoutePatternFactory.LiteralPart("A");
            var paramPartB      = RoutePatternFactory.ParameterPart("B");
            var paramPartC      = RoutePatternFactory.ParameterPart("C");
            var paramPartD      = RoutePatternFactory.ParameterPart("D");
            var separatorPartE  = RoutePatternFactory.SeparatorPart("E");
            var templateSegment = new TemplateSegment(RoutePatternFactory.Segment(paramPartC, literalPartA, separatorPartE, paramPartB));

            // Act
            var routePatternPathSegment = templateSegment.ToRoutePatternPathSegment();

            templateSegment.Parts[1] = new TemplatePart(RoutePatternFactory.ParameterPart("D"));
            templateSegment.Parts.RemoveAt(0);

            // Assert
            Assert.Equal(4, routePatternPathSegment.Parts.Count);
            Assert.IsType <RoutePatternParameterPart>(routePatternPathSegment.Parts[0]);
            Assert.Equal(paramPartC.Name, ((RoutePatternParameterPart)routePatternPathSegment.Parts[0]).Name);
            Assert.IsType <RoutePatternLiteralPart>(routePatternPathSegment.Parts[1]);
            Assert.Equal(literalPartA.Content, ((RoutePatternLiteralPart)routePatternPathSegment.Parts[1]).Content);
            Assert.IsType <RoutePatternSeparatorPart>(routePatternPathSegment.Parts[2]);
            Assert.Equal(separatorPartE.Content, ((RoutePatternSeparatorPart)routePatternPathSegment.Parts[2]).Content);
            Assert.IsType <RoutePatternParameterPart>(routePatternPathSegment.Parts[3]);
            Assert.Equal(paramPartB.Name, ((RoutePatternParameterPart)routePatternPathSegment.Parts[3]).Name);
        }
Beispiel #2
0
        public RoutePatternPart ToRoutePatternPart()
        {
            if (IsLiteral && IsOptionalSeperator)
            {
                return(RoutePatternFactory.SeparatorPart(Text));
            }
            else if (IsLiteral)
            {
                return(RoutePatternFactory.LiteralPart(Text));
            }
            else
            {
                var kind = IsCatchAll ?
                           RoutePatternParameterKind.CatchAll :
                           IsOptional ?
                           RoutePatternParameterKind.Optional :
                           RoutePatternParameterKind.Standard;

                var constraints = InlineConstraints.Select(c => new RoutePatternParameterPolicyReference(c.Constraint));
                return(RoutePatternFactory.ParameterPart(Name, DefaultValue, kind, constraints));
            }
        }
    private static bool IsSegmentValid(Context context, List <RoutePatternPart> parts)
    {
        // If a segment has multiple parts, then it can't contain a catch all.
        for (var i = 0; i < parts.Count; i++)
        {
            var part = parts[i];
            if (part is RoutePatternParameterPart parameter && parameter.IsCatchAll && parts.Count > 1)
            {
                context.Error = Resources.TemplateRoute_CannotHaveCatchAllInMultiSegment;
                return(false);
            }
        }

        // if a segment has multiple parts, then only the last one parameter can be optional
        // if it is following a optional separator.
        for (var i = 0; i < parts.Count; i++)
        {
            var part = parts[i];

            if (part is RoutePatternParameterPart parameter && parameter.IsOptional && parts.Count > 1)
            {
                // This optional parameter is the last part in the segment
                if (i == parts.Count - 1)
                {
                    var previousPart = parts[i - 1];

                    if (!previousPart.IsLiteral && !previousPart.IsSeparator)
                    {
                        // The optional parameter is preceded by something that is not a literal or separator
                        // Example of error message:
                        // "In the segment '{RouteValue}{param?}', the optional parameter 'param' is preceded
                        // by an invalid segment '{RouteValue}'. Only a period (.) can precede an optional parameter.
                        context.Error = Resources.FormatTemplateRoute_OptionalParameterCanbBePrecededByPeriod(
                            RoutePatternPathSegment.DebuggerToString(parts),
                            parameter.Name,
                            parts[i - 1].DebuggerToString());

                        return(false);
                    }
                    else if (previousPart is RoutePatternLiteralPart literal && literal.Content != PeriodString)
                    {
                        // The optional parameter is preceded by a literal other than period.
                        // Example of error message:
                        // "In the segment '{RouteValue}-{param?}', the optional parameter 'param' is preceded
                        // by an invalid segment '-'. Only a period (.) can precede an optional parameter.
                        context.Error = Resources.FormatTemplateRoute_OptionalParameterCanbBePrecededByPeriod(
                            RoutePatternPathSegment.DebuggerToString(parts),
                            parameter.Name,
                            parts[i - 1].DebuggerToString());

                        return(false);
                    }

                    parts[i - 1] = RoutePatternFactory.SeparatorPart(((RoutePatternLiteralPart)previousPart).Content);
                }
                else
                {
                    // This optional parameter is not the last one in the segment
                    // Example:
                    // An optional parameter must be at the end of the segment. In the segment '{RouteValue?})',
                    // optional parameter 'RouteValue' is followed by ')'
                    context.Error = Resources.FormatTemplateRoute_OptionalParameterHasTobeTheLast(
                        RoutePatternPathSegment.DebuggerToString(parts),
                        parameter.Name,
                        parts[i + 1].DebuggerToString());

                    return(false);
                }
            }
        }

        // A segment cannot contain two consecutive parameters
        var isLastSegmentParameter = false;

        for (var i = 0; i < parts.Count; i++)
        {
            var part = parts[i];
            if (part.IsParameter && isLastSegmentParameter)
            {
                context.Error = Resources.TemplateRoute_CannotHaveConsecutiveParameters;
                return(false);
            }

            isLastSegmentParameter = part.IsParameter;
        }

        return(true);
    }