コード例 #1
0
        public override async Task SelectAsync(EndpointSelectorContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            EnsureServicesInitialized(context);

            var snapshot = context.CreateSnapshot();

            var fallbackEndpoints = new List <Endpoint>();

            for (var i = context.Endpoints.Count - 1; i >= 0; i--)
            {
                var endpoint = context.Endpoints[i] as IRoutePatternEndpoint;
                if (endpoint == null || endpoint.HttpMethod == null)
                {
                    // No metadata.
                    Logger.NoHttpMethodFound(context.Endpoints[i]);

                    fallbackEndpoints.Add(context.Endpoints[i]);
                    context.Endpoints.RemoveAt(i);
                }
                else if (string.Equals(endpoint.HttpMethod, context.HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase))
                {
                    // The request method matches the endpoint's HTTP method.
                    Logger.RequestMethodMatchedEndpointMethod(endpoint.HttpMethod, context.Endpoints[i]);
                }
                else
                {
                    // Not a match.
                    Logger.RequestMethodDidNotMatchEndpointMethod(context.HttpContext.Request.Method, endpoint.HttpMethod, context.Endpoints[i]);
                    context.Endpoints.RemoveAt(i);
                }
            }

            // Now the list of endpoints only contains those that have an HTTP method preference AND match the current
            // request.
            await context.InvokeNextAsync();

            if (context.Endpoints.Count == 0)
            {
                Logger.NoEndpointMatchedRequestMethod(context.HttpContext.Request.Method);

                // Nothing matched, do the fallback.
                context.RestoreSnapshot(snapshot);

                context.Endpoints.Clear();

                for (var i = 0; i < fallbackEndpoints.Count; i++)
                {
                    context.Endpoints.Add(fallbackEndpoints[i]);
                }

                await context.InvokeNextAsync();
            }
        }
コード例 #2
0
        protected virtual async Task SelectEndpointAsync(MatcherContext context, IEnumerable <Endpoint> endpoints)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

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

            EnsureSelectorsInitialized();

            var selectorContext = new EndpointSelectorContext(context.HttpContext, context.Values, endpoints.ToList(), Selectors.ToList());
            await selectorContext.InvokeNextAsync();

            if (selectorContext.ShortCircuit != null)
            {
                context.ShortCircuit = selectorContext.ShortCircuit;
                Logger.RequestShortCircuitedMatcherBase(context);
                return;
            }

            switch (selectorContext.Endpoints.Count)
            {
            case 0:
                Logger.NoEndpointsMatched(context.HttpContext.Request.Path);
                return;

            case 1:
                context.Endpoint = selectorContext.Endpoints[0];

                Logger.EndpointMatchedMatcherBase(context.Endpoint);
                return;

            default:
                var endpointNames = string.Join(
                    Environment.NewLine,
                    selectorContext.Endpoints.Select(a => a.DisplayName));

                Logger.AmbiguousEndpoints(endpointNames);

                var message = Resources.FormatAmbiguousEndpoints(
                    Environment.NewLine,
                    endpointNames);

                throw new AmbiguousEndpointException(message);
            }
        }