Exemplo n.º 1
0
        public override IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText)
        {
            if (inlineText == null)
            {
                throw new ArgumentNullException(nameof(inlineText));
            }

            var parameterPolicy = ParameterPolicyActivator.ResolveParameterPolicy <IParameterPolicy>(
                _options.ConstraintMap,
                _serviceProvider,
                inlineText,
                out var parameterPolicyKey);

            if (parameterPolicy == null)
            {
                throw new InvalidOperationException($"The constraint reference '{parameterPolicyKey}' could not be resolved to a type. Register the constraint type with '{typeof(RouteOptions)}.{nameof(RouteOptions.ConstraintMap)}'.");
            }

            if (parameterPolicy is IRouteConstraint constraint)
            {
                return(InitializeRouteConstraint(parameter?.IsOptional ?? false, constraint));
            }

            return(parameterPolicy);
        }
Exemplo n.º 2
0
        public override IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText)
        {
            if (inlineText == null)
            {
                throw new ArgumentNullException(nameof(inlineText));
            }

            var parameterPolicy = ParameterPolicyActivator.ResolveParameterPolicy <IParameterPolicy>(
                _options.ConstraintMap,
                _serviceProvider,
                inlineText,
                out var parameterPolicyKey);

            if (parameterPolicy == null)
            {
                throw new InvalidOperationException(Resources.FormatRoutePattern_ConstraintReferenceNotFound(
                                                        parameterPolicyKey,
                                                        typeof(RouteOptions),
                                                        nameof(RouteOptions.ConstraintMap)));
            }

            if (parameterPolicy is IRouteConstraint constraint)
            {
                return(InitializeRouteConstraint(parameter?.IsOptional ?? false, constraint));
            }

            return(parameterPolicy);
        }
Exemplo n.º 3
0
        public MatchProcessor Create(RoutePatternParameterPart parameter, RoutePatternConstraintReference reference)
        {
            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }

            Debug.Assert(reference.MatchProcessor != null || reference.Constraint != null || reference.Content != null);

            if (reference.MatchProcessor != null)
            {
                return(Create(parameter?.Name, reference.MatchProcessor, parameter?.IsOptional ?? false));
            }

            if (reference.Constraint != null)
            {
                return(Create(parameter?.Name, reference.Constraint, parameter?.IsOptional ?? false));
            }

            if (reference.Content != null)
            {
                return(Create(parameter?.Name, reference.Content, parameter?.IsOptional ?? false));
            }

            // Unreachable
            throw new NotSupportedException();
        }
Exemplo n.º 4
0
 private bool Equals(RoutePatternParameterPart x, RoutePatternParameterPart y)
 {
     return
         (x.Name == y.Name &&
          x.Default == y.Default &&
          x.ParameterKind == y.ParameterKind &&
          Enumerable.SequenceEqual(x.ParameterPolicies, y.ParameterPolicies, this));
 }
 private static string BuildRoutePart(RoutePatternPart part)
 {
     return(part switch
     {
         RoutePatternLiteralPart lit => lit.Content,
         RoutePatternParameterPart param => $"{{{param.Name}}}",
         RoutePatternSeparatorPart sep => sep.Content,
         _ => string.Empty
     });
        public override IParameterPolicy Create(RoutePatternParameterPart parameter, IParameterPolicy parameterPolicy)
        {
            if (parameterPolicy == null)
            {
                throw new ArgumentNullException(nameof(parameterPolicy));
            }

            if (parameterPolicy is IRouteConstraint routeConstraint)
            {
                return(InitializeRouteConstraint(parameter?.IsOptional ?? false, routeConstraint, argument: null));
            }

            return(parameterPolicy);
        }
        public override IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText)
        {
            if (inlineText == null)
            {
                throw new ArgumentNullException(nameof(inlineText));
            }

            // Example:
            // {productId:regex(\d+)}
            //
            // ParameterName: productId
            // value: regex(\d+)
            // name: regex
            // argument: \d+
            (var name, var argument) = Parse(inlineText);

            if (!_options.ConstraintMap.TryGetValue(name, out var type))
            {
                throw new InvalidOperationException(Resources.FormatRoutePattern_ConstraintReferenceNotFound(
                                                        name,
                                                        typeof(RouteOptions),
                                                        nameof(RouteOptions.ConstraintMap)));
            }

            if (typeof(IRouteConstraint).IsAssignableFrom(type))
            {
                var constraint = DefaultInlineConstraintResolver.CreateConstraint(type, argument);
                return(InitializeRouteConstraint(parameter?.IsOptional ?? false, constraint, argument));
            }

            if (typeof(IParameterPolicy).IsAssignableFrom(type))
            {
                var parameterPolicy = (IParameterPolicy)_serviceProvider.GetRequiredService(type);
                return(parameterPolicy);
            }

            var message = Resources.FormatRoutePattern_InvalidStringConstraintReference(
                type,
                name,
                typeof(IRouteConstraint),
                typeof(IParameterPolicy));

            throw new InvalidOperationException(message);
        }
    private bool MatchesConstraints(RoutePattern pattern, RoutePatternParameterPart parameter, string key, RouteValueDictionary requiredValues)
    {
        if (pattern.ParameterPolicies.TryGetValue(key, out var policies))
        {
            for (var i = 0; i < policies.Count; i++)
            {
                var policy = _policyFactory.Create(parameter, policies[i]);
                if (policy is IRouteConstraint constraint)
                {
                    if (!constraint.Match(httpContext: null, NullRouter.Instance, key, requiredValues, RouteDirection.IncomingRequest))
                    {
                        return(false);
                    }
                }
            }
        }

        return(true);
    }
Exemplo n.º 9
0
        /// <summary>
        /// Creates a parameter policy.
        /// </summary>
        /// <param name="parameter">The parameter the parameter policy is being created for.</param>
        /// <param name="reference">The reference to resolve.</param>
        /// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns>
        public IParameterPolicy Create(RoutePatternParameterPart parameter, RoutePatternParameterPolicyReference reference)
        {
            if (reference == null)
            {
                throw new ArgumentNullException(nameof(reference));
            }

            Debug.Assert(reference.ParameterPolicy != null || reference.Content != null);

            if (reference.ParameterPolicy != null)
            {
                return(Create(parameter, reference.ParameterPolicy));
            }

            if (reference.Content != null)
            {
                return(Create(parameter, reference.Content));
            }

            // Unreachable
            throw new NotSupportedException();
        }
Exemplo n.º 10
0
 /// <summary>
 /// Creates a parameter policy.
 /// </summary>
 /// <param name="parameter">The parameter the parameter policy is being created for.</param>
 /// <param name="parameterPolicy">An existing parameter policy.</param>
 /// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns>
 public abstract IParameterPolicy Create(RoutePatternParameterPart parameter, IParameterPolicy parameterPolicy);
Exemplo n.º 11
0
            private void AddRequiredLiteralValue(RouteEndpoint endpoint, List <DfaNode> nextParents, DfaNode parent, RoutePatternParameterPart parameterPart, object requiredValue)
            {
                if (endpoint.RoutePattern.ParameterPolicies.TryGetValue(parameterPart.Name, out var parameterPolicyReferences))
                {
                    for (var k = 0; k < parameterPolicyReferences.Count; k++)
                    {
                        var reference       = parameterPolicyReferences[k];
                        var parameterPolicy = _parameterPolicyFactory.Create(parameterPart, reference);
                        if (parameterPolicy is IOutboundParameterTransformer parameterTransformer)
                        {
                            requiredValue = parameterTransformer.TransformOutbound(requiredValue);
                            break;
                        }
                    }
                }

                var literalValue = requiredValue?.ToString() ?? throw new InvalidOperationException($"Required value for literal '{parameterPart.Name}' must evaluate to a non-null string.");

                AddLiteralNode(_includeLabel, nextParents, parent, literalValue);
            }
Exemplo n.º 12
0
            private void AddParentsWithMatchingLiteralConstraints(List <DfaNode> nextParents, DfaNode parent, RoutePatternParameterPart parameterPart, IReadOnlyList <RoutePatternParameterPolicyReference> parameterPolicyReferences)
            {
                // The list of parameters that fail to meet at least one IParameterLiteralNodeMatchingPolicy.
                var hasFailingPolicy = parent.Literals.Keys.Count < 32 ?
                                       (stackalloc bool[32]).Slice(0, parent.Literals.Keys.Count) :
                                       new bool[parent.Literals.Keys.Count];

                // Whether or not all parameters have failed to meet at least one constraint.
                for (var i = 0; i < parameterPolicyReferences.Count; i++)
                {
                    var reference       = parameterPolicyReferences[i];
                    var parameterPolicy = _parameterPolicyFactory.Create(parameterPart, reference);
                    if (parameterPolicy is IParameterLiteralNodeMatchingPolicy constraint)
                    {
                        var literalIndex = 0;
                        var allFailed    = true;
                        foreach (var literal in parent.Literals.Keys)
                        {
                            if (!hasFailingPolicy[literalIndex] && !constraint.MatchesLiteral(parameterPart.Name, literal))
                            {
                                hasFailingPolicy[literalIndex] = true;
                            }

                            allFailed &= hasFailingPolicy[literalIndex];

                            literalIndex++;
                        }

                        if (allFailed)
                        {
                            // If we get here it means that all literals have failed at least one policy, which means we can skip checking policies
                            // and return early. This will be a very common case when your constraints are things like "int,length or a regex".
                            return;
                        }
                    }
                }

                var k = 0;

                foreach (var literal in parent.Literals.Values)
                {
                    if (!hasFailingPolicy[k])
                    {
                        nextParents.Add(literal);
                    }
                    k++;
                }
            }
Exemplo n.º 13
0
            private void AddParentsMatchingComplexSegment(RouteEndpoint endpoint, List <DfaNode> nextParents, RoutePatternPathSegment segment, DfaNode parent, RoutePatternParameterPart parameterPart)
            {
                var routeValues = new RouteValueDictionary();

                foreach (var literal in parent.Literals.Keys)
                {
                    if (RoutePatternMatcher.MatchComplexSegment(segment, literal, routeValues))
                    {
                        // If we got here (rare) it means that the literal matches the complex segment (for example the literal is something A-B)
                        // there is another thing we can try here, which is to evaluate the policies for the parts in case they have one (for example {a:length(4)}-{b:regex(\d+)})
                        // so that even if it maps closely to a complex parameter we have a chance to discard it and avoid adding the extra branches.
                        var passedAllPolicies = true;
                        for (var i = 0; i < segment.Parts.Count; i++)
                        {
                            var segmentPart = segment.Parts[i];
                            if (segmentPart is not RoutePatternParameterPart partParameter)
                            {
                                // We skip over the literals and the separator since we already checked against them
                                continue;
                            }

                            if (!routeValues.TryGetValue(partParameter.Name, out var parameterValue))
                            {
                                // We have a pattern like {a}-{b}.{part?} and a literal "a-b". Since we've matched the complex segment it means that the optional
                                // parameter was not specified, so we skip it.
                                Debug.Assert(i == segment.Parts.Count - 1 && partParameter.IsOptional);
                                continue;
                            }

                            if (endpoint.RoutePattern.ParameterPolicies.TryGetValue(partParameter.Name, out var parameterPolicyReferences))
                            {
                                for (var j = 0; j < parameterPolicyReferences.Count; j++)
                                {
                                    var reference       = parameterPolicyReferences[j];
                                    var parameterPolicy = _parameterPolicyFactory.Create(parameterPart, reference);
                                    if (parameterPolicy is IParameterLiteralNodeMatchingPolicy constraint && !constraint.MatchesLiteral(partParameter.Name, (string)parameterValue))
                                    {
                                        passedAllPolicies = false;
                                        break;
                                    }
                                }
                            }
                        }

                        if (passedAllPolicies)
                        {
                            nextParents.Add(parent.Literals[literal]);
                        }
                    }

                    routeValues.Clear();
                }
            }
Exemplo n.º 14
0
 /// <summary>
 /// Creates a parameter policy.
 /// </summary>
 /// <param name="parameter">The parameter the parameter policy is being created for.</param>
 /// <param name="inlineText">The inline text to resolve.</param>
 /// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns>
 public abstract IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText);
    private static void RemoveParameterDefault(List <RoutePatternPathSegment> segments, List <RoutePatternParameterPart> parameters, RoutePatternParameterPart parameter)
    {
        // We know that a parameter can only appear once, so we only need to rewrite one segment and one parameter.
        for (var i = 0; i < segments.Count; i++)
        {
            var segment = segments[i];
            for (var j = 0; j < segment.Parts.Count; j++)
            {
                if (object.ReferenceEquals(parameter, segment.Parts[j]))
                {
                    // Found it!
                    var updatedParameter = RoutePatternFactory.ParameterPart(parameter.Name, @default: null, parameter.ParameterKind, parameter.ParameterPolicies);

                    var updatedParts = new List <RoutePatternPart>(segment.Parts);
                    updatedParts[j] = updatedParameter;
                    segments[i]     = RoutePatternFactory.Segment(updatedParts);

                    for (var k = 0; k < parameters.Count; k++)
                    {
                        if (ReferenceEquals(parameter, parameters[k]))
                        {
                            parameters[k] = updatedParameter;
                            break;
                        }
                    }

                    return;
                }
            }
        }
    }
 public override IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText)
 {
     throw new NotImplementedException();
 }
 public override IParameterPolicy Create(RoutePatternParameterPart parameter, IParameterPolicy parameterPolicy)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 18
0
        public string GetResourceId(RouteEndpoint routeEndpoint)
        {
            StringBuilder templateBuilder = new StringBuilder();
            IEnumerable <RoutePatternPathSegment> pathSegments = routeEndpoint.RoutePattern.PathSegments;

            if (pathSegments.IsNullOrEmpty())
            {
                return(null);
            }
            IDictionary <string, object> values = GetRequiredValues();

            foreach (RoutePatternPathSegment segment in pathSegments)
            {
                templateBuilder.Append("/");
                foreach (RoutePatternPart part in segment.Parts)
                {
                    if (part.IsLiteral)
                    {
                        RoutePatternLiteralPart literalPart = part as RoutePatternLiteralPart;
                        templateBuilder.Append(literalPart.Content);
                    }
                    else if (part.IsSeparator)
                    {
                        RoutePatternSeparatorPart separatorPart = part as RoutePatternSeparatorPart;
                        templateBuilder.Append(separatorPart.Content);
                    }
                    else
                    {
                        RoutePatternParameterPart parameterPart = part as RoutePatternParameterPart;
                        templateBuilder.Append("{");
                        if (parameterPart.IsCatchAll)
                        {
                            templateBuilder.Append("*");
                            if (!parameterPart.EncodeSlashes)
                            {
                                templateBuilder.Append("*");
                            }
                        }
                        if (values.ContainsKey(parameterPart.Name))
                        {
                            templateBuilder.Append(values[parameterPart.Name]);
                        }
                        else
                        {
                            templateBuilder.Append(parameterPart.Name);
                        }
                        if (parameterPart.IsOptional)
                        {
                            templateBuilder.Append("?");
                        }
                        //需不要考虑规则呢? 例如5:int
                        //if (!parameterPart.ParameterPolicies.IsNullOrEmpty())
                        //{

                        //}
                        templateBuilder.Append("}");
                    }
                }
            }
            return(templateBuilder.ToString());
        }