private string GetLink(MatcherEndpoint endpoint, LinkGeneratorContext context) { var templateBinder = new TemplateBinder( UrlEncoder.Default, _uriBuildingContextPool, new RouteTemplate(endpoint.RoutePattern), new RouteValueDictionary(endpoint.RoutePattern.Defaults)); var templateValuesResult = templateBinder.GetValues( ambientValues: context.AmbientValues, explicitValues: context.ExplicitValues, endpoint.RequiredValues.Keys); if (templateValuesResult == null) { // We're missing one of the required values for this route. return(null); } if (!MatchesConstraints(context.HttpContext, endpoint, templateValuesResult.CombinedValues)) { return(null); } var url = templateBinder.BindValues(templateValuesResult.AcceptedValues); return(Normalize(context, url)); }
internal string MakeLink( HttpContext httpContext, MatcherEndpoint endpoint, RouteValueDictionary ambientValues, RouteValueDictionary explicitValues, LinkOptions options) { var templateBinder = new TemplateBinder( UrlEncoder.Default, _uriBuildingContextPool, new RouteTemplate(endpoint.RoutePattern), new RouteValueDictionary(endpoint.RoutePattern.Defaults)); var routeValuesAddressMetadata = endpoint.Metadata.GetMetadata <IRouteValuesAddressMetadata>(); var templateValuesResult = templateBinder.GetValues( ambientValues: ambientValues, explicitValues: explicitValues, requiredKeys: routeValuesAddressMetadata?.RequiredValues.Keys); if (templateValuesResult == null) { // We're missing one of the required values for this route. return(null); } if (!MatchesConstraints(httpContext, endpoint, templateValuesResult.CombinedValues)) { return(null); } var url = templateBinder.BindValues(templateValuesResult.AcceptedValues); return(Normalize(url, options)); }
private bool MatchesConstraints( HttpContext httpContext, MatcherEndpoint endpoint, RouteValueDictionary routeValues) { if (routeValues == null) { throw new ArgumentNullException(nameof(routeValues)); } foreach (var kvp in endpoint.RoutePattern.Constraints) { var parameter = endpoint.RoutePattern.GetParameter(kvp.Key); // may be null, that's ok var constraintReferences = kvp.Value; for (var i = 0; i < constraintReferences.Count; i++) { var constraintReference = constraintReferences[i]; var matchProcessor = _matchProcessorFactory.Create(parameter, constraintReference); if (!matchProcessor.ProcessOutbound(httpContext, routeValues)) { return(false); } } } return(true); }
internal CandidateState(MatcherEndpoint endpoint, int score) { Endpoint = endpoint; Score = score; IsValidCandidate = true; Values = null; }
private MatcherEndpoint CreateEndpoint(ActionDescriptor action, string template, int order, object source) { RequestDelegate invokerDelegate = (context) => { var values = context.Features.Get <IEndpointFeature>().Values; var routeData = new RouteData(); foreach (var kvp in values) { if (kvp.Value != null) { routeData.Values.Add(kvp.Key, kvp.Value); } } var actionContext = new ActionContext(context, routeData, action); var invoker = _invokerFactory.CreateInvoker(actionContext); return(invoker.InvokeAsync()); }; var metadata = new List <object>(); // REVIEW: Used for debugging. Consider removing before release metadata.Add(source); metadata.Add(action); // Add filter descriptors to endpoint metadata if (action.FilterDescriptors != null && action.FilterDescriptors.Count > 0) { metadata.AddRange(action.FilterDescriptors.OrderBy(f => f, FilterDescriptorOrderComparer.Comparer).Select(f => f.Filter)); } if (action.ActionConstraints != null && action.ActionConstraints.Count > 0) { foreach (var actionConstraint in action.ActionConstraints) { if (actionConstraint is HttpMethodActionConstraint httpMethodActionConstraint) { metadata.Add(new HttpMethodEndpointConstraint(httpMethodActionConstraint.HttpMethods)); } } } var metadataCollection = new EndpointMetadataCollection(metadata); var endpoint = new MatcherEndpoint( next => invokerDelegate, template, action.RouteValues, order, metadataCollection, action.DisplayName, address: null); return(endpoint); }
public override void AddEntry(string pattern, MatcherEndpoint endpoint) { var parsed = TemplateParser.Parse(pattern); _entries.Add(new Entry() { Order = 0, Pattern = parsed, Precedence = RoutePrecedence.ComputeInbound(parsed), Endpoint = endpoint, }); }
private MatcherEndpoint CreateEndpoint( ActionDescriptor action, string routeName, string template, object nonInlineDefaults, int order, object source, bool suppressLinkGeneration) { RequestDelegate invokerDelegate = (context) => { var values = context.Features.Get <IEndpointFeature>().Values; var routeData = new RouteData(); foreach (var kvp in values) { if (kvp.Value != null) { routeData.Values.Add(kvp.Key, kvp.Value); } } var actionContext = new ActionContext(context, routeData, action); var invoker = _invokerFactory.CreateInvoker(actionContext); return(invoker.InvokeAsync()); }; var defaults = new RouteValueDictionary(nonInlineDefaults); EnsureRequiredValuesInDefaults(action.RouteValues, defaults); var metadataCollection = BuildEndpointMetadata( action, routeName, new RouteValueDictionary(action.RouteValues), source, suppressLinkGeneration); var endpoint = new MatcherEndpoint( next => invokerDelegate, RoutePatternFactory.Parse(template, defaults, constraints: null), order, metadataCollection, action.DisplayName); return(endpoint); }
private OutboundRouteEntry CreateOutboundRouteEntry(MatcherEndpoint endpoint) { var routeValuesAddressMetadata = endpoint.Metadata.GetMetadata <IRouteValuesAddressMetadata>(); var entry = new OutboundRouteEntry() { Handler = NullRouter.Instance, Order = endpoint.Order, Precedence = RoutePrecedence.ComputeOutbound(endpoint.RoutePattern), RequiredLinkValues = new RouteValueDictionary(routeValuesAddressMetadata?.RequiredValues), RouteTemplate = new RouteTemplate(endpoint.RoutePattern), Data = endpoint, RouteName = routeValuesAddressMetadata?.Name, }; entry.Defaults = new RouteValueDictionary(endpoint.RoutePattern.Defaults); return(entry); }
private MatcherEndpoint CreateEndpoint( ActionDescriptor action, string routeName, string template, object nonInlineDefaults, int order, object source) { RequestDelegate invokerDelegate = (context) => { var values = context.Features.Get <IEndpointFeature>().Values; var routeData = new RouteData(); foreach (var kvp in values) { if (kvp.Value != null) { routeData.Values.Add(kvp.Key, kvp.Value); } } var actionContext = new ActionContext(context, routeData, action); var invoker = _invokerFactory.CreateInvoker(actionContext); return(invoker.InvokeAsync()); }; var metadataCollection = BuildEndpointMetadata(action, routeName, source); var endpoint = new MatcherEndpoint( next => invokerDelegate, template, new RouteValueDictionary(nonInlineDefaults), new RouteValueDictionary(action.RouteValues), order, metadataCollection, action.DisplayName); // Use defaults after the endpoint is created as it merges both the inline and // non-inline defaults into one. EnsureRequiredValuesInDefaults(endpoint.RequiredValues, endpoint.Defaults); return(endpoint); }
private OutboundRouteEntry CreateOutboundRouteEntry(MatcherEndpoint endpoint) { var routeNameMetadata = endpoint.Metadata.GetMetadata <IRouteNameMetadata>(); var entry = new OutboundRouteEntry() { Handler = NullRouter.Instance, Order = endpoint.Order, Precedence = RoutePrecedence.ComputeOutbound(endpoint.ParsedTemplate), RequiredLinkValues = endpoint.RequiredValues, RouteTemplate = endpoint.ParsedTemplate, Data = endpoint, RouteName = routeNameMetadata?.Name, }; // TODO: review. These route constriants should be constructed when the endpoint // is built. This way they can be checked for validity on app startup too var constraintBuilder = new RouteConstraintBuilder( _inlineConstraintResolver, endpoint.ParsedTemplate.TemplateText); foreach (var parameter in endpoint.ParsedTemplate.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 = endpoint.Defaults; return(entry); }
private MatcherEndpoint CreateEndpoint( ActionDescriptor action, string routeName, string template, object nonInlineDefaults, int order, object source) { RequestDelegate invokerDelegate = (context) => { var values = context.Features.Get <IEndpointFeature>().Values; var routeData = new RouteData(); foreach (var kvp in values) { if (kvp.Value != null) { routeData.Values.Add(kvp.Key, kvp.Value); } } var actionContext = new ActionContext(context, routeData, action); var invoker = _invokerFactory.CreateInvoker(actionContext); return(invoker.InvokeAsync()); }; var metadata = new List <object>(); // REVIEW: Used for debugging. Consider removing before release metadata.Add(source); metadata.Add(action); if (!string.IsNullOrEmpty(routeName)) { metadata.Add(new RouteNameMetadata(routeName)); } // Add filter descriptors to endpoint metadata if (action.FilterDescriptors != null && action.FilterDescriptors.Count > 0) { metadata.AddRange(action.FilterDescriptors.OrderBy(f => f, FilterDescriptorOrderComparer.Comparer) .Select(f => f.Filter)); } if (action.ActionConstraints != null && action.ActionConstraints.Count > 0) { foreach (var actionConstraint in action.ActionConstraints) { if (actionConstraint is HttpMethodActionConstraint httpMethodActionConstraint) { metadata.Add(new HttpMethodEndpointConstraint(httpMethodActionConstraint.HttpMethods)); } } } var metadataCollection = new EndpointMetadataCollection(metadata); var endpoint = new MatcherEndpoint( next => invokerDelegate, template, new RouteValueDictionary(nonInlineDefaults), new RouteValueDictionary(action.RouteValues), order, metadataCollection, action.DisplayName); // Use defaults after the endpoint is created as it merges both the inline and // non-inline defaults into one. EnsureRequiredValuesInDefaults(endpoint.RequiredValues, endpoint.Defaults); return(endpoint); }
public abstract void AddEndpoint(MatcherEndpoint endpoint);
public abstract void AddEntry(string template, MatcherEndpoint endpoint);