/// <summary>
    /// Creates a new instance of <see cref="RouteTokenTransformerConvention"/> with the specified <see cref="IOutboundParameterTransformer"/>.
    /// </summary>
    /// <param name="parameterTransformer">The <see cref="IOutboundParameterTransformer"/> to use with attribute routing token replacement.</param>
    public RouteTokenTransformerConvention(IOutboundParameterTransformer parameterTransformer)
    {
        if (parameterTransformer == null)
        {
            throw new ArgumentNullException(nameof(parameterTransformer));
        }

        _parameterTransformer = parameterTransformer;
    }
        public ControllerRouteTokenTransformerConvention(Type controllerType, IOutboundParameterTransformer parameterTransformer)
        {
            if (parameterTransformer == null)
            {
                throw new ArgumentNullException(nameof(parameterTransformer));
            }

            _controllerType       = controllerType;
            _parameterTransformer = parameterTransformer;
        }
Пример #3
0
 public CustomPageRouteTransformerConvention(IOutboundParameterTransformer parameterTransformer) : base(parameterTransformer)
 {
 }
Пример #4
0
        public static string ReplaceTokens(string template, IDictionary <string, string> values, IOutboundParameterTransformer routeTokenTransformer)
        {
            var builder = new StringBuilder();
            var state   = TemplateParserState.Plaintext;

            int?tokenStart = null;

            // We'll run the loop one extra time with 'null' to detect the end of the string.
            for (var i = 0; i <= template.Length; i++)
            {
                var c = i < template.Length ? (char?)template[i] : null;
                switch (state)
                {
                case TemplateParserState.Plaintext:
                    if (c == '[')
                    {
                        state = TemplateParserState.SeenLeft;
                        break;
                    }
                    else if (c == ']')
                    {
                        state = TemplateParserState.SeenRight;
                        break;
                    }
                    else if (c == null)
                    {
                        // We're at the end of the string, nothing left to do.
                        break;
                    }
                    else
                    {
                        builder.Append(c);
                        break;
                    }

                case TemplateParserState.SeenLeft:
                    if (c == '[')
                    {
                        // This is an escaped left-bracket
                        builder.Append(c);
                        state = TemplateParserState.Plaintext;
                        break;
                    }
                    else if (c == ']')
                    {
                        // This is zero-width parameter - not allowed.
                        var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
                            template,
                            Resources.AttributeRoute_TokenReplacement_EmptyTokenNotAllowed);
                        throw new InvalidOperationException(message);
                    }
                    else if (c == null)
                    {
                        // This is a left-bracket at the end of the string.
                        var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
                            template,
                            Resources.AttributeRoute_TokenReplacement_UnclosedToken);
                        throw new InvalidOperationException(message);
                    }
                    else
                    {
                        tokenStart = i;
                        state      = TemplateParserState.InsideToken;
                        break;
                    }

                case TemplateParserState.SeenRight:
                    if (c == ']')
                    {
                        // This is an escaped right-bracket
                        builder.Append(c);
                        state = TemplateParserState.Plaintext;
                        break;
                    }
                    else if (c == null)
                    {
                        // This is an imbalanced right-bracket at the end of the string.
                        var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
                            template,
                            Resources.AttributeRoute_TokenReplacement_ImbalancedSquareBrackets);
                        throw new InvalidOperationException(message);
                    }
                    else
                    {
                        // This is an imbalanced right-bracket.
                        var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
                            template,
                            Resources.AttributeRoute_TokenReplacement_ImbalancedSquareBrackets);
                        throw new InvalidOperationException(message);
                    }

                case TemplateParserState.InsideToken:
                    if (c == '[')
                    {
                        state = TemplateParserState.InsideToken | TemplateParserState.SeenLeft;
                        break;
                    }
                    else if (c == ']')
                    {
                        state = TemplateParserState.InsideToken | TemplateParserState.SeenRight;
                        break;
                    }
                    else if (c == null)
                    {
                        // This is an unclosed replacement token
                        var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
                            template,
                            Resources.AttributeRoute_TokenReplacement_UnclosedToken);
                        throw new InvalidOperationException(message);
                    }
                    else
                    {
                        // This is a just part of the parameter
                        break;
                    }

                case TemplateParserState.InsideToken | TemplateParserState.SeenLeft:
                    if (c == '[')
                    {
                        // This is an escaped left-bracket
                        state = TemplateParserState.InsideToken;
                        break;
                    }
                    else
                    {
                        // Unescaped left-bracket is not allowed inside a token.
                        var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
                            template,
                            Resources.AttributeRoute_TokenReplacement_UnescapedBraceInToken);
                        throw new InvalidOperationException(message);
                    }

                case TemplateParserState.InsideToken | TemplateParserState.SeenRight:
                    if (c == ']')
                    {
                        // This is an escaped right-bracket
                        state = TemplateParserState.InsideToken;
                        break;
                    }
                    else
                    {
                        // This is the end of a replacement token.
                        var token = template
                                    .Substring(tokenStart.Value, i - tokenStart.Value - 1)
                                    .Replace("[[", "[")
                                    .Replace("]]", "]");

                        if (!values.TryGetValue(token, out var value))
                        {
                            // Value not found
                            var message = Resources.FormatAttributeRoute_TokenReplacement_ReplacementValueNotFound(
                                template,
                                token,
                                string.Join(", ", values.Keys.OrderBy(k => k, StringComparer.OrdinalIgnoreCase)));
                            throw new InvalidOperationException(message);
                        }

                        if (routeTokenTransformer != null)
                        {
                            value = routeTokenTransformer.TransformOutbound(value);
                        }

                        builder.Append(value);

                        if (c == '[')
                        {
                            state = TemplateParserState.SeenLeft;
                        }
                        else if (c == ']')
                        {
                            state = TemplateParserState.SeenRight;
                        }
                        else if (c == null)
                        {
                            state = TemplateParserState.Plaintext;
                        }
                        else
                        {
                            builder.Append(c);
                            state = TemplateParserState.Plaintext;
                        }

                        tokenStart = null;
                        break;
                    }
                }
            }

            return(builder.ToString());
        }