public TemplateBinder( UrlEncoder urlEncoder, ObjectPool<UriBuildingContext> pool, RouteTemplate template, RouteValueDictionary defaults) { if (urlEncoder == null) { throw new ArgumentNullException(nameof(urlEncoder)); } if (pool == null) { throw new ArgumentNullException(nameof(pool)); } if (template == null) { throw new ArgumentNullException(nameof(template)); } _urlEncoder = urlEncoder; _pool = pool; _template = template; _defaults = defaults; // Any default that doesn't have a corresponding parameter is a 'filter' and if a value // is provided for that 'filter' it must match the value in defaults. _filters = new RouteValueDictionary(_defaults); foreach (var parameter in _template.Parameters) { _filters.Remove(parameter.Name); } }
public TemplateRoute( IRouter target, string routeName, string routeTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, IInlineConstraintResolver inlineConstraintResolver) { if (target == null) { throw new ArgumentNullException(nameof(target)); } _target = target; _routeTemplate = routeTemplate ?? string.Empty; Name = routeName; _dataTokens = dataTokens == null ? RouteValueDictionary.Empty : new RouteValueDictionary(dataTokens); // Data we parse from the template will be used to fill in the rest of the constraints or // defaults. The parser will throw for invalid routes. _parsedTemplate = TemplateParser.Parse(RouteTemplate); _constraints = GetConstraints(inlineConstraintResolver, RouteTemplate, _parsedTemplate, constraints); _defaults = GetDefaults(_parsedTemplate, defaults); _matcher = new TemplateMatcher(_parsedTemplate, Defaults); _binder = new TemplateBinder(_parsedTemplate, Defaults); }
/// <summary> /// Parses the specified route template string, placing the available information in /// <see cref="info" />. /// </summary> /// <param name="template">Template to parse</param> /// <param name="info">RouteInfo to store parsed info</param> public void Parse(RouteTemplate template, RouteInfo info) { var builder = new StringBuilder(); foreach (var segment in template.Segments) { foreach (var part in segment.Parts) { if (part.IsLiteral) { builder.Append(part.Text); continue; } if (part.DefaultValue != null) { info.Defaults[part.Name] = part.DefaultValue; } if (part.IsOptional) { info.Optional.Add(part.Name); } builder.Append('{'); builder.Append(part.Name); builder.Append('}'); // TODO part.IsOptionalSeperator // TODO part.IsCatchAll } builder.Append('/'); } info.Url = builder.ToString().TrimEnd('/'); }
public TemplateBinder(RouteTemplate template, IReadOnlyDictionary<string, object> defaults) { if (template == null) { throw new ArgumentNullException(nameof(template)); } _template = template; _defaults = defaults; }
public TemplateMatcher( RouteTemplate template, IReadOnlyDictionary<string, object> defaults) { if (template == null) { throw new ArgumentNullException(nameof(template)); } Template = template; Defaults = defaults ?? RouteValueDictionary.Empty; }
public static decimal Compute(RouteTemplate template) { // Each precedence digit corresponds to one decimal place. For example, 3 segments with precedences 2, 1, // and 4 results in a combined precedence of 2.14 (decimal). var precedence = 0m; for (var i = 0; i < template.Segments.Count; i++) { var segment = template.Segments[i]; var digit = ComputeDigit(segment); Debug.Assert(digit >= 0 && digit < 10); precedence += Decimal.Divide(digit, (decimal)Math.Pow(10, i)); } return precedence; }
public TemplateMatcher( RouteTemplate template, RouteValueDictionary defaults) { if (template == null) { throw new ArgumentNullException(nameof(template)); } Template = template; Defaults = defaults ?? new RouteValueDictionary(); // Perf: cache the default value for each parameter (other than complex segments). _hasDefaultValue = new bool[Template.Segments.Count]; _defaultValues = new object[Template.Segments.Count]; for (var i = 0; i < Template.Segments.Count; i++) { var segment = Template.Segments[i]; if (!segment.IsSimple) { continue; } var part = segment.Parts[0]; if (!part.IsParameter) { continue; } object value; if (Defaults.TryGetValue(part.Name, out value)) { _hasDefaultValue[i] = true; _defaultValues[i] = value; } } }
public TemplateRoute([NotNull] IRouter target, string routeName, string routeTemplate, IDictionary <string, object> defaults, IDictionary <string, object> constraints, IDictionary <string, object> dataTokens, IInlineConstraintResolver inlineConstraintResolver) { _target = target; _routeTemplate = routeTemplate ?? string.Empty; Name = routeName; _defaults = defaults ?? new RouteValueDictionary(); _constraints = RouteConstraintBuilder.BuildConstraints(constraints, _routeTemplate) ?? new Dictionary <string, IRouteConstraint>(); _dataTokens = dataTokens ?? new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); // The parser will throw for invalid routes. _parsedTemplate = TemplateParser.Parse(RouteTemplate, inlineConstraintResolver); UpdateInlineDefaultValuesAndConstraints(); _matcher = new TemplateMatcher(_parsedTemplate); _binder = new TemplateBinder(_parsedTemplate, _defaults); }
public TemplateRoute([NotNull] IRouter target, string routeName, string routeTemplate, IDictionary <string, object> defaults, IDictionary <string, object> constraints, IDictionary <string, object> dataTokens, IInlineConstraintResolver inlineConstraintResolver) { _target = target; _routeTemplate = routeTemplate ?? string.Empty; Name = routeName; _dataTokens = dataTokens == null ? RouteValueDictionary.Empty : new RouteValueDictionary(dataTokens); // Data we parse from the template will be used to fill in the rest of the constraints or // defaults. The parser will throw for invalid routes. _parsedTemplate = TemplateParser.Parse(RouteTemplate); _constraints = GetConstraints(inlineConstraintResolver, RouteTemplate, _parsedTemplate, constraints); _defaults = GetDefaults(_parsedTemplate, defaults); _matcher = new TemplateMatcher(_parsedTemplate, Defaults); _binder = new TemplateBinder(_parsedTemplate, Defaults); }
private static IReadOnlyDictionary<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(); }
/// <summary> /// Processes the defaults for the specified action. /// </summary> /// <param name="action">MVC action</param> /// <param name="template">Route template for this action</param> /// <returns>Defaults for this action</returns> private IDictionary<string, object> GetDefaults(ControllerActionDescriptor action, RouteTemplate template) { var defaults = template.Parameters .Where(p => p.DefaultValue != null) .ToDictionary( p => p.Name.ToLowerInvariant(), p => p.DefaultValue, StringComparer.OrdinalIgnoreCase ); defaults.Add("controller", action.ControllerName); defaults.Add("action", action.Name); return defaults; }
/// <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); }
public TemplateBinder([NotNull] RouteTemplate template, IReadOnlyDictionary <string, object> defaults) { _template = template; _defaults = defaults; }
protected static RouteValueDictionary GetDefaults( RouteTemplate parsedTemplate, RouteValueDictionary defaults) { var result = defaults == null ? new RouteValueDictionary() : new RouteValueDictionary(defaults); foreach (var parameter in parsedTemplate.Parameters) { if (parameter.DefaultValue != null) { if (result.ContainsKey(parameter.Name)) { throw new InvalidOperationException( Resources.FormatTemplateRoute_CannotHaveDefaultValueSpecifiedInlineAndExplicitly( parameter.Name)); } else { result.Add(parameter.Name, parameter.DefaultValue); } } } return result; }
private static RouteValueDictionary GetDefaults( RouteTemplate parsedTemplate, IDictionary<string, object> defaults) { // Do not use RouteValueDictionary.Empty for defaults, it might be modified inside // UpdateInlineDefaultValuesAndConstraints() var result = defaults == null ? new RouteValueDictionary() : new RouteValueDictionary(defaults); foreach (var parameter in parsedTemplate.Parameters) { if (parameter.DefaultValue != null) { if (result.ContainsKey(parameter.Name)) { throw new InvalidOperationException( Resources.FormatTemplateRoute_CannotHaveDefaultValueSpecifiedInlineAndExplicitly( parameter.Name)); } else { result.Add(parameter.Name, parameter.DefaultValue); } } } return result; }
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(); }
public TemplateBinder([NotNull] RouteTemplate template, IReadOnlyDictionary<string, object> defaults) { _template = template; _defaults = defaults; }