예제 #1
0
        private static IDictionary <string, IRouteConstraint> GetConstraints(
            IInlineConstraintResolver inlineConstraintResolver,
            RouteTemplate parsedTemplate,
            IDictionary <string, object> constraints)
        {
            var constraintBuilder = new RouteConstraintBuilder(inlineConstraintResolver, parsedTemplate.TemplateText);

            if (constraints != null)
            {
                foreach (var kvp in constraints)
                {
                    constraintBuilder.AddConstraint(kvp.Key, kvp.Value);
                }
            }

            foreach (var parameter in parsedTemplate.Parameters)
            {
                if (parameter.IsOptional)
                {
                    constraintBuilder.SetOptional(parameter.Name);
                }

                foreach (var inlineConstraint in parameter.InlineConstraints)
                {
                    constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint);
                }
            }

            return(constraintBuilder.Build());
        }
예제 #2
0
        /// <summary>
        /// Adds a new inbound route to the <see cref="TreeRouter"/>.
        /// </summary>
        /// <param name="handler">The <see cref="IRouter"/> for handling the route.</param>
        /// <param name="routeTemplate">The <see cref="RouteTemplate"/> of the route.</param>
        /// <param name="routeName">The route name.</param>
        /// <param name="order">The route order.</param>
        /// <returns>The <see cref="InboundRouteEntry"/>.</returns>
        public InboundRouteEntry MapInbound(
            IRouter handler,
            RouteTemplate routeTemplate,
            string routeName,
            int order)
        {
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            if (routeTemplate == null)
            {
                throw new ArgumentNullException(nameof(routeTemplate));
            }

            var entry = new InboundRouteEntry()
            {
                Handler       = handler,
                Order         = order,
                Precedence    = RoutePrecedence.ComputeInbound(routeTemplate),
                RouteName     = routeName,
                RouteTemplate = routeTemplate,
            };

            var constraintBuilder = new RouteConstraintBuilder(_constraintResolver, routeTemplate.TemplateText);

            foreach (var parameter in routeTemplate.Parameters)
            {
                if (parameter.InlineConstraints != null)
                {
                    if (parameter.IsOptional)
                    {
                        constraintBuilder.SetOptional(parameter.Name);
                    }

                    foreach (var constraint in parameter.InlineConstraints)
                    {
                        constraintBuilder.AddResolvedConstraint(parameter.Name, constraint.Constraint);
                    }
                }
            }

            entry.Constraints = constraintBuilder.Build();

            entry.Defaults = new RouteValueDictionary();
            foreach (var parameter in entry.RouteTemplate.Parameters)
            {
                if (parameter.DefaultValue != null)
                {
                    entry.Defaults.Add(parameter.Name, parameter.DefaultValue);
                }
            }

            InboundEntries.Add(entry);
            return(entry);
        }
예제 #3
0
        private InboundRouteEntry MapInbound(RouteTemplate template, Endpoint[] endpoints, int order)
        {
            if (template == null)
            {
                throw new ArgumentNullException(nameof(template));
            }

            var entry = new InboundRouteEntry()
            {
                Precedence    = RoutePrecedence.ComputeInbound(template),
                RouteTemplate = template,
                Order         = order,
                Tag           = endpoints,
            };

            var constraintBuilder = new RouteConstraintBuilder(_constraintFactory, template.TemplateText);

            foreach (var parameter in template.Parameters)
            {
                if (parameter.InlineConstraints != null)
                {
                    if (parameter.IsOptional)
                    {
                        constraintBuilder.SetOptional(parameter.Name);
                    }

                    foreach (var constraint in parameter.InlineConstraints)
                    {
                        constraintBuilder.AddResolvedConstraint(parameter.Name, constraint.Constraint);
                    }
                }
            }

            entry.Constraints = constraintBuilder.Build();

            entry.Defaults = new RouteValueDictionary();
            foreach (var parameter in entry.RouteTemplate.Parameters)
            {
                if (parameter.DefaultValue != null)
                {
                    entry.Defaults.Add(parameter.Name, parameter.DefaultValue);
                }
            }
            return(entry);
        }
예제 #4
0
        /// <summary>
        /// Processes the constraints for the specified template.
        /// </summary>
        /// <param name="rawTemplate">Raw template string</param>
        /// <param name="parsedTemplate">Parsed template</param>
        /// <returns>The constraints for this route</returns>
        private IDictionary <string, object> GetConstraints(string rawTemplate, RouteTemplate parsedTemplate)
        {
            var constraintBuilder = new RouteConstraintBuilder(_constraintResolver, rawTemplate);

            foreach (var parameter in parsedTemplate.Parameters)
            {
                if (parameter.InlineConstraints != null)
                {
                    if (parameter.IsOptional)
                    {
                        constraintBuilder.SetOptional(parameter.Name);
                    }

                    foreach (var inlineConstraint in parameter.InlineConstraints)
                    {
                        constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint);
                    }
                }
            }

            var constraints = constraintBuilder.Build();

            return(_constraintsProcessor.ProcessConstraints(constraints));
        }
예제 #5
0
        private static RouteInfo GetRouteInfo(
            IInlineConstraintResolver constraintResolver,
            Dictionary <string, RouteTemplate> templateCache,
            ActionDescriptor action)
        {
            var constraint = action.RouteConstraints
                             .FirstOrDefault(c => c.RouteKey == TreeRouter.RouteGroupKey);

            if (constraint == null ||
                constraint.KeyHandling != RouteKeyHandling.RequireKey ||
                constraint.RouteValue == null)
            {
                // This can happen if an ActionDescriptor has a route template, but doesn't have one of our
                // special route group constraints. This is a good indication that the user is using a 3rd party
                // routing system, or has customized their ADs in a way that we can no longer understand them.
                //
                // We just treat this case as an 'opt-out' of our attribute routing system.
                return(null);
            }

            var routeInfo = new RouteInfo()
            {
                ActionDescriptor = action,
                RouteGroup       = constraint.RouteValue,
                RouteTemplate    = action.AttributeRouteInfo.Template,
            };

            try
            {
                RouteTemplate parsedTemplate;
                if (!templateCache.TryGetValue(action.AttributeRouteInfo.Template, out parsedTemplate))
                {
                    // Parsing with throw if the template is invalid.
                    parsedTemplate = TemplateParser.Parse(action.AttributeRouteInfo.Template);
                    templateCache.Add(action.AttributeRouteInfo.Template, parsedTemplate);
                }

                routeInfo.ParsedTemplate = parsedTemplate;
            }
            catch (Exception ex)
            {
                routeInfo.ErrorMessage = ex.Message;
                return(routeInfo);
            }

            foreach (var kvp in action.RouteValueDefaults)
            {
                foreach (var parameter in routeInfo.ParsedTemplate.Parameters)
                {
                    if (string.Equals(kvp.Key, parameter.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        routeInfo.ErrorMessage = Resources.FormatAttributeRoute_CannotContainParameter(
                            routeInfo.RouteTemplate,
                            kvp.Key,
                            kvp.Value);

                        return(routeInfo);
                    }
                }
            }

            routeInfo.Order = action.AttributeRouteInfo.Order;

            routeInfo.MatchPrecedence      = RoutePrecedence.ComputeMatched(routeInfo.ParsedTemplate);
            routeInfo.GenerationPrecedence = RoutePrecedence.ComputeGenerated(routeInfo.ParsedTemplate);

            routeInfo.Name = action.AttributeRouteInfo.Name;

            var constraintBuilder = new RouteConstraintBuilder(constraintResolver, routeInfo.RouteTemplate);

            foreach (var parameter in routeInfo.ParsedTemplate.Parameters)
            {
                if (parameter.InlineConstraints != null)
                {
                    if (parameter.IsOptional)
                    {
                        constraintBuilder.SetOptional(parameter.Name);
                    }

                    foreach (var inlineConstraint in parameter.InlineConstraints)
                    {
                        constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint);
                    }
                }
            }

            routeInfo.Constraints = constraintBuilder.Build();

            routeInfo.Defaults = new RouteValueDictionary();
            foreach (var parameter in routeInfo.ParsedTemplate.Parameters)
            {
                if (parameter.DefaultValue != null)
                {
                    routeInfo.Defaults.Add(parameter.Name, parameter.DefaultValue);
                }
            }

            return(routeInfo);
        }
예제 #6
0
        private static IReadOnlyDictionary<string, IRouteConstraint> GetConstraints(
            IInlineConstraintResolver inlineConstraintResolver,
            string template,
            RouteTemplate parsedTemplate,
            IDictionary<string, object> constraints)
        {
            var constraintBuilder = new RouteConstraintBuilder(inlineConstraintResolver, template);

            if (constraints != null)
            {
                foreach (var kvp in constraints)
                {
                    constraintBuilder.AddConstraint(kvp.Key, kvp.Value);
                }
            }

            foreach (var parameter in parsedTemplate.Parameters)
            {
                if (parameter.IsOptional)
                {
                    constraintBuilder.SetOptional(parameter.Name);
                }

                foreach (var inlineConstraint in parameter.InlineConstraints)
                {
                    constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint);
                }
            }

            return constraintBuilder.Build();
        }
예제 #7
0
        private static IDictionary<string, IRouteConstraint> GetRouteConstriants(
            IInlineConstraintResolver inlineConstraintResolver,
            string template,
            RouteTemplate parsedRouteTemplate)
        {
            var constraintBuilder = new RouteConstraintBuilder(inlineConstraintResolver, template);
            foreach (var parameter in parsedRouteTemplate.Parameters)
            {
                if (parameter.InlineConstraints != null)
                {
                    if (parameter.IsOptional)
                    {
                        constraintBuilder.SetOptional(parameter.Name);
                    }

                    foreach (var constraint in parameter.InlineConstraints)
                    {
                        constraintBuilder.AddResolvedConstraint(parameter.Name, constraint.Constraint);
                    }
                }
            }

            return constraintBuilder.Build();
        }
예제 #8
0
        private static TreeRouteLinkGenerationEntry CreateGenerationEntry(
            string template,
            object requiredValues,
            int order = 0,
            string name = null)
        {
            var constraintResolver = CreateConstraintResolver();

            var entry = new TreeRouteLinkGenerationEntry();
            entry.Template = TemplateParser.Parse(template);

            var defaults = new RouteValueDictionary();
            foreach (var parameter in entry.Template.Parameters)
            {
                if (parameter.DefaultValue != null)
                {
                    defaults.Add(parameter.Name, parameter.DefaultValue);
                }
            }

            var constraintBuilder = new RouteConstraintBuilder(CreateConstraintResolver(), template);
            foreach (var parameter in entry.Template.Parameters)
            {
                if (parameter.InlineConstraints != null)
                {
                    if (parameter.IsOptional)
                    {
                        constraintBuilder.SetOptional(parameter.Name);
                    }

                    foreach (var constraint in parameter.InlineConstraints)
                    {
                        constraintBuilder.AddResolvedConstraint(parameter.Name, constraint.Constraint);
                    }
                }
            }

            var constraints = constraintBuilder.Build();

            entry.Constraints = constraints;
            entry.Defaults = defaults;
            entry.Binder = new TemplateBinder(Encoder, Pool, entry.Template, defaults);
            entry.Order = order;
            entry.GenerationPrecedence = RoutePrecedence.ComputeGenerated(entry.Template);
            entry.RequiredLinkValues = new RouteValueDictionary(requiredValues);
            entry.RouteGroup = CreateRouteGroup(order, template);
            entry.Name = name;
            return entry;
        }