private TemplateBinder CreateTemplateBinder(RouteEndpoint endpoint)
        {
            /*
             * The following code section is disabled
             * for its change to RoutePattern may cause
             * errors.
             *
             * var rawText = endpoint.RoutePattern.RawText;
             * var rv = endpoint.RoutePattern.RequiredValues as RouteValueDictionary;
             *
             * if (rawText != null)
             * {
             *     var m = Regex.Matches(rawText, "\\{(\\w+)\\}");
             *     for (int i = 0; i < m.Count; i++)
             *         rv.Add(m[i].Value.TrimStart('{').TrimEnd('}'), RoutePattern.RequiredValueAny);
             * }
             *
             * A better solution is to disable the _requiredKeys.
             */

            var binder = _binderFactory.Create(endpoint.RoutePattern);

            _requiredKeys.SetValue(binder, Array.Empty <string>());
            return(binder);
        }
Example #2
0
    /// <inheritdoc/>
    public override ValueTask ApplyAsync(RequestTransformContext context)
    {
        if (context is null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        // TemplateBinder.BindValues will modify the RouteValueDictionary
        // We make a copy so that the original request is not modified by the transform
        var routeValues     = context.HttpContext.Request.RouteValues;
        var routeValuesCopy = new RouteValueDictionary();

        // Only copy route values used in the pattern, otherwise they'll be added as query parameters.
        foreach (var pattern in Pattern.Parameters)
        {
            if (routeValues.TryGetValue(pattern.Name, out var value))
            {
                routeValuesCopy[pattern.Name] = value;
            }
        }

        var binder = _binderFactory.Create(Pattern);

        context.Path = binder.BindValues(acceptedValues: routeValuesCopy);

        return(default);
Example #3
0
        public string UrlFor <TInput>(TInput request, RouteValueDictionary queryString) where TInput : class
        {
            var path = typeof(TInput).FeatureName();

            var binder = _factory.Create(RoutePatternFactory.Parse(path));

            var qs = binder.BindValues(queryString);

            return(qs);
        }
Example #4
0
        public override void Apply(RequestParametersTransformContext context)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var routeValues = context.HttpContext.Request.RouteValues;
            // Route values that are not considered defaults will be appended as query parameters. Make them all defaults.
            var binder = _binderFactory.Create(Template, defaults: routeValues);

            context.Path = binder.BindValues(acceptedValues: routeValues);
        }
Example #5
0
        public PathRouteValuesTransform(string pattern, TemplateBinderFactory binderFactory)
        {
            if (pattern is null)
            {
                throw new System.ArgumentNullException(nameof(pattern));
            }

            if (binderFactory is null)
            {
                throw new System.ArgumentNullException(nameof(binderFactory));
            }

            _binder = binderFactory.Create(RoutePatternFactory.Parse(pattern));
        }
        /// <inheritdoc/>
        public override ValueTask ApplyAsync(RequestTransformContext context)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // TemplateBinder.BindValues will modify the RouteValueDictionary
            // We make a copy so that the original request is not modified by the transform
            var routeValues = new RouteValueDictionary(context.HttpContext.Request.RouteValues);

            // Route values that are not considered defaults will be appended as query parameters. Make them all defaults.
            var binder = _binderFactory.Create(Template, defaults: routeValues);

            context.Path = binder.BindValues(acceptedValues: routeValues);

            return(default);
Example #7
0
        private static bool TryProcessPrefixTemplate(HttpRequest request, RoutePattern routePattern, out string path)
        {
            // TODO: Do you have a better way to process the prefix template?
            Contract.Assert(request != null);
            Contract.Assert(routePattern != null);

            HttpContext           httpContext    = request.HttpContext;
            TemplateBinderFactory factory        = request.HttpContext.RequestServices.GetRequiredService <TemplateBinderFactory>();
            TemplateBinder        templateBinder = factory.Create(routePattern);

            RouteValueDictionary ambientValues = GetAmbientValues(httpContext);

            var templateValuesResult = templateBinder.GetValues(ambientValues, request.RouteValues);

            if (templateValuesResult == null)
            {
                // We're missing one of the required values for this route.
                path = default;
                return(false);
            }

            if (!templateBinder.TryProcessConstraints(httpContext, templateValuesResult.CombinedValues, out var _, out var _))
            {
                path = default;
                return(false);
            }

            path = templateBinder.BindValues(templateValuesResult.AcceptedValues);
            int index = path.IndexOf("?", StringComparison.Ordinal); // remove the query string

            if (index >= 0)
            {
                path = path.Substring(0, index);
            }

            return(true);
        }
Example #8
0
        public string?Format(HttpContext httpContext, RoutePattern pattern, object?routeValues)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

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

            // Refer to
            // https://github.com/dotnet/aspnetcore/blob/master/src/Http/Routing/src/DefaultLinkGenerator.cs#L291
            var binder = _templateBinderFactory.Create(pattern);
            // Route values captured from previous endpoint
            var ambientValues =
                httpContext.Features.Get <IExceptionMappingFeature>().RouteValues
                ?? EmptyRouteValues;

            var valuesResult = binder.GetValues(ambientValues, routeValues == null
                ? EmptyRouteValues
                : new RouteValueDictionary(routeValues));

            if (valuesResult == null)
            {
                return(null);
            }

            if (!binder.TryProcessConstraints(httpContext, valuesResult.CombinedValues, out var _, out var _))
            {
                return(null);
            }

            return(binder.BindValues(valuesResult.AcceptedValues));
        }
 private TemplateBinder CreateTemplateBinder(RouteEndpoint endpoint)
 {
     return(_binderFactory.Create(endpoint.RoutePattern));
 }