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); }
/// <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);
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); }
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); }
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);
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); }
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)); }